libxml2 2.9.1 clean sources
[tomato/tomato-dir865l.git] / release / src / router / libxml2 / xmlwriter.c
blobd3f29f8e60259cceaeefc1d71f5a52d69008648e
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 #include "buf.h"
25 #include "enc.h"
26 #include "save.h"
28 #define B64LINELEN 72
29 #define B64CRLF "\r\n"
32 * The following VA_COPY was coded following an example in
33 * the Samba project. It may not be sufficient for some
34 * esoteric implementations of va_list (i.e. it may need
35 * something involving a memcpy) but (hopefully) will be
36 * sufficient for libxml2.
38 #ifndef VA_COPY
39 #ifdef HAVE_VA_COPY
40 #define VA_COPY(dest, src) va_copy(dest, src)
41 #else
42 #ifdef HAVE___VA_COPY
43 #define VA_COPY(dest,src) __va_copy(dest, src)
44 #else
45 #define VA_COPY(dest,src) (dest) = (src)
46 #endif
47 #endif
48 #endif
51 * Types are kept private
53 typedef enum {
54 XML_TEXTWRITER_NONE = 0,
55 XML_TEXTWRITER_NAME,
56 XML_TEXTWRITER_ATTRIBUTE,
57 XML_TEXTWRITER_TEXT,
58 XML_TEXTWRITER_PI,
59 XML_TEXTWRITER_PI_TEXT,
60 XML_TEXTWRITER_CDATA,
61 XML_TEXTWRITER_DTD,
62 XML_TEXTWRITER_DTD_TEXT,
63 XML_TEXTWRITER_DTD_ELEM,
64 XML_TEXTWRITER_DTD_ELEM_TEXT,
65 XML_TEXTWRITER_DTD_ATTL,
66 XML_TEXTWRITER_DTD_ATTL_TEXT,
67 XML_TEXTWRITER_DTD_ENTY, /* entity */
68 XML_TEXTWRITER_DTD_ENTY_TEXT,
69 XML_TEXTWRITER_DTD_PENT, /* parameter entity */
70 XML_TEXTWRITER_COMMENT
71 } xmlTextWriterState;
73 typedef struct _xmlTextWriterStackEntry xmlTextWriterStackEntry;
75 struct _xmlTextWriterStackEntry {
76 xmlChar *name;
77 xmlTextWriterState state;
80 typedef struct _xmlTextWriterNsStackEntry xmlTextWriterNsStackEntry;
81 struct _xmlTextWriterNsStackEntry {
82 xmlChar *prefix;
83 xmlChar *uri;
84 xmlLinkPtr elem;
87 struct _xmlTextWriter {
88 xmlOutputBufferPtr out; /* output buffer */
89 xmlListPtr nodes; /* element name stack */
90 xmlListPtr nsstack; /* name spaces stack */
91 int level;
92 int indent; /* enable indent */
93 int doindent; /* internal indent flag */
94 xmlChar *ichar; /* indent character */
95 char qchar; /* character used for quoting attribute values */
96 xmlParserCtxtPtr ctxt;
97 int no_doc_free;
98 xmlDocPtr doc;
101 static void xmlFreeTextWriterStackEntry(xmlLinkPtr lk);
102 static int xmlCmpTextWriterStackEntry(const void *data0,
103 const void *data1);
104 static int xmlTextWriterOutputNSDecl(xmlTextWriterPtr writer);
105 static void xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk);
106 static int xmlCmpTextWriterNsStackEntry(const void *data0,
107 const void *data1);
108 static int xmlTextWriterWriteDocCallback(void *context,
109 const xmlChar * str, int len);
110 static int xmlTextWriterCloseDocCallback(void *context);
112 static xmlChar *xmlTextWriterVSprintf(const char *format, va_list argptr);
113 static int xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len,
114 const unsigned char *data);
115 static void xmlTextWriterStartDocumentCallback(void *ctx);
116 static int xmlTextWriterWriteIndent(xmlTextWriterPtr writer);
117 static int
118 xmlTextWriterHandleStateDependencies(xmlTextWriterPtr writer,
119 xmlTextWriterStackEntry * p);
122 * xmlWriterErrMsg:
123 * @ctxt: a writer context
124 * @error: the error number
125 * @msg: the error message
127 * Handle a writer error
129 static void
130 xmlWriterErrMsg(xmlTextWriterPtr ctxt, xmlParserErrors error,
131 const char *msg)
133 if (ctxt != NULL) {
134 __xmlRaiseError(NULL, NULL, NULL, ctxt->ctxt,
135 NULL, XML_FROM_WRITER, error, XML_ERR_FATAL,
136 NULL, 0, NULL, NULL, NULL, 0, 0, "%s", msg);
137 } else {
138 __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_WRITER, error,
139 XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, 0, 0, "%s", msg);
144 * xmlWriterErrMsgInt:
145 * @ctxt: a writer context
146 * @error: the error number
147 * @msg: the error message
148 * @val: an int
150 * Handle a writer error
152 static void
153 xmlWriterErrMsgInt(xmlTextWriterPtr ctxt, xmlParserErrors error,
154 const char *msg, int val)
156 if (ctxt != NULL) {
157 __xmlRaiseError(NULL, NULL, NULL, ctxt->ctxt,
158 NULL, XML_FROM_WRITER, error, XML_ERR_FATAL,
159 NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
160 } else {
161 __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_WRITER, error,
162 XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
167 * xmlNewTextWriter:
168 * @out: an xmlOutputBufferPtr
170 * Create a new xmlNewTextWriter structure using an xmlOutputBufferPtr
171 * NOTE: the @out parameter will be deallocated when the writer is closed
172 * (if the call succeed.)
174 * Returns the new xmlTextWriterPtr or NULL in case of error
176 xmlTextWriterPtr
177 xmlNewTextWriter(xmlOutputBufferPtr out)
179 xmlTextWriterPtr ret;
181 ret = (xmlTextWriterPtr) xmlMalloc(sizeof(xmlTextWriter));
182 if (ret == NULL) {
183 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
184 "xmlNewTextWriter : out of memory!\n");
185 return NULL;
187 memset(ret, 0, (size_t) sizeof(xmlTextWriter));
189 ret->nodes = xmlListCreate((xmlListDeallocator)
190 xmlFreeTextWriterStackEntry,
191 (xmlListDataCompare)
192 xmlCmpTextWriterStackEntry);
193 if (ret->nodes == NULL) {
194 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
195 "xmlNewTextWriter : out of memory!\n");
196 xmlFree(ret);
197 return NULL;
200 ret->nsstack = xmlListCreate((xmlListDeallocator)
201 xmlFreeTextWriterNsStackEntry,
202 (xmlListDataCompare)
203 xmlCmpTextWriterNsStackEntry);
204 if (ret->nsstack == NULL) {
205 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
206 "xmlNewTextWriter : out of memory!\n");
207 xmlListDelete(ret->nodes);
208 xmlFree(ret);
209 return NULL;
212 ret->out = out;
213 ret->ichar = xmlStrdup(BAD_CAST " ");
214 ret->qchar = '"';
216 if (!ret->ichar) {
217 xmlListDelete(ret->nodes);
218 xmlListDelete(ret->nsstack);
219 xmlFree(ret);
220 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
221 "xmlNewTextWriter : out of memory!\n");
222 return NULL;
225 ret->doc = xmlNewDoc(NULL);
227 ret->no_doc_free = 0;
229 return ret;
233 * xmlNewTextWriterFilename:
234 * @uri: the URI of the resource for the output
235 * @compression: compress the output?
237 * Create a new xmlNewTextWriter structure with @uri as output
239 * Returns the new xmlTextWriterPtr or NULL in case of error
241 xmlTextWriterPtr
242 xmlNewTextWriterFilename(const char *uri, int compression)
244 xmlTextWriterPtr ret;
245 xmlOutputBufferPtr out;
247 out = xmlOutputBufferCreateFilename(uri, NULL, compression);
248 if (out == NULL) {
249 xmlWriterErrMsg(NULL, XML_IO_EIO,
250 "xmlNewTextWriterFilename : cannot open uri\n");
251 return NULL;
254 ret = xmlNewTextWriter(out);
255 if (ret == NULL) {
256 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
257 "xmlNewTextWriterFilename : out of memory!\n");
258 xmlOutputBufferClose(out);
259 return NULL;
262 ret->indent = 0;
263 ret->doindent = 0;
264 return ret;
268 * xmlNewTextWriterMemory:
269 * @buf: xmlBufferPtr
270 * @compression: compress the output?
272 * Create a new xmlNewTextWriter structure with @buf as output
273 * TODO: handle compression
275 * Returns the new xmlTextWriterPtr or NULL in case of error
277 xmlTextWriterPtr
278 xmlNewTextWriterMemory(xmlBufferPtr buf, int compression ATTRIBUTE_UNUSED)
280 xmlTextWriterPtr ret;
281 xmlOutputBufferPtr out;
283 /*::todo handle compression */
284 out = xmlOutputBufferCreateBuffer(buf, NULL);
286 if (out == NULL) {
287 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
288 "xmlNewTextWriterMemory : out of memory!\n");
289 return NULL;
292 ret = xmlNewTextWriter(out);
293 if (ret == NULL) {
294 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
295 "xmlNewTextWriterMemory : out of memory!\n");
296 xmlOutputBufferClose(out);
297 return NULL;
300 return ret;
304 * xmlNewTextWriterPushParser:
305 * @ctxt: xmlParserCtxtPtr to hold the new XML document tree
306 * @compression: compress the output?
308 * Create a new xmlNewTextWriter structure with @ctxt as output
309 * NOTE: the @ctxt context will be freed with the resulting writer
310 * (if the call succeeds).
311 * TODO: handle compression
313 * Returns the new xmlTextWriterPtr or NULL in case of error
315 xmlTextWriterPtr
316 xmlNewTextWriterPushParser(xmlParserCtxtPtr ctxt,
317 int compression ATTRIBUTE_UNUSED)
319 xmlTextWriterPtr ret;
320 xmlOutputBufferPtr out;
322 if (ctxt == NULL) {
323 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
324 "xmlNewTextWriterPushParser : invalid context!\n");
325 return NULL;
328 out = xmlOutputBufferCreateIO((xmlOutputWriteCallback)
329 xmlTextWriterWriteDocCallback,
330 (xmlOutputCloseCallback)
331 xmlTextWriterCloseDocCallback,
332 (void *) ctxt, NULL);
333 if (out == NULL) {
334 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
335 "xmlNewTextWriterPushParser : error at xmlOutputBufferCreateIO!\n");
336 return NULL;
339 ret = xmlNewTextWriter(out);
340 if (ret == NULL) {
341 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
342 "xmlNewTextWriterPushParser : error at xmlNewTextWriter!\n");
343 xmlOutputBufferClose(out);
344 return NULL;
347 ret->ctxt = ctxt;
349 return ret;
353 * xmlNewTextWriterDoc:
354 * @doc: address of a xmlDocPtr to hold the new XML document tree
355 * @compression: compress the output?
357 * Create a new xmlNewTextWriter structure with @*doc as output
359 * Returns the new xmlTextWriterPtr or NULL in case of error
361 xmlTextWriterPtr
362 xmlNewTextWriterDoc(xmlDocPtr * doc, int compression)
364 xmlTextWriterPtr ret;
365 xmlSAXHandler saxHandler;
366 xmlParserCtxtPtr ctxt;
368 memset(&saxHandler, '\0', sizeof(saxHandler));
369 xmlSAX2InitDefaultSAXHandler(&saxHandler, 1);
370 saxHandler.startDocument = xmlTextWriterStartDocumentCallback;
371 saxHandler.startElement = xmlSAX2StartElement;
372 saxHandler.endElement = xmlSAX2EndElement;
374 ctxt = xmlCreatePushParserCtxt(&saxHandler, NULL, NULL, 0, NULL);
375 if (ctxt == NULL) {
376 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
377 "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\n");
378 return NULL;
381 * For some reason this seems to completely break if node names
382 * are interned.
384 ctxt->dictNames = 0;
386 ctxt->myDoc = xmlNewDoc(BAD_CAST XML_DEFAULT_VERSION);
387 if (ctxt->myDoc == NULL) {
388 xmlFreeParserCtxt(ctxt);
389 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
390 "xmlNewTextWriterDoc : error at xmlNewDoc!\n");
391 return NULL;
394 ret = xmlNewTextWriterPushParser(ctxt, compression);
395 if (ret == NULL) {
396 xmlFreeDoc(ctxt->myDoc);
397 xmlFreeParserCtxt(ctxt);
398 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
399 "xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n");
400 return NULL;
403 xmlSetDocCompressMode(ctxt->myDoc, compression);
405 if (doc != NULL) {
406 *doc = ctxt->myDoc;
407 ret->no_doc_free = 1;
410 return ret;
414 * xmlNewTextWriterTree:
415 * @doc: xmlDocPtr
416 * @node: xmlNodePtr or NULL for doc->children
417 * @compression: compress the output?
419 * Create a new xmlNewTextWriter structure with @doc as output
420 * starting at @node
422 * Returns the new xmlTextWriterPtr or NULL in case of error
424 xmlTextWriterPtr
425 xmlNewTextWriterTree(xmlDocPtr doc, xmlNodePtr node, int compression)
427 xmlTextWriterPtr ret;
428 xmlSAXHandler saxHandler;
429 xmlParserCtxtPtr ctxt;
431 if (doc == NULL) {
432 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
433 "xmlNewTextWriterTree : invalid document tree!\n");
434 return NULL;
437 memset(&saxHandler, '\0', sizeof(saxHandler));
438 xmlSAX2InitDefaultSAXHandler(&saxHandler, 1);
439 saxHandler.startDocument = xmlTextWriterStartDocumentCallback;
440 saxHandler.startElement = xmlSAX2StartElement;
441 saxHandler.endElement = xmlSAX2EndElement;
443 ctxt = xmlCreatePushParserCtxt(&saxHandler, NULL, NULL, 0, NULL);
444 if (ctxt == NULL) {
445 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
446 "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\n");
447 return NULL;
450 * For some reason this seems to completely break if node names
451 * are interned.
453 ctxt->dictNames = 0;
455 ret = xmlNewTextWriterPushParser(ctxt, compression);
456 if (ret == NULL) {
457 xmlFreeParserCtxt(ctxt);
458 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
459 "xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n");
460 return NULL;
463 ctxt->myDoc = doc;
464 ctxt->node = node;
465 ret->no_doc_free = 1;
467 xmlSetDocCompressMode(doc, compression);
469 return ret;
473 * xmlFreeTextWriter:
474 * @writer: the xmlTextWriterPtr
476 * Deallocate all the resources associated to the writer
478 void
479 xmlFreeTextWriter(xmlTextWriterPtr writer)
481 if (writer == NULL)
482 return;
484 if (writer->out != NULL)
485 xmlOutputBufferClose(writer->out);
487 if (writer->nodes != NULL)
488 xmlListDelete(writer->nodes);
490 if (writer->nsstack != NULL)
491 xmlListDelete(writer->nsstack);
493 if (writer->ctxt != NULL) {
494 if ((writer->ctxt->myDoc != NULL) && (writer->no_doc_free == 0)) {
495 xmlFreeDoc(writer->ctxt->myDoc);
496 writer->ctxt->myDoc = NULL;
498 xmlFreeParserCtxt(writer->ctxt);
501 if (writer->doc != NULL)
502 xmlFreeDoc(writer->doc);
504 if (writer->ichar != NULL)
505 xmlFree(writer->ichar);
506 xmlFree(writer);
510 * xmlTextWriterStartDocument:
511 * @writer: the xmlTextWriterPtr
512 * @version: the xml version ("1.0") or NULL for default ("1.0")
513 * @encoding: the encoding or NULL for default
514 * @standalone: "yes" or "no" or NULL for default
516 * Start a new xml document
518 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
521 xmlTextWriterStartDocument(xmlTextWriterPtr writer, const char *version,
522 const char *encoding, const char *standalone)
524 int count;
525 int sum;
526 xmlLinkPtr lk;
527 xmlCharEncodingHandlerPtr encoder;
529 if ((writer == NULL) || (writer->out == NULL)) {
530 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
531 "xmlTextWriterStartDocument : invalid writer!\n");
532 return -1;
535 lk = xmlListFront(writer->nodes);
536 if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) {
537 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
538 "xmlTextWriterStartDocument : not allowed in this context!\n");
539 return -1;
542 encoder = NULL;
543 if (encoding != NULL) {
544 encoder = xmlFindCharEncodingHandler(encoding);
545 if (encoder == NULL) {
546 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
547 "xmlTextWriterStartDocument : out of memory!\n");
548 return -1;
552 writer->out->encoder = encoder;
553 if (encoder != NULL) {
554 if (writer->out->conv == NULL) {
555 writer->out->conv = xmlBufCreateSize(4000);
557 xmlCharEncOutput(writer->out, 1);
558 if ((writer->doc != NULL) && (writer->doc->encoding == NULL))
559 writer->doc->encoding = xmlStrdup((xmlChar *)writer->out->encoder->name);
560 } else
561 writer->out->conv = NULL;
563 sum = 0;
564 count = xmlOutputBufferWriteString(writer->out, "<?xml version=");
565 if (count < 0)
566 return -1;
567 sum += count;
568 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
569 if (count < 0)
570 return -1;
571 sum += count;
572 if (version != 0)
573 count = xmlOutputBufferWriteString(writer->out, version);
574 else
575 count = xmlOutputBufferWriteString(writer->out, "1.0");
576 if (count < 0)
577 return -1;
578 sum += count;
579 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
580 if (count < 0)
581 return -1;
582 sum += count;
583 if (writer->out->encoder != 0) {
584 count = xmlOutputBufferWriteString(writer->out, " encoding=");
585 if (count < 0)
586 return -1;
587 sum += count;
588 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
589 if (count < 0)
590 return -1;
591 sum += count;
592 count =
593 xmlOutputBufferWriteString(writer->out,
594 writer->out->encoder->name);
595 if (count < 0)
596 return -1;
597 sum += count;
598 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
599 if (count < 0)
600 return -1;
601 sum += count;
604 if (standalone != 0) {
605 count = xmlOutputBufferWriteString(writer->out, " standalone=");
606 if (count < 0)
607 return -1;
608 sum += count;
609 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
610 if (count < 0)
611 return -1;
612 sum += count;
613 count = xmlOutputBufferWriteString(writer->out, standalone);
614 if (count < 0)
615 return -1;
616 sum += count;
617 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
618 if (count < 0)
619 return -1;
620 sum += count;
623 count = xmlOutputBufferWriteString(writer->out, "?>\n");
624 if (count < 0)
625 return -1;
626 sum += count;
628 return sum;
632 * xmlTextWriterEndDocument:
633 * @writer: the xmlTextWriterPtr
635 * End an xml document. All open elements are closed, and
636 * the content is flushed to the output.
638 * Returns the bytes written or -1 in case of error
641 xmlTextWriterEndDocument(xmlTextWriterPtr writer)
643 int count;
644 int sum;
645 xmlLinkPtr lk;
646 xmlTextWriterStackEntry *p;
648 if (writer == NULL) {
649 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
650 "xmlTextWriterEndDocument : invalid writer!\n");
651 return -1;
654 sum = 0;
655 while ((lk = xmlListFront(writer->nodes)) != NULL) {
656 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
657 if (p == 0)
658 break;
659 switch (p->state) {
660 case XML_TEXTWRITER_NAME:
661 case XML_TEXTWRITER_ATTRIBUTE:
662 case XML_TEXTWRITER_TEXT:
663 count = xmlTextWriterEndElement(writer);
664 if (count < 0)
665 return -1;
666 sum += count;
667 break;
668 case XML_TEXTWRITER_PI:
669 case XML_TEXTWRITER_PI_TEXT:
670 count = xmlTextWriterEndPI(writer);
671 if (count < 0)
672 return -1;
673 sum += count;
674 break;
675 case XML_TEXTWRITER_CDATA:
676 count = xmlTextWriterEndCDATA(writer);
677 if (count < 0)
678 return -1;
679 sum += count;
680 break;
681 case XML_TEXTWRITER_DTD:
682 case XML_TEXTWRITER_DTD_TEXT:
683 case XML_TEXTWRITER_DTD_ELEM:
684 case XML_TEXTWRITER_DTD_ELEM_TEXT:
685 case XML_TEXTWRITER_DTD_ATTL:
686 case XML_TEXTWRITER_DTD_ATTL_TEXT:
687 case XML_TEXTWRITER_DTD_ENTY:
688 case XML_TEXTWRITER_DTD_ENTY_TEXT:
689 case XML_TEXTWRITER_DTD_PENT:
690 count = xmlTextWriterEndDTD(writer);
691 if (count < 0)
692 return -1;
693 sum += count;
694 break;
695 case XML_TEXTWRITER_COMMENT:
696 count = xmlTextWriterEndComment(writer);
697 if (count < 0)
698 return -1;
699 sum += count;
700 break;
701 default:
702 break;
706 if (!writer->indent) {
707 count = xmlOutputBufferWriteString(writer->out, "\n");
708 if (count < 0)
709 return -1;
710 sum += count;
713 sum += xmlTextWriterFlush(writer);
715 return sum;
719 * xmlTextWriterStartComment:
720 * @writer: the xmlTextWriterPtr
722 * Start an xml comment.
724 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
727 xmlTextWriterStartComment(xmlTextWriterPtr writer)
729 int count;
730 int sum;
731 xmlLinkPtr lk;
732 xmlTextWriterStackEntry *p;
734 if (writer == NULL) {
735 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
736 "xmlTextWriterStartComment : invalid writer!\n");
737 return -1;
740 sum = 0;
741 lk = xmlListFront(writer->nodes);
742 if (lk != 0) {
743 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
744 if (p != 0) {
745 switch (p->state) {
746 case XML_TEXTWRITER_TEXT:
747 case XML_TEXTWRITER_NONE:
748 break;
749 case XML_TEXTWRITER_NAME:
750 /* Output namespace declarations */
751 count = xmlTextWriterOutputNSDecl(writer);
752 if (count < 0)
753 return -1;
754 sum += count;
755 count = xmlOutputBufferWriteString(writer->out, ">");
756 if (count < 0)
757 return -1;
758 sum += count;
759 if (writer->indent) {
760 count =
761 xmlOutputBufferWriteString(writer->out, "\n");
762 if (count < 0)
763 return -1;
764 sum += count;
766 p->state = XML_TEXTWRITER_TEXT;
767 break;
768 default:
769 return -1;
774 p = (xmlTextWriterStackEntry *)
775 xmlMalloc(sizeof(xmlTextWriterStackEntry));
776 if (p == 0) {
777 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
778 "xmlTextWriterStartElement : out of memory!\n");
779 return -1;
782 p->name = NULL;
783 p->state = XML_TEXTWRITER_COMMENT;
785 xmlListPushFront(writer->nodes, p);
787 if (writer->indent) {
788 count = xmlTextWriterWriteIndent(writer);
789 if (count < 0)
790 return -1;
791 sum += count;
794 count = xmlOutputBufferWriteString(writer->out, "<!--");
795 if (count < 0)
796 return -1;
797 sum += count;
799 return sum;
803 * xmlTextWriterEndComment:
804 * @writer: the xmlTextWriterPtr
806 * End the current xml coment.
808 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
811 xmlTextWriterEndComment(xmlTextWriterPtr writer)
813 int count;
814 int sum;
815 xmlLinkPtr lk;
816 xmlTextWriterStackEntry *p;
818 if (writer == NULL) {
819 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
820 "xmlTextWriterEndComment : invalid writer!\n");
821 return -1;
824 lk = xmlListFront(writer->nodes);
825 if (lk == 0) {
826 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
827 "xmlTextWriterEndComment : not allowed in this context!\n");
828 return -1;
831 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
832 if (p == 0)
833 return -1;
835 sum = 0;
836 switch (p->state) {
837 case XML_TEXTWRITER_COMMENT:
838 count = xmlOutputBufferWriteString(writer->out, "-->");
839 if (count < 0)
840 return -1;
841 sum += count;
842 break;
843 default:
844 return -1;
847 if (writer->indent) {
848 count = xmlOutputBufferWriteString(writer->out, "\n");
849 if (count < 0)
850 return -1;
851 sum += count;
854 xmlListPopFront(writer->nodes);
855 return sum;
859 * xmlTextWriterWriteFormatComment:
860 * @writer: the xmlTextWriterPtr
861 * @format: format string (see printf)
862 * @...: extra parameters for the format
864 * Write an xml comment.
866 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
868 int XMLCDECL
869 xmlTextWriterWriteFormatComment(xmlTextWriterPtr writer,
870 const char *format, ...)
872 int rc;
873 va_list ap;
875 va_start(ap, format);
877 rc = xmlTextWriterWriteVFormatComment(writer, format, ap);
879 va_end(ap);
880 return rc;
884 * xmlTextWriterWriteVFormatComment:
885 * @writer: the xmlTextWriterPtr
886 * @format: format string (see printf)
887 * @argptr: pointer to the first member of the variable argument list.
889 * Write an xml comment.
891 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
894 xmlTextWriterWriteVFormatComment(xmlTextWriterPtr writer,
895 const char *format, va_list argptr)
897 int rc;
898 xmlChar *buf;
900 if (writer == NULL) {
901 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
902 "xmlTextWriterWriteVFormatComment : invalid writer!\n");
903 return -1;
906 buf = xmlTextWriterVSprintf(format, argptr);
907 if (buf == NULL)
908 return -1;
910 rc = xmlTextWriterWriteComment(writer, buf);
912 xmlFree(buf);
913 return rc;
917 * xmlTextWriterWriteComment:
918 * @writer: the xmlTextWriterPtr
919 * @content: comment string
921 * Write an xml comment.
923 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
926 xmlTextWriterWriteComment(xmlTextWriterPtr writer, const xmlChar * content)
928 int count;
929 int sum;
931 sum = 0;
932 count = xmlTextWriterStartComment(writer);
933 if (count < 0)
934 return -1;
935 sum += count;
936 count = xmlTextWriterWriteString(writer, content);
937 if (count < 0)
938 return -1;
939 sum += count;
940 count = xmlTextWriterEndComment(writer);
941 if (count < 0)
942 return -1;
943 sum += count;
945 return sum;
949 * xmlTextWriterStartElement:
950 * @writer: the xmlTextWriterPtr
951 * @name: element name
953 * Start an xml element.
955 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
958 xmlTextWriterStartElement(xmlTextWriterPtr writer, const xmlChar * name)
960 int count;
961 int sum;
962 xmlLinkPtr lk;
963 xmlTextWriterStackEntry *p;
965 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
966 return -1;
968 sum = 0;
969 lk = xmlListFront(writer->nodes);
970 if (lk != 0) {
971 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
972 if (p != 0) {
973 switch (p->state) {
974 case XML_TEXTWRITER_PI:
975 case XML_TEXTWRITER_PI_TEXT:
976 return -1;
977 case XML_TEXTWRITER_NONE:
978 break;
979 case XML_TEXTWRITER_ATTRIBUTE:
980 count = xmlTextWriterEndAttribute(writer);
981 if (count < 0)
982 return -1;
983 sum += count;
984 /* fallthrough */
985 case XML_TEXTWRITER_NAME:
986 /* Output namespace declarations */
987 count = xmlTextWriterOutputNSDecl(writer);
988 if (count < 0)
989 return -1;
990 sum += count;
991 count = xmlOutputBufferWriteString(writer->out, ">");
992 if (count < 0)
993 return -1;
994 sum += count;
995 if (writer->indent)
996 count =
997 xmlOutputBufferWriteString(writer->out, "\n");
998 p->state = XML_TEXTWRITER_TEXT;
999 break;
1000 default:
1001 break;
1006 p = (xmlTextWriterStackEntry *)
1007 xmlMalloc(sizeof(xmlTextWriterStackEntry));
1008 if (p == 0) {
1009 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
1010 "xmlTextWriterStartElement : out of memory!\n");
1011 return -1;
1014 p->name = xmlStrdup(name);
1015 if (p->name == 0) {
1016 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
1017 "xmlTextWriterStartElement : out of memory!\n");
1018 xmlFree(p);
1019 return -1;
1021 p->state = XML_TEXTWRITER_NAME;
1023 xmlListPushFront(writer->nodes, p);
1025 if (writer->indent) {
1026 count = xmlTextWriterWriteIndent(writer);
1027 sum += count;
1030 count = xmlOutputBufferWriteString(writer->out, "<");
1031 if (count < 0)
1032 return -1;
1033 sum += count;
1034 count =
1035 xmlOutputBufferWriteString(writer->out, (const char *) p->name);
1036 if (count < 0)
1037 return -1;
1038 sum += count;
1040 return sum;
1044 * xmlTextWriterStartElementNS:
1045 * @writer: the xmlTextWriterPtr
1046 * @prefix: namespace prefix or NULL
1047 * @name: element local name
1048 * @namespaceURI: namespace URI or NULL
1050 * Start an xml element with namespace support.
1052 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1055 xmlTextWriterStartElementNS(xmlTextWriterPtr writer,
1056 const xmlChar * prefix, const xmlChar * name,
1057 const xmlChar * namespaceURI)
1059 int count;
1060 int sum;
1061 xmlChar *buf;
1063 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1064 return -1;
1066 buf = NULL;
1067 if (prefix != 0) {
1068 buf = xmlStrdup(prefix);
1069 buf = xmlStrcat(buf, BAD_CAST ":");
1071 buf = xmlStrcat(buf, name);
1073 sum = 0;
1074 count = xmlTextWriterStartElement(writer, buf);
1075 xmlFree(buf);
1076 if (count < 0)
1077 return -1;
1078 sum += count;
1080 if (namespaceURI != 0) {
1081 xmlTextWriterNsStackEntry *p = (xmlTextWriterNsStackEntry *)
1082 xmlMalloc(sizeof(xmlTextWriterNsStackEntry));
1083 if (p == 0) {
1084 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
1085 "xmlTextWriterStartElementNS : out of memory!\n");
1086 return -1;
1089 buf = xmlStrdup(BAD_CAST "xmlns");
1090 if (prefix != 0) {
1091 buf = xmlStrcat(buf, BAD_CAST ":");
1092 buf = xmlStrcat(buf, prefix);
1095 p->prefix = buf;
1096 p->uri = xmlStrdup(namespaceURI);
1097 if (p->uri == 0) {
1098 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
1099 "xmlTextWriterStartElementNS : out of memory!\n");
1100 xmlFree(p);
1101 return -1;
1103 p->elem = xmlListFront(writer->nodes);
1105 xmlListPushFront(writer->nsstack, p);
1108 return sum;
1112 * xmlTextWriterEndElement:
1113 * @writer: the xmlTextWriterPtr
1115 * End the current xml element.
1117 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1120 xmlTextWriterEndElement(xmlTextWriterPtr writer)
1122 int count;
1123 int sum;
1124 xmlLinkPtr lk;
1125 xmlTextWriterStackEntry *p;
1127 if (writer == NULL)
1128 return -1;
1130 lk = xmlListFront(writer->nodes);
1131 if (lk == 0) {
1132 xmlListDelete(writer->nsstack);
1133 writer->nsstack = NULL;
1134 return -1;
1137 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1138 if (p == 0) {
1139 xmlListDelete(writer->nsstack);
1140 writer->nsstack = NULL;
1141 return -1;
1144 sum = 0;
1145 switch (p->state) {
1146 case XML_TEXTWRITER_ATTRIBUTE:
1147 count = xmlTextWriterEndAttribute(writer);
1148 if (count < 0) {
1149 xmlListDelete(writer->nsstack);
1150 writer->nsstack = NULL;
1151 return -1;
1153 sum += count;
1154 /* fallthrough */
1155 case XML_TEXTWRITER_NAME:
1156 /* Output namespace declarations */
1157 count = xmlTextWriterOutputNSDecl(writer);
1158 if (count < 0)
1159 return -1;
1160 sum += count;
1162 if (writer->indent) /* next element needs indent */
1163 writer->doindent = 1;
1164 count = xmlOutputBufferWriteString(writer->out, "/>");
1165 if (count < 0)
1166 return -1;
1167 sum += count;
1168 break;
1169 case XML_TEXTWRITER_TEXT:
1170 if ((writer->indent) && (writer->doindent)) {
1171 count = xmlTextWriterWriteIndent(writer);
1172 sum += count;
1173 writer->doindent = 1;
1174 } else
1175 writer->doindent = 1;
1176 count = xmlOutputBufferWriteString(writer->out, "</");
1177 if (count < 0)
1178 return -1;
1179 sum += count;
1180 count = xmlOutputBufferWriteString(writer->out,
1181 (const char *) p->name);
1182 if (count < 0)
1183 return -1;
1184 sum += count;
1185 count = xmlOutputBufferWriteString(writer->out, ">");
1186 if (count < 0)
1187 return -1;
1188 sum += count;
1189 break;
1190 default:
1191 return -1;
1194 if (writer->indent) {
1195 count = xmlOutputBufferWriteString(writer->out, "\n");
1196 sum += count;
1199 xmlListPopFront(writer->nodes);
1200 return sum;
1204 * xmlTextWriterFullEndElement:
1205 * @writer: the xmlTextWriterPtr
1207 * End the current xml element. Writes an end tag even if the element is empty
1209 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1212 xmlTextWriterFullEndElement(xmlTextWriterPtr writer)
1214 int count;
1215 int sum;
1216 xmlLinkPtr lk;
1217 xmlTextWriterStackEntry *p;
1219 if (writer == NULL)
1220 return -1;
1222 lk = xmlListFront(writer->nodes);
1223 if (lk == 0)
1224 return -1;
1226 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1227 if (p == 0)
1228 return -1;
1230 sum = 0;
1231 switch (p->state) {
1232 case XML_TEXTWRITER_ATTRIBUTE:
1233 count = xmlTextWriterEndAttribute(writer);
1234 if (count < 0)
1235 return -1;
1236 sum += count;
1237 /* fallthrough */
1238 case XML_TEXTWRITER_NAME:
1239 /* Output namespace declarations */
1240 count = xmlTextWriterOutputNSDecl(writer);
1241 if (count < 0)
1242 return -1;
1243 sum += count;
1245 count = xmlOutputBufferWriteString(writer->out, ">");
1246 if (count < 0)
1247 return -1;
1248 sum += count;
1249 if (writer->indent)
1250 writer->doindent = 0;
1251 /* fallthrough */
1252 case XML_TEXTWRITER_TEXT:
1253 if ((writer->indent) && (writer->doindent)) {
1254 count = xmlTextWriterWriteIndent(writer);
1255 sum += count;
1256 writer->doindent = 1;
1257 } else
1258 writer->doindent = 1;
1259 count = xmlOutputBufferWriteString(writer->out, "</");
1260 if (count < 0)
1261 return -1;
1262 sum += count;
1263 count = xmlOutputBufferWriteString(writer->out,
1264 (const char *) p->name);
1265 if (count < 0)
1266 return -1;
1267 sum += count;
1268 count = xmlOutputBufferWriteString(writer->out, ">");
1269 if (count < 0)
1270 return -1;
1271 sum += count;
1272 break;
1273 default:
1274 return -1;
1277 if (writer->indent) {
1278 count = xmlOutputBufferWriteString(writer->out, "\n");
1279 sum += count;
1282 xmlListPopFront(writer->nodes);
1283 return sum;
1287 * xmlTextWriterWriteFormatRaw:
1288 * @writer: the xmlTextWriterPtr
1289 * @format: format string (see printf)
1290 * @...: extra parameters for the format
1292 * Write a formatted raw xml text.
1294 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1296 int XMLCDECL
1297 xmlTextWriterWriteFormatRaw(xmlTextWriterPtr writer, const char *format,
1298 ...)
1300 int rc;
1301 va_list ap;
1303 va_start(ap, format);
1305 rc = xmlTextWriterWriteVFormatRaw(writer, format, ap);
1307 va_end(ap);
1308 return rc;
1312 * xmlTextWriterWriteVFormatRaw:
1313 * @writer: the xmlTextWriterPtr
1314 * @format: format string (see printf)
1315 * @argptr: pointer to the first member of the variable argument list.
1317 * Write a formatted raw xml text.
1319 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1322 xmlTextWriterWriteVFormatRaw(xmlTextWriterPtr writer, const char *format,
1323 va_list argptr)
1325 int rc;
1326 xmlChar *buf;
1328 if (writer == NULL)
1329 return -1;
1331 buf = xmlTextWriterVSprintf(format, argptr);
1332 if (buf == NULL)
1333 return -1;
1335 rc = xmlTextWriterWriteRaw(writer, buf);
1337 xmlFree(buf);
1338 return rc;
1342 * xmlTextWriterWriteRawLen:
1343 * @writer: the xmlTextWriterPtr
1344 * @content: text string
1345 * @len: length of the text string
1347 * Write an xml text.
1348 * TODO: what about entities and special chars??
1350 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1353 xmlTextWriterWriteRawLen(xmlTextWriterPtr writer, const xmlChar * content,
1354 int len)
1356 int count;
1357 int sum;
1358 xmlLinkPtr lk;
1359 xmlTextWriterStackEntry *p;
1361 if (writer == NULL) {
1362 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
1363 "xmlTextWriterWriteRawLen : invalid writer!\n");
1364 return -1;
1367 if ((content == NULL) || (len < 0)) {
1368 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
1369 "xmlTextWriterWriteRawLen : invalid content!\n");
1370 return -1;
1373 sum = 0;
1374 lk = xmlListFront(writer->nodes);
1375 if (lk != 0) {
1376 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1377 count = xmlTextWriterHandleStateDependencies(writer, p);
1378 if (count < 0)
1379 return -1;
1380 sum += count;
1383 if (writer->indent)
1384 writer->doindent = 0;
1386 if (content != NULL) {
1387 count =
1388 xmlOutputBufferWrite(writer->out, len, (const char *) content);
1389 if (count < 0)
1390 return -1;
1391 sum += count;
1394 return sum;
1398 * xmlTextWriterWriteRaw:
1399 * @writer: the xmlTextWriterPtr
1400 * @content: text string
1402 * Write a raw xml text.
1404 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1407 xmlTextWriterWriteRaw(xmlTextWriterPtr writer, const xmlChar * content)
1409 return xmlTextWriterWriteRawLen(writer, content, xmlStrlen(content));
1413 * xmlTextWriterWriteFormatString:
1414 * @writer: the xmlTextWriterPtr
1415 * @format: format string (see printf)
1416 * @...: extra parameters for the format
1418 * Write a formatted xml text.
1420 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1422 int XMLCDECL
1423 xmlTextWriterWriteFormatString(xmlTextWriterPtr writer, const char *format,
1424 ...)
1426 int rc;
1427 va_list ap;
1429 if ((writer == NULL) || (format == NULL))
1430 return -1;
1432 va_start(ap, format);
1434 rc = xmlTextWriterWriteVFormatString(writer, format, ap);
1436 va_end(ap);
1437 return rc;
1441 * xmlTextWriterWriteVFormatString:
1442 * @writer: the xmlTextWriterPtr
1443 * @format: format string (see printf)
1444 * @argptr: pointer to the first member of the variable argument list.
1446 * Write a formatted xml text.
1448 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1451 xmlTextWriterWriteVFormatString(xmlTextWriterPtr writer,
1452 const char *format, va_list argptr)
1454 int rc;
1455 xmlChar *buf;
1457 if ((writer == NULL) || (format == NULL))
1458 return -1;
1460 buf = xmlTextWriterVSprintf(format, argptr);
1461 if (buf == NULL)
1462 return -1;
1464 rc = xmlTextWriterWriteString(writer, buf);
1466 xmlFree(buf);
1467 return rc;
1471 * xmlTextWriterWriteString:
1472 * @writer: the xmlTextWriterPtr
1473 * @content: text string
1475 * Write an xml text.
1477 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1480 xmlTextWriterWriteString(xmlTextWriterPtr writer, const xmlChar * content)
1482 int count;
1483 int sum;
1484 xmlLinkPtr lk;
1485 xmlTextWriterStackEntry *p;
1486 xmlChar *buf;
1488 if ((writer == NULL) || (content == NULL))
1489 return -1;
1491 sum = 0;
1492 buf = (xmlChar *) content;
1493 lk = xmlListFront(writer->nodes);
1494 if (lk != 0) {
1495 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1496 if (p != 0) {
1497 switch (p->state) {
1498 case XML_TEXTWRITER_NAME:
1499 case XML_TEXTWRITER_TEXT:
1500 #if 0
1501 buf = NULL;
1502 xmlOutputBufferWriteEscape(writer->out, content, NULL);
1503 #endif
1504 buf = xmlEncodeSpecialChars(NULL, content);
1505 break;
1506 case XML_TEXTWRITER_ATTRIBUTE:
1507 buf = NULL;
1508 xmlBufAttrSerializeTxtContent(writer->out->buffer,
1509 writer->doc, NULL, content);
1510 break;
1511 default:
1512 break;
1517 if (buf != NULL) {
1518 count = xmlTextWriterWriteRaw(writer, buf);
1520 if (buf != content) /* buf was allocated by us, so free it */
1521 xmlFree(buf);
1523 if (count < 0)
1524 return -1;
1525 sum += count;
1528 return sum;
1532 * xmlOutputBufferWriteBase64:
1533 * @out: the xmlOutputBufferPtr
1534 * @data: binary data
1535 * @len: the number of bytes to encode
1537 * Write base64 encoded data to an xmlOutputBuffer.
1538 * Adapted from John Walker's base64.c (http://www.fourmilab.ch/).
1540 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1542 static int
1543 xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len,
1544 const unsigned char *data)
1546 static unsigned char dtable[64] =
1547 {'A','B','C','D','E','F','G','H','I','J','K','L','M',
1548 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
1549 'a','b','c','d','e','f','g','h','i','j','k','l','m',
1550 'n','o','p','q','r','s','t','u','v','w','x','y','z',
1551 '0','1','2','3','4','5','6','7','8','9','+','/'};
1553 int i;
1554 int linelen;
1555 int count;
1556 int sum;
1558 if ((out == NULL) || (len < 0) || (data == NULL))
1559 return(-1);
1561 linelen = 0;
1562 sum = 0;
1564 i = 0;
1565 while (1) {
1566 unsigned char igroup[3];
1567 unsigned char ogroup[4];
1568 int c;
1569 int n;
1571 igroup[0] = igroup[1] = igroup[2] = 0;
1572 for (n = 0; n < 3 && i < len; n++, i++) {
1573 c = data[i];
1574 igroup[n] = (unsigned char) c;
1577 if (n > 0) {
1578 ogroup[0] = dtable[igroup[0] >> 2];
1579 ogroup[1] = dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)];
1580 ogroup[2] =
1581 dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)];
1582 ogroup[3] = dtable[igroup[2] & 0x3F];
1584 if (n < 3) {
1585 ogroup[3] = '=';
1586 if (n < 2) {
1587 ogroup[2] = '=';
1591 if (linelen >= B64LINELEN) {
1592 count = xmlOutputBufferWrite(out, 2, B64CRLF);
1593 if (count == -1)
1594 return -1;
1595 sum += count;
1596 linelen = 0;
1598 count = xmlOutputBufferWrite(out, 4, (const char *) ogroup);
1599 if (count == -1)
1600 return -1;
1601 sum += count;
1603 linelen += 4;
1606 if (i >= len)
1607 break;
1610 return sum;
1614 * xmlTextWriterWriteBase64:
1615 * @writer: the xmlTextWriterPtr
1616 * @data: binary data
1617 * @start: the position within the data of the first byte to encode
1618 * @len: the number of bytes to encode
1620 * Write an base64 encoded xml text.
1622 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1625 xmlTextWriterWriteBase64(xmlTextWriterPtr writer, const char *data,
1626 int start, int len)
1628 int count;
1629 int sum;
1630 xmlLinkPtr lk;
1631 xmlTextWriterStackEntry *p;
1633 if ((writer == NULL) || (data == NULL) || (start < 0) || (len < 0))
1634 return -1;
1636 sum = 0;
1637 lk = xmlListFront(writer->nodes);
1638 if (lk != 0) {
1639 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1640 if (p != 0) {
1641 count = xmlTextWriterHandleStateDependencies(writer, p);
1642 if (count < 0)
1643 return -1;
1644 sum += count;
1648 if (writer->indent)
1649 writer->doindent = 0;
1651 count =
1652 xmlOutputBufferWriteBase64(writer->out, len,
1653 (unsigned char *) data + start);
1654 if (count < 0)
1655 return -1;
1656 sum += count;
1658 return sum;
1662 * xmlOutputBufferWriteBinHex:
1663 * @out: the xmlOutputBufferPtr
1664 * @data: binary data
1665 * @len: the number of bytes to encode
1667 * Write hqx encoded data to an xmlOutputBuffer.
1668 * ::todo
1670 * Returns the bytes written (may be 0 because of buffering)
1671 * or -1 in case of error
1673 static int
1674 xmlOutputBufferWriteBinHex(xmlOutputBufferPtr out,
1675 int len, const unsigned char *data)
1677 int count;
1678 int sum;
1679 static char hex[16] =
1680 {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
1681 int i;
1683 if ((out == NULL) || (data == NULL) || (len < 0)) {
1684 return -1;
1687 sum = 0;
1688 for (i = 0; i < len; i++) {
1689 count =
1690 xmlOutputBufferWrite(out, 1,
1691 (const char *) &hex[data[i] >> 4]);
1692 if (count == -1)
1693 return -1;
1694 sum += count;
1695 count =
1696 xmlOutputBufferWrite(out, 1,
1697 (const char *) &hex[data[i] & 0xF]);
1698 if (count == -1)
1699 return -1;
1700 sum += count;
1703 return sum;
1707 * xmlTextWriterWriteBinHex:
1708 * @writer: the xmlTextWriterPtr
1709 * @data: binary data
1710 * @start: the position within the data of the first byte to encode
1711 * @len: the number of bytes to encode
1713 * Write a BinHex encoded xml text.
1715 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1718 xmlTextWriterWriteBinHex(xmlTextWriterPtr writer, const char *data,
1719 int start, int len)
1721 int count;
1722 int sum;
1723 xmlLinkPtr lk;
1724 xmlTextWriterStackEntry *p;
1726 if ((writer == NULL) || (data == NULL) || (start < 0) || (len < 0))
1727 return -1;
1729 sum = 0;
1730 lk = xmlListFront(writer->nodes);
1731 if (lk != 0) {
1732 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1733 if (p != 0) {
1734 count = xmlTextWriterHandleStateDependencies(writer, p);
1735 if (count < 0)
1736 return -1;
1737 sum += count;
1741 if (writer->indent)
1742 writer->doindent = 0;
1744 count =
1745 xmlOutputBufferWriteBinHex(writer->out, len,
1746 (unsigned char *) data + start);
1747 if (count < 0)
1748 return -1;
1749 sum += count;
1751 return sum;
1755 * xmlTextWriterStartAttribute:
1756 * @writer: the xmlTextWriterPtr
1757 * @name: element name
1759 * Start an xml attribute.
1761 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1764 xmlTextWriterStartAttribute(xmlTextWriterPtr writer, const xmlChar * name)
1766 int count;
1767 int sum;
1768 xmlLinkPtr lk;
1769 xmlTextWriterStackEntry *p;
1771 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1772 return -1;
1774 sum = 0;
1775 lk = xmlListFront(writer->nodes);
1776 if (lk == 0)
1777 return -1;
1779 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1780 if (p == 0)
1781 return -1;
1783 switch (p->state) {
1784 case XML_TEXTWRITER_ATTRIBUTE:
1785 count = xmlTextWriterEndAttribute(writer);
1786 if (count < 0)
1787 return -1;
1788 sum += count;
1789 /* fallthrough */
1790 case XML_TEXTWRITER_NAME:
1791 count = xmlOutputBufferWriteString(writer->out, " ");
1792 if (count < 0)
1793 return -1;
1794 sum += count;
1795 count =
1796 xmlOutputBufferWriteString(writer->out,
1797 (const char *) name);
1798 if (count < 0)
1799 return -1;
1800 sum += count;
1801 count = xmlOutputBufferWriteString(writer->out, "=");
1802 if (count < 0)
1803 return -1;
1804 sum += count;
1805 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
1806 if (count < 0)
1807 return -1;
1808 sum += count;
1809 p->state = XML_TEXTWRITER_ATTRIBUTE;
1810 break;
1811 default:
1812 return -1;
1815 return sum;
1819 * xmlTextWriterStartAttributeNS:
1820 * @writer: the xmlTextWriterPtr
1821 * @prefix: namespace prefix or NULL
1822 * @name: element local name
1823 * @namespaceURI: namespace URI or NULL
1825 * Start an xml attribute with namespace support.
1827 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1830 xmlTextWriterStartAttributeNS(xmlTextWriterPtr writer,
1831 const xmlChar * prefix, const xmlChar * name,
1832 const xmlChar * namespaceURI)
1834 int count;
1835 int sum;
1836 xmlChar *buf;
1837 xmlTextWriterNsStackEntry *p;
1839 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1840 return -1;
1842 /* Handle namespace first in case of error */
1843 if (namespaceURI != 0) {
1844 xmlTextWriterNsStackEntry nsentry, *curns;
1846 buf = xmlStrdup(BAD_CAST "xmlns");
1847 if (prefix != 0) {
1848 buf = xmlStrcat(buf, BAD_CAST ":");
1849 buf = xmlStrcat(buf, prefix);
1852 nsentry.prefix = buf;
1853 nsentry.uri = (xmlChar *)namespaceURI;
1854 nsentry.elem = xmlListFront(writer->nodes);
1856 curns = (xmlTextWriterNsStackEntry *)xmlListSearch(writer->nsstack,
1857 (void *)&nsentry);
1858 if ((curns != NULL)) {
1859 xmlFree(buf);
1860 if (xmlStrcmp(curns->uri, namespaceURI) == 0) {
1861 /* Namespace already defined on element skip */
1862 buf = NULL;
1863 } else {
1864 /* Prefix mismatch so error out */
1865 return -1;
1869 /* Do not add namespace decl to list - it is already there */
1870 if (buf != NULL) {
1871 p = (xmlTextWriterNsStackEntry *)
1872 xmlMalloc(sizeof(xmlTextWriterNsStackEntry));
1873 if (p == 0) {
1874 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
1875 "xmlTextWriterStartAttributeNS : out of memory!\n");
1876 return -1;
1879 p->prefix = buf;
1880 p->uri = xmlStrdup(namespaceURI);
1881 if (p->uri == 0) {
1882 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
1883 "xmlTextWriterStartAttributeNS : out of memory!\n");
1884 xmlFree(p);
1885 return -1;
1887 p->elem = xmlListFront(writer->nodes);
1889 xmlListPushFront(writer->nsstack, p);
1893 buf = NULL;
1894 if (prefix != 0) {
1895 buf = xmlStrdup(prefix);
1896 buf = xmlStrcat(buf, BAD_CAST ":");
1898 buf = xmlStrcat(buf, name);
1900 sum = 0;
1901 count = xmlTextWriterStartAttribute(writer, buf);
1902 xmlFree(buf);
1903 if (count < 0)
1904 return -1;
1905 sum += count;
1907 return sum;
1911 * xmlTextWriterEndAttribute:
1912 * @writer: the xmlTextWriterPtr
1914 * End the current xml element.
1916 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1919 xmlTextWriterEndAttribute(xmlTextWriterPtr writer)
1921 int count;
1922 int sum;
1923 xmlLinkPtr lk;
1924 xmlTextWriterStackEntry *p;
1926 if (writer == NULL)
1927 return -1;
1929 lk = xmlListFront(writer->nodes);
1930 if (lk == 0) {
1931 return -1;
1934 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1935 if (p == 0) {
1936 return -1;
1939 sum = 0;
1940 switch (p->state) {
1941 case XML_TEXTWRITER_ATTRIBUTE:
1942 p->state = XML_TEXTWRITER_NAME;
1944 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
1945 if (count < 0) {
1946 return -1;
1948 sum += count;
1949 break;
1950 default:
1951 return -1;
1954 return sum;
1958 * xmlTextWriterWriteFormatAttribute:
1959 * @writer: the xmlTextWriterPtr
1960 * @name: attribute name
1961 * @format: format string (see printf)
1962 * @...: extra parameters for the format
1964 * Write a formatted xml attribute.
1966 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1968 int XMLCDECL
1969 xmlTextWriterWriteFormatAttribute(xmlTextWriterPtr writer,
1970 const xmlChar * name, const char *format,
1971 ...)
1973 int rc;
1974 va_list ap;
1976 va_start(ap, format);
1978 rc = xmlTextWriterWriteVFormatAttribute(writer, name, format, ap);
1980 va_end(ap);
1981 return rc;
1985 * xmlTextWriterWriteVFormatAttribute:
1986 * @writer: the xmlTextWriterPtr
1987 * @name: attribute name
1988 * @format: format string (see printf)
1989 * @argptr: pointer to the first member of the variable argument list.
1991 * Write a formatted xml attribute.
1993 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1996 xmlTextWriterWriteVFormatAttribute(xmlTextWriterPtr writer,
1997 const xmlChar * name,
1998 const char *format, va_list argptr)
2000 int rc;
2001 xmlChar *buf;
2003 if (writer == NULL)
2004 return -1;
2006 buf = xmlTextWriterVSprintf(format, argptr);
2007 if (buf == NULL)
2008 return -1;
2010 rc = xmlTextWriterWriteAttribute(writer, name, buf);
2012 xmlFree(buf);
2013 return rc;
2017 * xmlTextWriterWriteAttribute:
2018 * @writer: the xmlTextWriterPtr
2019 * @name: attribute name
2020 * @content: attribute content
2022 * Write an xml attribute.
2024 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2027 xmlTextWriterWriteAttribute(xmlTextWriterPtr writer, const xmlChar * name,
2028 const xmlChar * content)
2030 int count;
2031 int sum;
2033 sum = 0;
2034 count = xmlTextWriterStartAttribute(writer, name);
2035 if (count < 0)
2036 return -1;
2037 sum += count;
2038 count = xmlTextWriterWriteString(writer, content);
2039 if (count < 0)
2040 return -1;
2041 sum += count;
2042 count = xmlTextWriterEndAttribute(writer);
2043 if (count < 0)
2044 return -1;
2045 sum += count;
2047 return sum;
2051 * xmlTextWriterWriteFormatAttributeNS:
2052 * @writer: the xmlTextWriterPtr
2053 * @prefix: namespace prefix
2054 * @name: attribute local name
2055 * @namespaceURI: namespace URI
2056 * @format: format string (see printf)
2057 * @...: extra parameters for the format
2059 * Write a formatted xml attribute.with namespace support
2061 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2063 int XMLCDECL
2064 xmlTextWriterWriteFormatAttributeNS(xmlTextWriterPtr writer,
2065 const xmlChar * prefix,
2066 const xmlChar * name,
2067 const xmlChar * namespaceURI,
2068 const char *format, ...)
2070 int rc;
2071 va_list ap;
2073 va_start(ap, format);
2075 rc = xmlTextWriterWriteVFormatAttributeNS(writer, prefix, name,
2076 namespaceURI, format, ap);
2078 va_end(ap);
2079 return rc;
2083 * xmlTextWriterWriteVFormatAttributeNS:
2084 * @writer: the xmlTextWriterPtr
2085 * @prefix: namespace prefix
2086 * @name: attribute local name
2087 * @namespaceURI: namespace URI
2088 * @format: format string (see printf)
2089 * @argptr: pointer to the first member of the variable argument list.
2091 * Write a formatted xml attribute.with namespace support
2093 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2096 xmlTextWriterWriteVFormatAttributeNS(xmlTextWriterPtr writer,
2097 const xmlChar * prefix,
2098 const xmlChar * name,
2099 const xmlChar * namespaceURI,
2100 const char *format, va_list argptr)
2102 int rc;
2103 xmlChar *buf;
2105 if (writer == NULL)
2106 return -1;
2108 buf = xmlTextWriterVSprintf(format, argptr);
2109 if (buf == NULL)
2110 return -1;
2112 rc = xmlTextWriterWriteAttributeNS(writer, prefix, name, namespaceURI,
2113 buf);
2115 xmlFree(buf);
2116 return rc;
2120 * xmlTextWriterWriteAttributeNS:
2121 * @writer: the xmlTextWriterPtr
2122 * @prefix: namespace prefix
2123 * @name: attribute local name
2124 * @namespaceURI: namespace URI
2125 * @content: attribute content
2127 * Write an xml attribute.
2129 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2132 xmlTextWriterWriteAttributeNS(xmlTextWriterPtr writer,
2133 const xmlChar * prefix, const xmlChar * name,
2134 const xmlChar * namespaceURI,
2135 const xmlChar * content)
2137 int count;
2138 int sum;
2140 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
2141 return -1;
2143 sum = 0;
2144 count = xmlTextWriterStartAttributeNS(writer, prefix, name, namespaceURI);
2145 if (count < 0)
2146 return -1;
2147 sum += count;
2148 count = xmlTextWriterWriteString(writer, content);
2149 if (count < 0)
2150 return -1;
2151 sum += count;
2152 count = xmlTextWriterEndAttribute(writer);
2153 if (count < 0)
2154 return -1;
2155 sum += count;
2157 return sum;
2161 * xmlTextWriterWriteFormatElement:
2162 * @writer: the xmlTextWriterPtr
2163 * @name: element name
2164 * @format: format string (see printf)
2165 * @...: extra parameters for the format
2167 * Write a formatted xml element.
2169 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2171 int XMLCDECL
2172 xmlTextWriterWriteFormatElement(xmlTextWriterPtr writer,
2173 const xmlChar * name, const char *format,
2174 ...)
2176 int rc;
2177 va_list ap;
2179 va_start(ap, format);
2181 rc = xmlTextWriterWriteVFormatElement(writer, name, format, ap);
2183 va_end(ap);
2184 return rc;
2188 * xmlTextWriterWriteVFormatElement:
2189 * @writer: the xmlTextWriterPtr
2190 * @name: element name
2191 * @format: format string (see printf)
2192 * @argptr: pointer to the first member of the variable argument list.
2194 * Write a formatted xml element.
2196 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2199 xmlTextWriterWriteVFormatElement(xmlTextWriterPtr writer,
2200 const xmlChar * name, const char *format,
2201 va_list argptr)
2203 int rc;
2204 xmlChar *buf;
2206 if (writer == NULL)
2207 return -1;
2209 buf = xmlTextWriterVSprintf(format, argptr);
2210 if (buf == NULL)
2211 return -1;
2213 rc = xmlTextWriterWriteElement(writer, name, buf);
2215 xmlFree(buf);
2216 return rc;
2220 * xmlTextWriterWriteElement:
2221 * @writer: the xmlTextWriterPtr
2222 * @name: element name
2223 * @content: element content
2225 * Write an xml element.
2227 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2230 xmlTextWriterWriteElement(xmlTextWriterPtr writer, const xmlChar * name,
2231 const xmlChar * content)
2233 int count;
2234 int sum;
2236 sum = 0;
2237 count = xmlTextWriterStartElement(writer, name);
2238 if (count == -1)
2239 return -1;
2240 sum += count;
2241 count = xmlTextWriterWriteString(writer, content);
2242 if (count == -1)
2243 return -1;
2244 sum += count;
2245 count = xmlTextWriterEndElement(writer);
2246 if (count == -1)
2247 return -1;
2248 sum += count;
2250 return sum;
2254 * xmlTextWriterWriteFormatElementNS:
2255 * @writer: the xmlTextWriterPtr
2256 * @prefix: namespace prefix
2257 * @name: element local name
2258 * @namespaceURI: namespace URI
2259 * @format: format string (see printf)
2260 * @...: extra parameters for the format
2262 * Write a formatted xml element with namespace support.
2264 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2266 int XMLCDECL
2267 xmlTextWriterWriteFormatElementNS(xmlTextWriterPtr writer,
2268 const xmlChar * prefix,
2269 const xmlChar * name,
2270 const xmlChar * namespaceURI,
2271 const char *format, ...)
2273 int rc;
2274 va_list ap;
2276 va_start(ap, format);
2278 rc = xmlTextWriterWriteVFormatElementNS(writer, prefix, name,
2279 namespaceURI, format, ap);
2281 va_end(ap);
2282 return rc;
2286 * xmlTextWriterWriteVFormatElementNS:
2287 * @writer: the xmlTextWriterPtr
2288 * @prefix: namespace prefix
2289 * @name: element local name
2290 * @namespaceURI: namespace URI
2291 * @format: format string (see printf)
2292 * @argptr: pointer to the first member of the variable argument list.
2294 * Write a formatted xml element with namespace support.
2296 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2299 xmlTextWriterWriteVFormatElementNS(xmlTextWriterPtr writer,
2300 const xmlChar * prefix,
2301 const xmlChar * name,
2302 const xmlChar * namespaceURI,
2303 const char *format, va_list argptr)
2305 int rc;
2306 xmlChar *buf;
2308 if (writer == NULL)
2309 return -1;
2311 buf = xmlTextWriterVSprintf(format, argptr);
2312 if (buf == NULL)
2313 return -1;
2315 rc = xmlTextWriterWriteElementNS(writer, prefix, name, namespaceURI,
2316 buf);
2318 xmlFree(buf);
2319 return rc;
2323 * xmlTextWriterWriteElementNS:
2324 * @writer: the xmlTextWriterPtr
2325 * @prefix: namespace prefix
2326 * @name: element local name
2327 * @namespaceURI: namespace URI
2328 * @content: element content
2330 * Write an xml element with namespace support.
2332 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2335 xmlTextWriterWriteElementNS(xmlTextWriterPtr writer,
2336 const xmlChar * prefix, const xmlChar * name,
2337 const xmlChar * namespaceURI,
2338 const xmlChar * content)
2340 int count;
2341 int sum;
2343 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
2344 return -1;
2346 sum = 0;
2347 count =
2348 xmlTextWriterStartElementNS(writer, prefix, name, namespaceURI);
2349 if (count < 0)
2350 return -1;
2351 sum += count;
2352 count = xmlTextWriterWriteString(writer, content);
2353 if (count == -1)
2354 return -1;
2355 sum += count;
2356 count = xmlTextWriterEndElement(writer);
2357 if (count == -1)
2358 return -1;
2359 sum += count;
2361 return sum;
2365 * xmlTextWriterStartPI:
2366 * @writer: the xmlTextWriterPtr
2367 * @target: PI target
2369 * Start an xml PI.
2371 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2374 xmlTextWriterStartPI(xmlTextWriterPtr writer, const xmlChar * target)
2376 int count;
2377 int sum;
2378 xmlLinkPtr lk;
2379 xmlTextWriterStackEntry *p;
2381 if ((writer == NULL) || (target == NULL) || (*target == '\0'))
2382 return -1;
2384 if (xmlStrcasecmp(target, (const xmlChar *) "xml") == 0) {
2385 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
2386 "xmlTextWriterStartPI : target name [Xx][Mm][Ll] is reserved for xml standardization!\n");
2387 return -1;
2390 sum = 0;
2391 lk = xmlListFront(writer->nodes);
2392 if (lk != 0) {
2393 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2394 if (p != 0) {
2395 switch (p->state) {
2396 case XML_TEXTWRITER_ATTRIBUTE:
2397 count = xmlTextWriterEndAttribute(writer);
2398 if (count < 0)
2399 return -1;
2400 sum += count;
2401 /* fallthrough */
2402 case XML_TEXTWRITER_NAME:
2403 /* Output namespace declarations */
2404 count = xmlTextWriterOutputNSDecl(writer);
2405 if (count < 0)
2406 return -1;
2407 sum += count;
2408 count = xmlOutputBufferWriteString(writer->out, ">");
2409 if (count < 0)
2410 return -1;
2411 sum += count;
2412 p->state = XML_TEXTWRITER_TEXT;
2413 break;
2414 case XML_TEXTWRITER_NONE:
2415 case XML_TEXTWRITER_TEXT:
2416 case XML_TEXTWRITER_DTD:
2417 break;
2418 case XML_TEXTWRITER_PI:
2419 case XML_TEXTWRITER_PI_TEXT:
2420 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
2421 "xmlTextWriterStartPI : nested PI!\n");
2422 return -1;
2423 default:
2424 return -1;
2429 p = (xmlTextWriterStackEntry *)
2430 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2431 if (p == 0) {
2432 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
2433 "xmlTextWriterStartPI : out of memory!\n");
2434 return -1;
2437 p->name = xmlStrdup(target);
2438 if (p->name == 0) {
2439 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
2440 "xmlTextWriterStartPI : out of memory!\n");
2441 xmlFree(p);
2442 return -1;
2444 p->state = XML_TEXTWRITER_PI;
2446 xmlListPushFront(writer->nodes, p);
2448 count = xmlOutputBufferWriteString(writer->out, "<?");
2449 if (count < 0)
2450 return -1;
2451 sum += count;
2452 count =
2453 xmlOutputBufferWriteString(writer->out, (const char *) p->name);
2454 if (count < 0)
2455 return -1;
2456 sum += count;
2458 return sum;
2462 * xmlTextWriterEndPI:
2463 * @writer: the xmlTextWriterPtr
2465 * End the current xml PI.
2467 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2470 xmlTextWriterEndPI(xmlTextWriterPtr writer)
2472 int count;
2473 int sum;
2474 xmlLinkPtr lk;
2475 xmlTextWriterStackEntry *p;
2477 if (writer == NULL)
2478 return -1;
2480 lk = xmlListFront(writer->nodes);
2481 if (lk == 0)
2482 return 0;
2484 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2485 if (p == 0)
2486 return 0;
2488 sum = 0;
2489 switch (p->state) {
2490 case XML_TEXTWRITER_PI:
2491 case XML_TEXTWRITER_PI_TEXT:
2492 count = xmlOutputBufferWriteString(writer->out, "?>");
2493 if (count < 0)
2494 return -1;
2495 sum += count;
2496 break;
2497 default:
2498 return -1;
2501 if (writer->indent) {
2502 count = xmlOutputBufferWriteString(writer->out, "\n");
2503 if (count < 0)
2504 return -1;
2505 sum += count;
2508 xmlListPopFront(writer->nodes);
2509 return sum;
2513 * xmlTextWriterWriteFormatPI:
2514 * @writer: the xmlTextWriterPtr
2515 * @target: PI target
2516 * @format: format string (see printf)
2517 * @...: extra parameters for the format
2519 * Write a formatted PI.
2521 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2523 int XMLCDECL
2524 xmlTextWriterWriteFormatPI(xmlTextWriterPtr writer, const xmlChar * target,
2525 const char *format, ...)
2527 int rc;
2528 va_list ap;
2530 va_start(ap, format);
2532 rc = xmlTextWriterWriteVFormatPI(writer, target, format, ap);
2534 va_end(ap);
2535 return rc;
2539 * xmlTextWriterWriteVFormatPI:
2540 * @writer: the xmlTextWriterPtr
2541 * @target: PI target
2542 * @format: format string (see printf)
2543 * @argptr: pointer to the first member of the variable argument list.
2545 * Write a formatted xml PI.
2547 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2550 xmlTextWriterWriteVFormatPI(xmlTextWriterPtr writer,
2551 const xmlChar * target, const char *format,
2552 va_list argptr)
2554 int rc;
2555 xmlChar *buf;
2557 if (writer == NULL)
2558 return -1;
2560 buf = xmlTextWriterVSprintf(format, argptr);
2561 if (buf == NULL)
2562 return -1;
2564 rc = xmlTextWriterWritePI(writer, target, buf);
2566 xmlFree(buf);
2567 return rc;
2571 * xmlTextWriterWritePI:
2572 * @writer: the xmlTextWriterPtr
2573 * @target: PI target
2574 * @content: PI content
2576 * Write an xml PI.
2578 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2581 xmlTextWriterWritePI(xmlTextWriterPtr writer, const xmlChar * target,
2582 const xmlChar * content)
2584 int count;
2585 int sum;
2587 sum = 0;
2588 count = xmlTextWriterStartPI(writer, target);
2589 if (count == -1)
2590 return -1;
2591 sum += count;
2592 if (content != 0) {
2593 count = xmlTextWriterWriteString(writer, content);
2594 if (count == -1)
2595 return -1;
2596 sum += count;
2598 count = xmlTextWriterEndPI(writer);
2599 if (count == -1)
2600 return -1;
2601 sum += count;
2603 return sum;
2607 * xmlTextWriterStartCDATA:
2608 * @writer: the xmlTextWriterPtr
2610 * Start an xml CDATA section.
2612 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2615 xmlTextWriterStartCDATA(xmlTextWriterPtr writer)
2617 int count;
2618 int sum;
2619 xmlLinkPtr lk;
2620 xmlTextWriterStackEntry *p;
2622 if (writer == NULL)
2623 return -1;
2625 sum = 0;
2626 lk = xmlListFront(writer->nodes);
2627 if (lk != 0) {
2628 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2629 if (p != 0) {
2630 switch (p->state) {
2631 case XML_TEXTWRITER_NONE:
2632 case XML_TEXTWRITER_TEXT:
2633 case XML_TEXTWRITER_PI:
2634 case XML_TEXTWRITER_PI_TEXT:
2635 break;
2636 case XML_TEXTWRITER_ATTRIBUTE:
2637 count = xmlTextWriterEndAttribute(writer);
2638 if (count < 0)
2639 return -1;
2640 sum += count;
2641 /* fallthrough */
2642 case XML_TEXTWRITER_NAME:
2643 /* Output namespace declarations */
2644 count = xmlTextWriterOutputNSDecl(writer);
2645 if (count < 0)
2646 return -1;
2647 sum += count;
2648 count = xmlOutputBufferWriteString(writer->out, ">");
2649 if (count < 0)
2650 return -1;
2651 sum += count;
2652 p->state = XML_TEXTWRITER_TEXT;
2653 break;
2654 case XML_TEXTWRITER_CDATA:
2655 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
2656 "xmlTextWriterStartCDATA : CDATA not allowed in this context!\n");
2657 return -1;
2658 default:
2659 return -1;
2664 p = (xmlTextWriterStackEntry *)
2665 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2666 if (p == 0) {
2667 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
2668 "xmlTextWriterStartCDATA : out of memory!\n");
2669 return -1;
2672 p->name = NULL;
2673 p->state = XML_TEXTWRITER_CDATA;
2675 xmlListPushFront(writer->nodes, p);
2677 count = xmlOutputBufferWriteString(writer->out, "<![CDATA[");
2678 if (count < 0)
2679 return -1;
2680 sum += count;
2682 return sum;
2686 * xmlTextWriterEndCDATA:
2687 * @writer: the xmlTextWriterPtr
2689 * End an xml CDATA section.
2691 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2694 xmlTextWriterEndCDATA(xmlTextWriterPtr writer)
2696 int count;
2697 int sum;
2698 xmlLinkPtr lk;
2699 xmlTextWriterStackEntry *p;
2701 if (writer == NULL)
2702 return -1;
2704 lk = xmlListFront(writer->nodes);
2705 if (lk == 0)
2706 return -1;
2708 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2709 if (p == 0)
2710 return -1;
2712 sum = 0;
2713 switch (p->state) {
2714 case XML_TEXTWRITER_CDATA:
2715 count = xmlOutputBufferWriteString(writer->out, "]]>");
2716 if (count < 0)
2717 return -1;
2718 sum += count;
2719 break;
2720 default:
2721 return -1;
2724 xmlListPopFront(writer->nodes);
2725 return sum;
2729 * xmlTextWriterWriteFormatCDATA:
2730 * @writer: the xmlTextWriterPtr
2731 * @format: format string (see printf)
2732 * @...: extra parameters for the format
2734 * Write a formatted xml CDATA.
2736 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2738 int XMLCDECL
2739 xmlTextWriterWriteFormatCDATA(xmlTextWriterPtr writer, const char *format,
2740 ...)
2742 int rc;
2743 va_list ap;
2745 va_start(ap, format);
2747 rc = xmlTextWriterWriteVFormatCDATA(writer, format, ap);
2749 va_end(ap);
2750 return rc;
2754 * xmlTextWriterWriteVFormatCDATA:
2755 * @writer: the xmlTextWriterPtr
2756 * @format: format string (see printf)
2757 * @argptr: pointer to the first member of the variable argument list.
2759 * Write a formatted xml CDATA.
2761 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2764 xmlTextWriterWriteVFormatCDATA(xmlTextWriterPtr writer, const char *format,
2765 va_list argptr)
2767 int rc;
2768 xmlChar *buf;
2770 if (writer == NULL)
2771 return -1;
2773 buf = xmlTextWriterVSprintf(format, argptr);
2774 if (buf == NULL)
2775 return -1;
2777 rc = xmlTextWriterWriteCDATA(writer, buf);
2779 xmlFree(buf);
2780 return rc;
2784 * xmlTextWriterWriteCDATA:
2785 * @writer: the xmlTextWriterPtr
2786 * @content: CDATA content
2788 * Write an xml CDATA.
2790 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2793 xmlTextWriterWriteCDATA(xmlTextWriterPtr writer, const xmlChar * content)
2795 int count;
2796 int sum;
2798 sum = 0;
2799 count = xmlTextWriterStartCDATA(writer);
2800 if (count == -1)
2801 return -1;
2802 sum += count;
2803 if (content != 0) {
2804 count = xmlTextWriterWriteString(writer, content);
2805 if (count == -1)
2806 return -1;
2807 sum += count;
2809 count = xmlTextWriterEndCDATA(writer);
2810 if (count == -1)
2811 return -1;
2812 sum += count;
2814 return sum;
2818 * xmlTextWriterStartDTD:
2819 * @writer: the xmlTextWriterPtr
2820 * @name: the name of the DTD
2821 * @pubid: the public identifier, which is an alternative to the system identifier
2822 * @sysid: the system identifier, which is the URI of the DTD
2824 * Start an xml DTD.
2826 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2829 xmlTextWriterStartDTD(xmlTextWriterPtr writer,
2830 const xmlChar * name,
2831 const xmlChar * pubid, const xmlChar * sysid)
2833 int count;
2834 int sum;
2835 xmlLinkPtr lk;
2836 xmlTextWriterStackEntry *p;
2838 if (writer == NULL || name == NULL || *name == '\0')
2839 return -1;
2841 sum = 0;
2842 lk = xmlListFront(writer->nodes);
2843 if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) {
2844 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
2845 "xmlTextWriterStartDTD : DTD allowed only in prolog!\n");
2846 return -1;
2849 p = (xmlTextWriterStackEntry *)
2850 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2851 if (p == 0) {
2852 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
2853 "xmlTextWriterStartDTD : out of memory!\n");
2854 return -1;
2857 p->name = xmlStrdup(name);
2858 if (p->name == 0) {
2859 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
2860 "xmlTextWriterStartDTD : out of memory!\n");
2861 xmlFree(p);
2862 return -1;
2864 p->state = XML_TEXTWRITER_DTD;
2866 xmlListPushFront(writer->nodes, p);
2868 count = xmlOutputBufferWriteString(writer->out, "<!DOCTYPE ");
2869 if (count < 0)
2870 return -1;
2871 sum += count;
2872 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
2873 if (count < 0)
2874 return -1;
2875 sum += count;
2877 if (pubid != 0) {
2878 if (sysid == 0) {
2879 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
2880 "xmlTextWriterStartDTD : system identifier needed!\n");
2881 return -1;
2884 if (writer->indent)
2885 count = xmlOutputBufferWrite(writer->out, 1, "\n");
2886 else
2887 count = xmlOutputBufferWrite(writer->out, 1, " ");
2888 if (count < 0)
2889 return -1;
2890 sum += count;
2892 count = xmlOutputBufferWriteString(writer->out, "PUBLIC ");
2893 if (count < 0)
2894 return -1;
2895 sum += count;
2897 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
2898 if (count < 0)
2899 return -1;
2900 sum += count;
2902 count =
2903 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
2904 if (count < 0)
2905 return -1;
2906 sum += count;
2908 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
2909 if (count < 0)
2910 return -1;
2911 sum += count;
2914 if (sysid != 0) {
2915 if (pubid == 0) {
2916 if (writer->indent)
2917 count = xmlOutputBufferWrite(writer->out, 1, "\n");
2918 else
2919 count = xmlOutputBufferWrite(writer->out, 1, " ");
2920 if (count < 0)
2921 return -1;
2922 sum += count;
2923 count = xmlOutputBufferWriteString(writer->out, "SYSTEM ");
2924 if (count < 0)
2925 return -1;
2926 sum += count;
2927 } else {
2928 if (writer->indent)
2929 count = xmlOutputBufferWriteString(writer->out, "\n ");
2930 else
2931 count = xmlOutputBufferWrite(writer->out, 1, " ");
2932 if (count < 0)
2933 return -1;
2934 sum += count;
2937 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
2938 if (count < 0)
2939 return -1;
2940 sum += count;
2942 count =
2943 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
2944 if (count < 0)
2945 return -1;
2946 sum += count;
2948 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
2949 if (count < 0)
2950 return -1;
2951 sum += count;
2954 return sum;
2958 * xmlTextWriterEndDTD:
2959 * @writer: the xmlTextWriterPtr
2961 * End an xml DTD.
2963 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2966 xmlTextWriterEndDTD(xmlTextWriterPtr writer)
2968 int loop;
2969 int count;
2970 int sum;
2971 xmlLinkPtr lk;
2972 xmlTextWriterStackEntry *p;
2974 if (writer == NULL)
2975 return -1;
2977 sum = 0;
2978 loop = 1;
2979 while (loop) {
2980 lk = xmlListFront(writer->nodes);
2981 if (lk == NULL)
2982 break;
2983 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2984 if (p == 0)
2985 break;
2986 switch (p->state) {
2987 case XML_TEXTWRITER_DTD_TEXT:
2988 count = xmlOutputBufferWriteString(writer->out, "]");
2989 if (count < 0)
2990 return -1;
2991 sum += count;
2992 /* fallthrough */
2993 case XML_TEXTWRITER_DTD:
2994 count = xmlOutputBufferWriteString(writer->out, ">");
2996 if (writer->indent) {
2997 if (count < 0)
2998 return -1;
2999 sum += count;
3000 count = xmlOutputBufferWriteString(writer->out, "\n");
3003 xmlListPopFront(writer->nodes);
3004 break;
3005 case XML_TEXTWRITER_DTD_ELEM:
3006 case XML_TEXTWRITER_DTD_ELEM_TEXT:
3007 count = xmlTextWriterEndDTDElement(writer);
3008 break;
3009 case XML_TEXTWRITER_DTD_ATTL:
3010 case XML_TEXTWRITER_DTD_ATTL_TEXT:
3011 count = xmlTextWriterEndDTDAttlist(writer);
3012 break;
3013 case XML_TEXTWRITER_DTD_ENTY:
3014 case XML_TEXTWRITER_DTD_PENT:
3015 case XML_TEXTWRITER_DTD_ENTY_TEXT:
3016 count = xmlTextWriterEndDTDEntity(writer);
3017 break;
3018 case XML_TEXTWRITER_COMMENT:
3019 count = xmlTextWriterEndComment(writer);
3020 break;
3021 default:
3022 loop = 0;
3023 continue;
3026 if (count < 0)
3027 return -1;
3028 sum += count;
3031 return sum;
3035 * xmlTextWriterWriteFormatDTD:
3036 * @writer: the xmlTextWriterPtr
3037 * @name: the name of the DTD
3038 * @pubid: the public identifier, which is an alternative to the system identifier
3039 * @sysid: the system identifier, which is the URI of the DTD
3040 * @format: format string (see printf)
3041 * @...: extra parameters for the format
3043 * Write a DTD with a formatted markup declarations part.
3045 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3047 int XMLCDECL
3048 xmlTextWriterWriteFormatDTD(xmlTextWriterPtr writer,
3049 const xmlChar * name,
3050 const xmlChar * pubid,
3051 const xmlChar * sysid, const char *format, ...)
3053 int rc;
3054 va_list ap;
3056 va_start(ap, format);
3058 rc = xmlTextWriterWriteVFormatDTD(writer, name, pubid, sysid, format,
3059 ap);
3061 va_end(ap);
3062 return rc;
3066 * xmlTextWriterWriteVFormatDTD:
3067 * @writer: the xmlTextWriterPtr
3068 * @name: the name of the DTD
3069 * @pubid: the public identifier, which is an alternative to the system identifier
3070 * @sysid: the system identifier, which is the URI of the DTD
3071 * @format: format string (see printf)
3072 * @argptr: pointer to the first member of the variable argument list.
3074 * Write a DTD with a formatted markup declarations part.
3076 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3079 xmlTextWriterWriteVFormatDTD(xmlTextWriterPtr writer,
3080 const xmlChar * name,
3081 const xmlChar * pubid,
3082 const xmlChar * sysid,
3083 const char *format, va_list argptr)
3085 int rc;
3086 xmlChar *buf;
3088 if (writer == NULL)
3089 return -1;
3091 buf = xmlTextWriterVSprintf(format, argptr);
3092 if (buf == NULL)
3093 return -1;
3095 rc = xmlTextWriterWriteDTD(writer, name, pubid, sysid, buf);
3097 xmlFree(buf);
3098 return rc;
3102 * xmlTextWriterWriteDTD:
3103 * @writer: the xmlTextWriterPtr
3104 * @name: the name of the DTD
3105 * @pubid: the public identifier, which is an alternative to the system identifier
3106 * @sysid: the system identifier, which is the URI of the DTD
3107 * @subset: string content of the DTD
3109 * Write a DTD.
3111 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3114 xmlTextWriterWriteDTD(xmlTextWriterPtr writer,
3115 const xmlChar * name,
3116 const xmlChar * pubid,
3117 const xmlChar * sysid, const xmlChar * subset)
3119 int count;
3120 int sum;
3122 sum = 0;
3123 count = xmlTextWriterStartDTD(writer, name, pubid, sysid);
3124 if (count == -1)
3125 return -1;
3126 sum += count;
3127 if (subset != 0) {
3128 count = xmlTextWriterWriteString(writer, subset);
3129 if (count == -1)
3130 return -1;
3131 sum += count;
3133 count = xmlTextWriterEndDTD(writer);
3134 if (count == -1)
3135 return -1;
3136 sum += count;
3138 return sum;
3142 * xmlTextWriterStartDTDElement:
3143 * @writer: the xmlTextWriterPtr
3144 * @name: the name of the DTD element
3146 * Start an xml DTD element.
3148 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3151 xmlTextWriterStartDTDElement(xmlTextWriterPtr writer, const xmlChar * name)
3153 int count;
3154 int sum;
3155 xmlLinkPtr lk;
3156 xmlTextWriterStackEntry *p;
3158 if (writer == NULL || name == NULL || *name == '\0')
3159 return -1;
3161 sum = 0;
3162 lk = xmlListFront(writer->nodes);
3163 if (lk == 0) {
3164 return -1;
3167 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3168 if (p != 0) {
3169 switch (p->state) {
3170 case XML_TEXTWRITER_DTD:
3171 count = xmlOutputBufferWriteString(writer->out, " [");
3172 if (count < 0)
3173 return -1;
3174 sum += count;
3175 if (writer->indent) {
3176 count = xmlOutputBufferWriteString(writer->out, "\n");
3177 if (count < 0)
3178 return -1;
3179 sum += count;
3181 p->state = XML_TEXTWRITER_DTD_TEXT;
3182 /* fallthrough */
3183 case XML_TEXTWRITER_DTD_TEXT:
3184 case XML_TEXTWRITER_NONE:
3185 break;
3186 default:
3187 return -1;
3191 p = (xmlTextWriterStackEntry *)
3192 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3193 if (p == 0) {
3194 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
3195 "xmlTextWriterStartDTDElement : out of memory!\n");
3196 return -1;
3199 p->name = xmlStrdup(name);
3200 if (p->name == 0) {
3201 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
3202 "xmlTextWriterStartDTDElement : out of memory!\n");
3203 xmlFree(p);
3204 return -1;
3206 p->state = XML_TEXTWRITER_DTD_ELEM;
3208 xmlListPushFront(writer->nodes, p);
3210 if (writer->indent) {
3211 count = xmlTextWriterWriteIndent(writer);
3212 if (count < 0)
3213 return -1;
3214 sum += count;
3217 count = xmlOutputBufferWriteString(writer->out, "<!ELEMENT ");
3218 if (count < 0)
3219 return -1;
3220 sum += count;
3221 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
3222 if (count < 0)
3223 return -1;
3224 sum += count;
3226 return sum;
3230 * xmlTextWriterEndDTDElement:
3231 * @writer: the xmlTextWriterPtr
3233 * End an xml DTD element.
3235 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3238 xmlTextWriterEndDTDElement(xmlTextWriterPtr writer)
3240 int count;
3241 int sum;
3242 xmlLinkPtr lk;
3243 xmlTextWriterStackEntry *p;
3245 if (writer == NULL)
3246 return -1;
3248 sum = 0;
3249 lk = xmlListFront(writer->nodes);
3250 if (lk == 0)
3251 return -1;
3253 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3254 if (p == 0)
3255 return -1;
3257 switch (p->state) {
3258 case XML_TEXTWRITER_DTD_ELEM:
3259 case XML_TEXTWRITER_DTD_ELEM_TEXT:
3260 count = xmlOutputBufferWriteString(writer->out, ">");
3261 if (count < 0)
3262 return -1;
3263 sum += count;
3264 break;
3265 default:
3266 return -1;
3269 if (writer->indent) {
3270 count = xmlOutputBufferWriteString(writer->out, "\n");
3271 if (count < 0)
3272 return -1;
3273 sum += count;
3276 xmlListPopFront(writer->nodes);
3277 return sum;
3281 * xmlTextWriterWriteFormatDTDElement:
3282 * @writer: the xmlTextWriterPtr
3283 * @name: the name of the DTD element
3284 * @format: format string (see printf)
3285 * @...: extra parameters for the format
3287 * Write a formatted DTD element.
3289 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3291 int XMLCDECL
3292 xmlTextWriterWriteFormatDTDElement(xmlTextWriterPtr writer,
3293 const xmlChar * name,
3294 const char *format, ...)
3296 int rc;
3297 va_list ap;
3299 va_start(ap, format);
3301 rc = xmlTextWriterWriteVFormatDTDElement(writer, name, format, ap);
3303 va_end(ap);
3304 return rc;
3308 * xmlTextWriterWriteVFormatDTDElement:
3309 * @writer: the xmlTextWriterPtr
3310 * @name: the name of the DTD element
3311 * @format: format string (see printf)
3312 * @argptr: pointer to the first member of the variable argument list.
3314 * Write a formatted DTD element.
3316 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3319 xmlTextWriterWriteVFormatDTDElement(xmlTextWriterPtr writer,
3320 const xmlChar * name,
3321 const char *format, va_list argptr)
3323 int rc;
3324 xmlChar *buf;
3326 if (writer == NULL)
3327 return -1;
3329 buf = xmlTextWriterVSprintf(format, argptr);
3330 if (buf == NULL)
3331 return -1;
3333 rc = xmlTextWriterWriteDTDElement(writer, name, buf);
3335 xmlFree(buf);
3336 return rc;
3340 * xmlTextWriterWriteDTDElement:
3341 * @writer: the xmlTextWriterPtr
3342 * @name: the name of the DTD element
3343 * @content: content of the element
3345 * Write a DTD element.
3347 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3350 xmlTextWriterWriteDTDElement(xmlTextWriterPtr writer,
3351 const xmlChar * name, const xmlChar * content)
3353 int count;
3354 int sum;
3356 if (content == NULL)
3357 return -1;
3359 sum = 0;
3360 count = xmlTextWriterStartDTDElement(writer, name);
3361 if (count == -1)
3362 return -1;
3363 sum += count;
3365 count = xmlTextWriterWriteString(writer, content);
3366 if (count == -1)
3367 return -1;
3368 sum += count;
3370 count = xmlTextWriterEndDTDElement(writer);
3371 if (count == -1)
3372 return -1;
3373 sum += count;
3375 return sum;
3379 * xmlTextWriterStartDTDAttlist:
3380 * @writer: the xmlTextWriterPtr
3381 * @name: the name of the DTD ATTLIST
3383 * Start an xml DTD ATTLIST.
3385 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3388 xmlTextWriterStartDTDAttlist(xmlTextWriterPtr writer, const xmlChar * name)
3390 int count;
3391 int sum;
3392 xmlLinkPtr lk;
3393 xmlTextWriterStackEntry *p;
3395 if (writer == NULL || name == NULL || *name == '\0')
3396 return -1;
3398 sum = 0;
3399 lk = xmlListFront(writer->nodes);
3400 if (lk == 0) {
3401 return -1;
3404 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3405 if (p != 0) {
3406 switch (p->state) {
3407 case XML_TEXTWRITER_DTD:
3408 count = xmlOutputBufferWriteString(writer->out, " [");
3409 if (count < 0)
3410 return -1;
3411 sum += count;
3412 if (writer->indent) {
3413 count = xmlOutputBufferWriteString(writer->out, "\n");
3414 if (count < 0)
3415 return -1;
3416 sum += count;
3418 p->state = XML_TEXTWRITER_DTD_TEXT;
3419 /* fallthrough */
3420 case XML_TEXTWRITER_DTD_TEXT:
3421 case XML_TEXTWRITER_NONE:
3422 break;
3423 default:
3424 return -1;
3428 p = (xmlTextWriterStackEntry *)
3429 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3430 if (p == 0) {
3431 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
3432 "xmlTextWriterStartDTDAttlist : out of memory!\n");
3433 return -1;
3436 p->name = xmlStrdup(name);
3437 if (p->name == 0) {
3438 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
3439 "xmlTextWriterStartDTDAttlist : out of memory!\n");
3440 xmlFree(p);
3441 return -1;
3443 p->state = XML_TEXTWRITER_DTD_ATTL;
3445 xmlListPushFront(writer->nodes, p);
3447 if (writer->indent) {
3448 count = xmlTextWriterWriteIndent(writer);
3449 if (count < 0)
3450 return -1;
3451 sum += count;
3454 count = xmlOutputBufferWriteString(writer->out, "<!ATTLIST ");
3455 if (count < 0)
3456 return -1;
3457 sum += count;
3458 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
3459 if (count < 0)
3460 return -1;
3461 sum += count;
3463 return sum;
3467 * xmlTextWriterEndDTDAttlist:
3468 * @writer: the xmlTextWriterPtr
3470 * End an xml DTD attribute list.
3472 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3475 xmlTextWriterEndDTDAttlist(xmlTextWriterPtr writer)
3477 int count;
3478 int sum;
3479 xmlLinkPtr lk;
3480 xmlTextWriterStackEntry *p;
3482 if (writer == NULL)
3483 return -1;
3485 sum = 0;
3486 lk = xmlListFront(writer->nodes);
3487 if (lk == 0)
3488 return -1;
3490 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3491 if (p == 0)
3492 return -1;
3494 switch (p->state) {
3495 case XML_TEXTWRITER_DTD_ATTL:
3496 case XML_TEXTWRITER_DTD_ATTL_TEXT:
3497 count = xmlOutputBufferWriteString(writer->out, ">");
3498 if (count < 0)
3499 return -1;
3500 sum += count;
3501 break;
3502 default:
3503 return -1;
3506 if (writer->indent) {
3507 count = xmlOutputBufferWriteString(writer->out, "\n");
3508 if (count < 0)
3509 return -1;
3510 sum += count;
3513 xmlListPopFront(writer->nodes);
3514 return sum;
3518 * xmlTextWriterWriteFormatDTDAttlist:
3519 * @writer: the xmlTextWriterPtr
3520 * @name: the name of the DTD ATTLIST
3521 * @format: format string (see printf)
3522 * @...: extra parameters for the format
3524 * Write a formatted DTD ATTLIST.
3526 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3528 int XMLCDECL
3529 xmlTextWriterWriteFormatDTDAttlist(xmlTextWriterPtr writer,
3530 const xmlChar * name,
3531 const char *format, ...)
3533 int rc;
3534 va_list ap;
3536 va_start(ap, format);
3538 rc = xmlTextWriterWriteVFormatDTDAttlist(writer, name, format, ap);
3540 va_end(ap);
3541 return rc;
3545 * xmlTextWriterWriteVFormatDTDAttlist:
3546 * @writer: the xmlTextWriterPtr
3547 * @name: the name of the DTD ATTLIST
3548 * @format: format string (see printf)
3549 * @argptr: pointer to the first member of the variable argument list.
3551 * Write a formatted DTD ATTLIST.
3553 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3556 xmlTextWriterWriteVFormatDTDAttlist(xmlTextWriterPtr writer,
3557 const xmlChar * name,
3558 const char *format, va_list argptr)
3560 int rc;
3561 xmlChar *buf;
3563 if (writer == NULL)
3564 return -1;
3566 buf = xmlTextWriterVSprintf(format, argptr);
3567 if (buf == NULL)
3568 return -1;
3570 rc = xmlTextWriterWriteDTDAttlist(writer, name, buf);
3572 xmlFree(buf);
3573 return rc;
3577 * xmlTextWriterWriteDTDAttlist:
3578 * @writer: the xmlTextWriterPtr
3579 * @name: the name of the DTD ATTLIST
3580 * @content: content of the ATTLIST
3582 * Write a DTD ATTLIST.
3584 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3587 xmlTextWriterWriteDTDAttlist(xmlTextWriterPtr writer,
3588 const xmlChar * name, const xmlChar * content)
3590 int count;
3591 int sum;
3593 if (content == NULL)
3594 return -1;
3596 sum = 0;
3597 count = xmlTextWriterStartDTDAttlist(writer, name);
3598 if (count == -1)
3599 return -1;
3600 sum += count;
3602 count = xmlTextWriterWriteString(writer, content);
3603 if (count == -1)
3604 return -1;
3605 sum += count;
3607 count = xmlTextWriterEndDTDAttlist(writer);
3608 if (count == -1)
3609 return -1;
3610 sum += count;
3612 return sum;
3616 * xmlTextWriterStartDTDEntity:
3617 * @writer: the xmlTextWriterPtr
3618 * @pe: TRUE if this is a parameter entity, FALSE if not
3619 * @name: the name of the DTD ATTLIST
3621 * Start an xml DTD ATTLIST.
3623 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3626 xmlTextWriterStartDTDEntity(xmlTextWriterPtr writer,
3627 int pe, const xmlChar * name)
3629 int count;
3630 int sum;
3631 xmlLinkPtr lk;
3632 xmlTextWriterStackEntry *p;
3634 if (writer == NULL || name == NULL || *name == '\0')
3635 return -1;
3637 sum = 0;
3638 lk = xmlListFront(writer->nodes);
3639 if (lk != 0) {
3641 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3642 if (p != 0) {
3643 switch (p->state) {
3644 case XML_TEXTWRITER_DTD:
3645 count = xmlOutputBufferWriteString(writer->out, " [");
3646 if (count < 0)
3647 return -1;
3648 sum += count;
3649 if (writer->indent) {
3650 count =
3651 xmlOutputBufferWriteString(writer->out, "\n");
3652 if (count < 0)
3653 return -1;
3654 sum += count;
3656 p->state = XML_TEXTWRITER_DTD_TEXT;
3657 /* fallthrough */
3658 case XML_TEXTWRITER_DTD_TEXT:
3659 case XML_TEXTWRITER_NONE:
3660 break;
3661 default:
3662 return -1;
3667 p = (xmlTextWriterStackEntry *)
3668 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3669 if (p == 0) {
3670 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
3671 "xmlTextWriterStartDTDElement : out of memory!\n");
3672 return -1;
3675 p->name = xmlStrdup(name);
3676 if (p->name == 0) {
3677 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
3678 "xmlTextWriterStartDTDElement : out of memory!\n");
3679 xmlFree(p);
3680 return -1;
3683 if (pe != 0)
3684 p->state = XML_TEXTWRITER_DTD_PENT;
3685 else
3686 p->state = XML_TEXTWRITER_DTD_ENTY;
3688 xmlListPushFront(writer->nodes, p);
3690 if (writer->indent) {
3691 count = xmlTextWriterWriteIndent(writer);
3692 if (count < 0)
3693 return -1;
3694 sum += count;
3697 count = xmlOutputBufferWriteString(writer->out, "<!ENTITY ");
3698 if (count < 0)
3699 return -1;
3700 sum += count;
3702 if (pe != 0) {
3703 count = xmlOutputBufferWriteString(writer->out, "% ");
3704 if (count < 0)
3705 return -1;
3706 sum += count;
3709 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
3710 if (count < 0)
3711 return -1;
3712 sum += count;
3714 return sum;
3718 * xmlTextWriterEndDTDEntity:
3719 * @writer: the xmlTextWriterPtr
3721 * End an xml DTD entity.
3723 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3726 xmlTextWriterEndDTDEntity(xmlTextWriterPtr writer)
3728 int count;
3729 int sum;
3730 xmlLinkPtr lk;
3731 xmlTextWriterStackEntry *p;
3733 if (writer == NULL)
3734 return -1;
3736 sum = 0;
3737 lk = xmlListFront(writer->nodes);
3738 if (lk == 0)
3739 return -1;
3741 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3742 if (p == 0)
3743 return -1;
3745 switch (p->state) {
3746 case XML_TEXTWRITER_DTD_ENTY_TEXT:
3747 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3748 if (count < 0)
3749 return -1;
3750 sum += count;
3751 case XML_TEXTWRITER_DTD_ENTY:
3752 case XML_TEXTWRITER_DTD_PENT:
3753 count = xmlOutputBufferWriteString(writer->out, ">");
3754 if (count < 0)
3755 return -1;
3756 sum += count;
3757 break;
3758 default:
3759 return -1;
3762 if (writer->indent) {
3763 count = xmlOutputBufferWriteString(writer->out, "\n");
3764 if (count < 0)
3765 return -1;
3766 sum += count;
3769 xmlListPopFront(writer->nodes);
3770 return sum;
3774 * xmlTextWriterWriteFormatDTDInternalEntity:
3775 * @writer: the xmlTextWriterPtr
3776 * @pe: TRUE if this is a parameter entity, FALSE if not
3777 * @name: the name of the DTD entity
3778 * @format: format string (see printf)
3779 * @...: extra parameters for the format
3781 * Write a formatted DTD internal entity.
3783 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3785 int XMLCDECL
3786 xmlTextWriterWriteFormatDTDInternalEntity(xmlTextWriterPtr writer,
3787 int pe,
3788 const xmlChar * name,
3789 const char *format, ...)
3791 int rc;
3792 va_list ap;
3794 va_start(ap, format);
3796 rc = xmlTextWriterWriteVFormatDTDInternalEntity(writer, pe, name,
3797 format, ap);
3799 va_end(ap);
3800 return rc;
3804 * xmlTextWriterWriteVFormatDTDInternalEntity:
3805 * @writer: the xmlTextWriterPtr
3806 * @pe: TRUE if this is a parameter entity, FALSE if not
3807 * @name: the name of the DTD entity
3808 * @format: format string (see printf)
3809 * @argptr: pointer to the first member of the variable argument list.
3811 * Write a formatted DTD internal entity.
3813 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3816 xmlTextWriterWriteVFormatDTDInternalEntity(xmlTextWriterPtr writer,
3817 int pe,
3818 const xmlChar * name,
3819 const char *format,
3820 va_list argptr)
3822 int rc;
3823 xmlChar *buf;
3825 if (writer == NULL)
3826 return -1;
3828 buf = xmlTextWriterVSprintf(format, argptr);
3829 if (buf == NULL)
3830 return -1;
3832 rc = xmlTextWriterWriteDTDInternalEntity(writer, pe, name, buf);
3834 xmlFree(buf);
3835 return rc;
3839 * xmlTextWriterWriteDTDEntity:
3840 * @writer: the xmlTextWriterPtr
3841 * @pe: TRUE if this is a parameter entity, FALSE if not
3842 * @name: the name of the DTD entity
3843 * @pubid: the public identifier, which is an alternative to the system identifier
3844 * @sysid: the system identifier, which is the URI of the DTD
3845 * @ndataid: the xml notation name.
3846 * @content: content of the entity
3848 * Write a DTD entity.
3850 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3853 xmlTextWriterWriteDTDEntity(xmlTextWriterPtr writer,
3854 int pe,
3855 const xmlChar * name,
3856 const xmlChar * pubid,
3857 const xmlChar * sysid,
3858 const xmlChar * ndataid,
3859 const xmlChar * content)
3861 if ((content == NULL) && (pubid == NULL) && (sysid == NULL))
3862 return -1;
3863 if ((pe != 0) && (ndataid != NULL))
3864 return -1;
3866 if ((pubid == NULL) && (sysid == NULL))
3867 return xmlTextWriterWriteDTDInternalEntity(writer, pe, name,
3868 content);
3870 return xmlTextWriterWriteDTDExternalEntity(writer, pe, name, pubid,
3871 sysid, ndataid);
3875 * xmlTextWriterWriteDTDInternalEntity:
3876 * @writer: the xmlTextWriterPtr
3877 * @pe: TRUE if this is a parameter entity, FALSE if not
3878 * @name: the name of the DTD entity
3879 * @content: content of the entity
3881 * Write a DTD internal entity.
3883 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3886 xmlTextWriterWriteDTDInternalEntity(xmlTextWriterPtr writer,
3887 int pe,
3888 const xmlChar * name,
3889 const xmlChar * content)
3891 int count;
3892 int sum;
3894 if ((name == NULL) || (*name == '\0') || (content == NULL))
3895 return -1;
3897 sum = 0;
3898 count = xmlTextWriterStartDTDEntity(writer, pe, name);
3899 if (count == -1)
3900 return -1;
3901 sum += count;
3903 count = xmlTextWriterWriteString(writer, content);
3904 if (count == -1)
3905 return -1;
3906 sum += count;
3908 count = xmlTextWriterEndDTDEntity(writer);
3909 if (count == -1)
3910 return -1;
3911 sum += count;
3913 return sum;
3917 * xmlTextWriterWriteDTDExternalEntity:
3918 * @writer: the xmlTextWriterPtr
3919 * @pe: TRUE if this is a parameter entity, FALSE if not
3920 * @name: the name of the DTD entity
3921 * @pubid: the public identifier, which is an alternative to the system identifier
3922 * @sysid: the system identifier, which is the URI of the DTD
3923 * @ndataid: the xml notation name.
3925 * Write a DTD external entity. The entity must have been started with xmlTextWriterStartDTDEntity
3927 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3930 xmlTextWriterWriteDTDExternalEntity(xmlTextWriterPtr writer,
3931 int pe,
3932 const xmlChar * name,
3933 const xmlChar * pubid,
3934 const xmlChar * sysid,
3935 const xmlChar * ndataid)
3937 int count;
3938 int sum;
3940 if (((pubid == NULL) && (sysid == NULL)))
3941 return -1;
3942 if ((pe != 0) && (ndataid != NULL))
3943 return -1;
3945 sum = 0;
3946 count = xmlTextWriterStartDTDEntity(writer, pe, name);
3947 if (count == -1)
3948 return -1;
3949 sum += count;
3951 count =
3952 xmlTextWriterWriteDTDExternalEntityContents(writer, pubid, sysid,
3953 ndataid);
3954 if (count < 0)
3955 return -1;
3956 sum += count;
3958 count = xmlTextWriterEndDTDEntity(writer);
3959 if (count == -1)
3960 return -1;
3961 sum += count;
3963 return sum;
3967 * xmlTextWriterWriteDTDExternalEntityContents:
3968 * @writer: the xmlTextWriterPtr
3969 * @pubid: the public identifier, which is an alternative to the system identifier
3970 * @sysid: the system identifier, which is the URI of the DTD
3971 * @ndataid: the xml notation name.
3973 * Write the contents of a DTD external entity.
3975 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3978 xmlTextWriterWriteDTDExternalEntityContents(xmlTextWriterPtr writer,
3979 const xmlChar * pubid,
3980 const xmlChar * sysid,
3981 const xmlChar * ndataid)
3983 int count;
3984 int sum;
3985 xmlLinkPtr lk;
3986 xmlTextWriterStackEntry *p;
3988 if (writer == NULL) {
3989 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
3990 "xmlTextWriterWriteDTDExternalEntityContents: xmlTextWriterPtr invalid!\n");
3991 return -1;
3994 sum = 0;
3995 lk = xmlListFront(writer->nodes);
3996 if (lk == 0) {
3997 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
3998 "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n");
3999 return -1;
4002 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
4003 if (p == 0)
4004 return -1;
4006 switch (p->state) {
4007 case XML_TEXTWRITER_DTD_ENTY:
4008 break;
4009 case XML_TEXTWRITER_DTD_PENT:
4010 if (ndataid != NULL) {
4011 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
4012 "xmlTextWriterWriteDTDExternalEntityContents: notation not allowed with parameter entities!\n");
4013 return -1;
4015 break;
4016 default:
4017 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
4018 "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n");
4019 return -1;
4022 if (pubid != 0) {
4023 if (sysid == 0) {
4024 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
4025 "xmlTextWriterWriteDTDExternalEntityContents: system identifier needed!\n");
4026 return -1;
4029 count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
4030 if (count < 0)
4031 return -1;
4032 sum += count;
4034 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4035 if (count < 0)
4036 return -1;
4037 sum += count;
4039 count =
4040 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
4041 if (count < 0)
4042 return -1;
4043 sum += count;
4045 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4046 if (count < 0)
4047 return -1;
4048 sum += count;
4051 if (sysid != 0) {
4052 if (pubid == 0) {
4053 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
4054 if (count < 0)
4055 return -1;
4056 sum += count;
4059 count = xmlOutputBufferWriteString(writer->out, " ");
4060 if (count < 0)
4061 return -1;
4062 sum += count;
4064 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4065 if (count < 0)
4066 return -1;
4067 sum += count;
4069 count =
4070 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
4071 if (count < 0)
4072 return -1;
4073 sum += count;
4075 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4076 if (count < 0)
4077 return -1;
4078 sum += count;
4081 if (ndataid != NULL) {
4082 count = xmlOutputBufferWriteString(writer->out, " NDATA ");
4083 if (count < 0)
4084 return -1;
4085 sum += count;
4087 count =
4088 xmlOutputBufferWriteString(writer->out,
4089 (const char *) ndataid);
4090 if (count < 0)
4091 return -1;
4092 sum += count;
4095 return sum;
4099 * xmlTextWriterWriteDTDNotation:
4100 * @writer: the xmlTextWriterPtr
4101 * @name: the name of the xml notation
4102 * @pubid: the public identifier, which is an alternative to the system identifier
4103 * @sysid: the system identifier, which is the URI of the DTD
4105 * Write a DTD entity.
4107 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
4110 xmlTextWriterWriteDTDNotation(xmlTextWriterPtr writer,
4111 const xmlChar * name,
4112 const xmlChar * pubid, const xmlChar * sysid)
4114 int count;
4115 int sum;
4116 xmlLinkPtr lk;
4117 xmlTextWriterStackEntry *p;
4119 if (writer == NULL || name == NULL || *name == '\0')
4120 return -1;
4122 sum = 0;
4123 lk = xmlListFront(writer->nodes);
4124 if (lk == 0) {
4125 return -1;
4128 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
4129 if (p != 0) {
4130 switch (p->state) {
4131 case XML_TEXTWRITER_DTD:
4132 count = xmlOutputBufferWriteString(writer->out, " [");
4133 if (count < 0)
4134 return -1;
4135 sum += count;
4136 if (writer->indent) {
4137 count = xmlOutputBufferWriteString(writer->out, "\n");
4138 if (count < 0)
4139 return -1;
4140 sum += count;
4142 p->state = XML_TEXTWRITER_DTD_TEXT;
4143 /* fallthrough */
4144 case XML_TEXTWRITER_DTD_TEXT:
4145 break;
4146 default:
4147 return -1;
4151 if (writer->indent) {
4152 count = xmlTextWriterWriteIndent(writer);
4153 if (count < 0)
4154 return -1;
4155 sum += count;
4158 count = xmlOutputBufferWriteString(writer->out, "<!NOTATION ");
4159 if (count < 0)
4160 return -1;
4161 sum += count;
4162 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
4163 if (count < 0)
4164 return -1;
4165 sum += count;
4167 if (pubid != 0) {
4168 count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
4169 if (count < 0)
4170 return -1;
4171 sum += count;
4172 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4173 if (count < 0)
4174 return -1;
4175 sum += count;
4176 count =
4177 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
4178 if (count < 0)
4179 return -1;
4180 sum += count;
4181 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4182 if (count < 0)
4183 return -1;
4184 sum += count;
4187 if (sysid != 0) {
4188 if (pubid == 0) {
4189 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
4190 if (count < 0)
4191 return -1;
4192 sum += count;
4194 count = xmlOutputBufferWriteString(writer->out, " ");
4195 if (count < 0)
4196 return -1;
4197 sum += count;
4198 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4199 if (count < 0)
4200 return -1;
4201 sum += count;
4202 count =
4203 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
4204 if (count < 0)
4205 return -1;
4206 sum += count;
4207 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4208 if (count < 0)
4209 return -1;
4210 sum += count;
4213 count = xmlOutputBufferWriteString(writer->out, ">");
4214 if (count < 0)
4215 return -1;
4216 sum += count;
4218 return sum;
4222 * xmlTextWriterFlush:
4223 * @writer: the xmlTextWriterPtr
4225 * Flush the output buffer.
4227 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
4230 xmlTextWriterFlush(xmlTextWriterPtr writer)
4232 int count;
4234 if (writer == NULL)
4235 return -1;
4237 if (writer->out == NULL)
4238 count = 0;
4239 else
4240 count = xmlOutputBufferFlush(writer->out);
4242 return count;
4246 * misc
4250 * xmlFreeTextWriterStackEntry:
4251 * @lk: the xmlLinkPtr
4253 * Free callback for the xmlList.
4255 static void
4256 xmlFreeTextWriterStackEntry(xmlLinkPtr lk)
4258 xmlTextWriterStackEntry *p;
4260 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
4261 if (p == 0)
4262 return;
4264 if (p->name != 0)
4265 xmlFree(p->name);
4266 xmlFree(p);
4270 * xmlCmpTextWriterStackEntry:
4271 * @data0: the first data
4272 * @data1: the second data
4274 * Compare callback for the xmlList.
4276 * Returns -1, 0, 1
4278 static int
4279 xmlCmpTextWriterStackEntry(const void *data0, const void *data1)
4281 xmlTextWriterStackEntry *p0;
4282 xmlTextWriterStackEntry *p1;
4284 if (data0 == data1)
4285 return 0;
4287 if (data0 == 0)
4288 return -1;
4290 if (data1 == 0)
4291 return 1;
4293 p0 = (xmlTextWriterStackEntry *) data0;
4294 p1 = (xmlTextWriterStackEntry *) data1;
4296 return xmlStrcmp(p0->name, p1->name);
4300 * misc
4304 * xmlTextWriterOutputNSDecl:
4305 * @writer: the xmlTextWriterPtr
4307 * Output the current namespace declarations.
4309 static int
4310 xmlTextWriterOutputNSDecl(xmlTextWriterPtr writer)
4312 xmlLinkPtr lk;
4313 xmlTextWriterNsStackEntry *np;
4314 int count;
4315 int sum;
4317 sum = 0;
4318 while (!xmlListEmpty(writer->nsstack)) {
4319 xmlChar *namespaceURI = NULL;
4320 xmlChar *prefix = NULL;
4322 lk = xmlListFront(writer->nsstack);
4323 np = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
4325 if (np != 0) {
4326 namespaceURI = xmlStrdup(np->uri);
4327 prefix = xmlStrdup(np->prefix);
4330 xmlListPopFront(writer->nsstack);
4332 if (np != 0) {
4333 count = xmlTextWriterWriteAttribute(writer, prefix, namespaceURI);
4334 xmlFree(namespaceURI);
4335 xmlFree(prefix);
4337 if (count < 0) {
4338 xmlListDelete(writer->nsstack);
4339 writer->nsstack = NULL;
4340 return -1;
4342 sum += count;
4345 return sum;
4349 * xmlFreeTextWriterNsStackEntry:
4350 * @lk: the xmlLinkPtr
4352 * Free callback for the xmlList.
4354 static void
4355 xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk)
4357 xmlTextWriterNsStackEntry *p;
4359 p = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
4360 if (p == 0)
4361 return;
4363 if (p->prefix != 0)
4364 xmlFree(p->prefix);
4365 if (p->uri != 0)
4366 xmlFree(p->uri);
4368 xmlFree(p);
4372 * xmlCmpTextWriterNsStackEntry:
4373 * @data0: the first data
4374 * @data1: the second data
4376 * Compare callback for the xmlList.
4378 * Returns -1, 0, 1
4380 static int
4381 xmlCmpTextWriterNsStackEntry(const void *data0, const void *data1)
4383 xmlTextWriterNsStackEntry *p0;
4384 xmlTextWriterNsStackEntry *p1;
4385 int rc;
4387 if (data0 == data1)
4388 return 0;
4390 if (data0 == 0)
4391 return -1;
4393 if (data1 == 0)
4394 return 1;
4396 p0 = (xmlTextWriterNsStackEntry *) data0;
4397 p1 = (xmlTextWriterNsStackEntry *) data1;
4399 rc = xmlStrcmp(p0->prefix, p1->prefix);
4401 if ((rc != 0) || (p0->elem != p1->elem))
4402 rc = -1;
4404 return rc;
4408 * xmlTextWriterWriteDocCallback:
4409 * @context: the xmlBufferPtr
4410 * @str: the data to write
4411 * @len: the length of the data
4413 * Write callback for the xmlOutputBuffer with target xmlBuffer
4415 * Returns -1, 0, 1
4417 static int
4418 xmlTextWriterWriteDocCallback(void *context, const xmlChar * str, int len)
4420 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context;
4421 int rc;
4423 if ((rc = xmlParseChunk(ctxt, (const char *) str, len, 0)) != 0) {
4424 xmlWriterErrMsgInt(NULL, XML_ERR_INTERNAL_ERROR,
4425 "xmlTextWriterWriteDocCallback : XML error %d !\n",
4426 rc);
4427 return -1;
4430 return len;
4434 * xmlTextWriterCloseDocCallback:
4435 * @context: the xmlBufferPtr
4437 * Close callback for the xmlOutputBuffer with target xmlBuffer
4439 * Returns -1, 0, 1
4441 static int
4442 xmlTextWriterCloseDocCallback(void *context)
4444 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context;
4445 int rc;
4447 if ((rc = xmlParseChunk(ctxt, NULL, 0, 1)) != 0) {
4448 xmlWriterErrMsgInt(NULL, XML_ERR_INTERNAL_ERROR,
4449 "xmlTextWriterWriteDocCallback : XML error %d !\n",
4450 rc);
4451 return -1;
4454 return 0;
4458 * xmlTextWriterVSprintf:
4459 * @format: see printf
4460 * @argptr: pointer to the first member of the variable argument list.
4462 * Utility function for formatted output
4464 * Returns a new xmlChar buffer with the data or NULL on error. This buffer must be freed.
4466 static xmlChar *
4467 xmlTextWriterVSprintf(const char *format, va_list argptr)
4469 int size;
4470 int count;
4471 xmlChar *buf;
4472 va_list locarg;
4474 size = BUFSIZ;
4475 buf = (xmlChar *) xmlMalloc(size);
4476 if (buf == NULL) {
4477 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
4478 "xmlTextWriterVSprintf : out of memory!\n");
4479 return NULL;
4482 VA_COPY(locarg, argptr);
4483 while (((count = vsnprintf((char *) buf, size, format, locarg)) < 0)
4484 || (count == size - 1) || (count == size) || (count > size)) {
4485 va_end(locarg);
4486 xmlFree(buf);
4487 size += BUFSIZ;
4488 buf = (xmlChar *) xmlMalloc(size);
4489 if (buf == NULL) {
4490 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
4491 "xmlTextWriterVSprintf : out of memory!\n");
4492 return NULL;
4494 VA_COPY(locarg, argptr);
4496 va_end(locarg);
4498 return buf;
4502 * xmlTextWriterStartDocumentCallback:
4503 * @ctx: the user data (XML parser context)
4505 * called at the start of document processing.
4507 static void
4508 xmlTextWriterStartDocumentCallback(void *ctx)
4510 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
4511 xmlDocPtr doc;
4513 if (ctxt->html) {
4514 #ifdef LIBXML_HTML_ENABLED
4515 if (ctxt->myDoc == NULL)
4516 ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
4517 if (ctxt->myDoc == NULL) {
4518 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
4519 ctxt->sax->error(ctxt->userData,
4520 "SAX.startDocument(): out of memory\n");
4521 ctxt->errNo = XML_ERR_NO_MEMORY;
4522 ctxt->instate = XML_PARSER_EOF;
4523 ctxt->disableSAX = 1;
4524 return;
4526 #else
4527 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
4528 "libxml2 built without HTML support\n");
4529 ctxt->errNo = XML_ERR_INTERNAL_ERROR;
4530 ctxt->instate = XML_PARSER_EOF;
4531 ctxt->disableSAX = 1;
4532 return;
4533 #endif
4534 } else {
4535 doc = ctxt->myDoc;
4536 if (doc == NULL)
4537 doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
4538 if (doc != NULL) {
4539 if (doc->children == NULL) {
4540 if (ctxt->encoding != NULL)
4541 doc->encoding = xmlStrdup(ctxt->encoding);
4542 else
4543 doc->encoding = NULL;
4544 doc->standalone = ctxt->standalone;
4546 } else {
4547 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
4548 ctxt->sax->error(ctxt->userData,
4549 "SAX.startDocument(): out of memory\n");
4550 ctxt->errNo = XML_ERR_NO_MEMORY;
4551 ctxt->instate = XML_PARSER_EOF;
4552 ctxt->disableSAX = 1;
4553 return;
4556 if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) &&
4557 (ctxt->input != NULL) && (ctxt->input->filename != NULL)) {
4558 ctxt->myDoc->URL =
4559 xmlCanonicPath((const xmlChar *) ctxt->input->filename);
4560 if (ctxt->myDoc->URL == NULL)
4561 ctxt->myDoc->URL =
4562 xmlStrdup((const xmlChar *) ctxt->input->filename);
4567 * xmlTextWriterSetIndent:
4568 * @writer: the xmlTextWriterPtr
4569 * @indent: do indentation?
4571 * Set indentation output. indent = 0 do not indentation. indent > 0 do indentation.
4573 * Returns -1 on error or 0 otherwise.
4576 xmlTextWriterSetIndent(xmlTextWriterPtr writer, int indent)
4578 if ((writer == NULL) || (indent < 0))
4579 return -1;
4581 writer->indent = indent;
4582 writer->doindent = 1;
4584 return 0;
4588 * xmlTextWriterSetIndentString:
4589 * @writer: the xmlTextWriterPtr
4590 * @str: the xmlChar string
4592 * Set string indentation.
4594 * Returns -1 on error or 0 otherwise.
4597 xmlTextWriterSetIndentString(xmlTextWriterPtr writer, const xmlChar * str)
4599 if ((writer == NULL) || (!str))
4600 return -1;
4602 if (writer->ichar != NULL)
4603 xmlFree(writer->ichar);
4604 writer->ichar = xmlStrdup(str);
4606 if (!writer->ichar)
4607 return -1;
4608 else
4609 return 0;
4613 * xmlTextWriterSetQuoteChar:
4614 * @writer: the xmlTextWriterPtr
4615 * @quotechar: the quote character
4617 * Set the character used for quoting attributes.
4619 * Returns -1 on error or 0 otherwise.
4622 xmlTextWriterSetQuoteChar(xmlTextWriterPtr writer, xmlChar quotechar)
4624 if ((writer == NULL) || ((quotechar != '\'') && (quotechar != '"')))
4625 return -1;
4627 writer->qchar = quotechar;
4629 return 0;
4633 * xmlTextWriterWriteIndent:
4634 * @writer: the xmlTextWriterPtr
4636 * Write indent string.
4638 * Returns -1 on error or the number of strings written.
4640 static int
4641 xmlTextWriterWriteIndent(xmlTextWriterPtr writer)
4643 int lksize;
4644 int i;
4645 int ret;
4647 lksize = xmlListSize(writer->nodes);
4648 if (lksize < 1)
4649 return (-1); /* list is empty */
4650 for (i = 0; i < (lksize - 1); i++) {
4651 ret = xmlOutputBufferWriteString(writer->out,
4652 (const char *) writer->ichar);
4653 if (ret == -1)
4654 return (-1);
4657 return (lksize - 1);
4661 * xmlTextWriterHandleStateDependencies:
4662 * @writer: the xmlTextWriterPtr
4663 * @p: the xmlTextWriterStackEntry
4665 * Write state dependent strings.
4667 * Returns -1 on error or the number of characters written.
4669 static int
4670 xmlTextWriterHandleStateDependencies(xmlTextWriterPtr writer,
4671 xmlTextWriterStackEntry * p)
4673 int count;
4674 int sum;
4675 char extra[3];
4677 if (writer == NULL)
4678 return -1;
4680 if (p == NULL)
4681 return 0;
4683 sum = 0;
4684 extra[0] = extra[1] = extra[2] = '\0';
4685 if (p != 0) {
4686 sum = 0;
4687 switch (p->state) {
4688 case XML_TEXTWRITER_NAME:
4689 /* Output namespace declarations */
4690 count = xmlTextWriterOutputNSDecl(writer);
4691 if (count < 0)
4692 return -1;
4693 sum += count;
4694 extra[0] = '>';
4695 p->state = XML_TEXTWRITER_TEXT;
4696 break;
4697 case XML_TEXTWRITER_PI:
4698 extra[0] = ' ';
4699 p->state = XML_TEXTWRITER_PI_TEXT;
4700 break;
4701 case XML_TEXTWRITER_DTD:
4702 extra[0] = ' ';
4703 extra[1] = '[';
4704 p->state = XML_TEXTWRITER_DTD_TEXT;
4705 break;
4706 case XML_TEXTWRITER_DTD_ELEM:
4707 extra[0] = ' ';
4708 p->state = XML_TEXTWRITER_DTD_ELEM_TEXT;
4709 break;
4710 case XML_TEXTWRITER_DTD_ATTL:
4711 extra[0] = ' ';
4712 p->state = XML_TEXTWRITER_DTD_ATTL_TEXT;
4713 break;
4714 case XML_TEXTWRITER_DTD_ENTY:
4715 case XML_TEXTWRITER_DTD_PENT:
4716 extra[0] = ' ';
4717 extra[1] = writer->qchar;
4718 p->state = XML_TEXTWRITER_DTD_ENTY_TEXT;
4719 break;
4720 default:
4721 break;
4725 if (*extra != '\0') {
4726 count = xmlOutputBufferWriteString(writer->out, extra);
4727 if (count < 0)
4728 return -1;
4729 sum += count;
4732 return sum;
4735 #define bottom_xmlwriter
4736 #include "elfgcchack.h"
4737 #endif