blob: 0e2a979ea29a4711b7b691f6d9ae9c7e484e9855 [file] [log] [blame]
Daniel Veillard1d211e22003-10-20 22:32:39 +00001/*
2 * xmlwriter.c: XML text writer implementation
3 *
4 * For license and disclaimer see the license and disclaimer of
5 * libxml2.
6 *
7 * alfred@mickautsch.de
8 */
9
10#include <string.h>
11#include <stdarg.h>
12
13#include "libxml.h"
14#include <libxml/xmlmemory.h>
15#include <libxml/parser.h>
16
17#ifdef LIBXML_WRITER_ENABLED
18
19#include <libxml/xmlwriter.h>
20
21#define B64LINELEN 72
22#define B64CRLF "\r\n"
23
24/*
25 * Types are kept private
26 */
27typedef enum {
28 XML_TEXTWRITER_NONE = 0,
29 XML_TEXTWRITER_NAME,
30 XML_TEXTWRITER_ATTRIBUTE,
31 XML_TEXTWRITER_TEXT,
32 XML_TEXTWRITER_PI,
33 XML_TEXTWRITER_PI_TEXT,
34 XML_TEXTWRITER_CDATA,
35 XML_TEXTWRITER_DTD,
36 XML_TEXTWRITER_DTD_TEXT,
37 XML_TEXTWRITER_DTD_ELEM,
38 XML_TEXTWRITER_DTD_ATTL,
39 XML_TEXTWRITER_DTD_ENTY
40} xmlTextWriterState;
41
42typedef struct _xmlTextWriterStackEntry xmlTextWriterStackEntry;
43
44struct _xmlTextWriterStackEntry {
45 xmlChar *name;
46 xmlTextWriterState state;
47};
48
49typedef struct _xmlTextWriterNsStackEntry xmlTextWriterNsStackEntry;
50struct _xmlTextWriterNsStackEntry {
51 xmlChar *prefix;
52 xmlChar *uri;
53 xmlLinkPtr elem;
54};
55
56struct _xmlTextWriter {
57 xmlOutputBufferPtr out; /* output buffer */
58 xmlListPtr nodes; /* element name stack */
59 xmlListPtr nsstack; /* name spaces stack */
60 int level;
61 char indent; /* indent amount */
62 char ichar; /* indent character */
63 char qchar; /* character used for quoting attribute values */
64};
65
66static void xmlFreeTextWriterStackEntry(xmlLinkPtr lk);
67static int xmlCmpTextWriterStackEntry(const void *data0,
68 const void *data1);
69static void xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk);
70static int xmlCmpTextWriterNsStackEntry(const void *data0,
71 const void *data1);
72static int xmlTextWriterWriteMemCallback(void *context,
73 const xmlChar * str, int len);
74static int xmlTextWriterCloseMemCallback(void *context);
75static xmlChar *xmlTextWriterVSprintf(const char *format, va_list argptr);
76static int xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len,
77 const unsigned char *data);
78
79/**
80 * xmlNewTextWriter:
81 * @out: an xmlOutputBufferPtr
82 *
83 * Create a new xmlNewTextWriter structure using an xmlOutputBufferPtr
84 *
85 * Returns the new xmlTextWriterPtr or NULL in case of error
86 */
87xmlTextWriterPtr
88xmlNewTextWriter(xmlOutputBufferPtr out)
89{
90 xmlTextWriterPtr ret;
91
92 ret = (xmlTextWriterPtr) xmlMalloc(sizeof(xmlTextWriter));
93 if (ret == NULL) {
94 xmlGenericError(xmlGenericErrorContext,
95 "xmlNewTextWriter : out of memory!\n");
96 return NULL;
97 }
98 memset(ret, 0, (size_t) sizeof(xmlTextWriter));
99
100 ret->nodes = xmlListCreate((xmlListDeallocator)
101 xmlFreeTextWriterStackEntry,
102 (xmlListDataCompare)
103 xmlCmpTextWriterStackEntry);
104 if (ret->nodes == NULL) {
105 xmlGenericError(xmlGenericErrorContext,
106 "xmlNewTextWriter : out of memory!\n");
107 xmlFree(ret);
108 return NULL;
109 }
110
111 ret->nsstack = xmlListCreate((xmlListDeallocator)
112 xmlFreeTextWriterNsStackEntry,
113 (xmlListDataCompare)
114 xmlCmpTextWriterNsStackEntry);
115 if (ret->nsstack == NULL) {
116 xmlGenericError(xmlGenericErrorContext,
117 "xmlNewTextWriter : out of memory!\n");
118 xmlFree(ret->nodes);
119 xmlFree(ret);
120 return NULL;
121 }
122
123 ret->out = out;
124 ret->ichar = ' ';
125 ret->qchar = '"';
126
127 return ret;
128}
129
130/**
131 * xmlNewTextWriterFilename:
132 * @uri: the URI of the resource for the output
133 * @compression: compress the output?
134 *
135 * Create a new xmlNewTextWriter structure with @uri as output
136 *
137 * Returns the new xmlTextWriterPtr or NULL in case of error
138 */
139xmlTextWriterPtr
140xmlNewTextWriterFilename(const char *uri, int compression)
141{
142 xmlTextWriterPtr ret;
143 xmlOutputBufferPtr out;
144
145 out = xmlOutputBufferCreateFilename(uri, NULL, compression);
146 if (out == NULL) {
147 xmlGenericError(xmlGenericErrorContext,
148 "xmlNewTextWriterFilename : out of memory!\n");
149 return NULL;
150 }
151
152 ret = xmlNewTextWriter(out);
153 if (ret == NULL) {
154 xmlGenericError(xmlGenericErrorContext,
155 "xmlNewTextWriterFilename : out of memory!\n");
156 xmlOutputBufferClose(out);
157 return NULL;
158 }
159
160 return ret;
161}
162
163/**
164 * xmlNewTextWriterMemory:
165 * @buf: xmlBufferPtr
166 * @compression: compress the output?
167 *
168 * Create a new xmlNewTextWriter structure with @buf as output
169 * TODO: handle compression
170 *
171 * Returns the new xmlTextWriterPtr or NULL in case of error
172 */
173xmlTextWriterPtr
174xmlNewTextWriterMemory(xmlBufferPtr buf, int compression ATTRIBUTE_UNUSED)
175{
176 xmlTextWriterPtr ret;
177 xmlOutputBufferPtr out;
178
179/*::todo handle compression */
180 out = xmlOutputBufferCreateIO((xmlOutputWriteCallback)
181 xmlTextWriterWriteMemCallback,
182 (xmlOutputCloseCallback)
183 xmlTextWriterCloseMemCallback,
184 (void *) buf, NULL);
185 if (out == NULL) {
186 xmlGenericError(xmlGenericErrorContext,
187 "xmlNewTextWriterMemory : out of memory!\n");
188 return NULL;
189 }
190
191 ret = xmlNewTextWriter(out);
192 if (ret == NULL) {
193 xmlGenericError(xmlGenericErrorContext,
194 "xmlNewTextWriterMemory : out of memory!\n");
195 xmlOutputBufferClose(out);
196 return NULL;
197 }
198
199 return ret;
200}
201
202/**
203 * xmlFreeTextWriter:
204 * @writer: the xmlTextWriterPtr
205 *
206 * Deallocate all the resources associated to the writer
207 */
208void
209xmlFreeTextWriter(xmlTextWriterPtr writer)
210{
211 if (writer == NULL)
212 return;
213
214 if (writer->out != NULL)
215 xmlOutputBufferClose(writer->out);
216
217 if (writer->nodes != NULL)
218 xmlListDelete(writer->nodes);
219
220 if (writer->nsstack != NULL)
221 xmlListDelete(writer->nsstack);
222
223 xmlFree(writer);
224}
225
226/**
227 * xmlTextWriterStartDocument:
228 * @writer: the xmlTextWriterPtr
229 * @version: the xml version ("1.0") or NULL for default ("1.0")
230 * @encoding: the encoding or NULL for default
231 * @standalone: "yes" or "no" or NULL for default
232 *
233 * Start a new xml document
234 *
235 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
236 */
237int
238xmlTextWriterStartDocument(xmlTextWriterPtr writer, const char *version,
239 const char *encoding, const char *standalone)
240{
241 int count;
242 int sum;
243 xmlLinkPtr lk;
244 xmlCharEncodingHandlerPtr encoder;
245
246 if ((writer == NULL) || (writer->out == NULL))
247 return -1;
248
249 lk = xmlListFront(writer->nodes);
250 if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) {
251 xmlGenericError(xmlGenericErrorContext,
252 "xmlTextWriterStartDocument : only one prolog allowed in an XML document!\n");
253 return -1;
254 }
255
256 encoder = NULL;
257 if (encoding != NULL) {
258 encoder = xmlFindCharEncodingHandler(encoding);
259 if (encoder == NULL) {
260 xmlGenericError(xmlGenericErrorContext,
261 "xmlTextWriterStartDocument : out of memory!\n");
262 return -1;
263 }
264 }
265
266 writer->out->encoder = encoder;
267 if (encoder != NULL) {
268 writer->out->conv = xmlBufferCreateSize(4000);
269 xmlCharEncOutFunc(encoder, writer->out->conv, NULL);
270 } else
271 writer->out->conv = NULL;
272
273 sum = 0;
274 count = xmlOutputBufferWriteString(writer->out, "<?xml version=");
275 if (count < 0)
276 return -1;
277 sum += count;
278 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
279 if (count < 0)
280 return -1;
281 sum += count;
282 if (version != 0)
283 count = xmlOutputBufferWriteString(writer->out, version);
284 else
285 count = xmlOutputBufferWriteString(writer->out, "1.0");
286 if (count < 0)
287 return -1;
288 sum += count;
289 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
290 if (count < 0)
291 return -1;
292 sum += count;
293 if (writer->out->encoder != 0) {
294 count = xmlOutputBufferWriteString(writer->out, " encoding=");
295 if (count < 0)
296 return -1;
297 sum += count;
298 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
299 if (count < 0)
300 return -1;
301 sum += count;
302 count =
303 xmlOutputBufferWriteString(writer->out,
304 writer->out->encoder->name);
305 if (count < 0)
306 return -1;
307 sum += count;
308 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
309 if (count < 0)
310 return -1;
311 sum += count;
312 }
313
314 if (standalone != 0) {
315 count = xmlOutputBufferWriteString(writer->out, " standalone=");
316 if (count < 0)
317 return -1;
318 sum += count;
319 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
320 if (count < 0)
321 return -1;
322 sum += count;
323 count = xmlOutputBufferWriteString(writer->out, standalone);
324 if (count < 0)
325 return -1;
326 sum += count;
327 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
328 if (count < 0)
329 return -1;
330 sum += count;
331 }
332
333 count = xmlOutputBufferWriteString(writer->out, "?>\n");
334 if (count < 0)
335 return -1;
336 sum += count;
337
338 return sum;
339}
340
341/**
342 * xmlTextWriterEndDocument:
343 * @writer: the xmlTextWriterPtr
344 *
345 * End an xml document. All open elements are closed
346 *
347 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
348 */
349int
350xmlTextWriterEndDocument(xmlTextWriterPtr writer)
351{
352 int count;
353 int sum;
354 xmlLinkPtr lk;
355 xmlTextWriterStackEntry *p;
356
357 if (writer == NULL)
358 return -1;
359
360 sum = 0;
361 while ((lk = xmlListFront(writer->nodes)) != NULL) {
362 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
363 if (p == 0)
364 break;
365 switch (p->state) {
366 case XML_TEXTWRITER_NAME:
367 case XML_TEXTWRITER_ATTRIBUTE:
368 case XML_TEXTWRITER_TEXT:
369 count = xmlTextWriterEndElement(writer);
370 if (count < 0)
371 return -1;
372 sum += count;
373 break;
374 case XML_TEXTWRITER_PI:
375 case XML_TEXTWRITER_PI_TEXT:
376 count = xmlTextWriterEndPI(writer);
377 if (count < 0)
378 return -1;
379 sum += count;
380 break;
381 case XML_TEXTWRITER_CDATA:
382 count = xmlTextWriterEndCDATA(writer);
383 if (count < 0)
384 return -1;
385 sum += count;
386 break;
387 case XML_TEXTWRITER_DTD:
388 count = xmlTextWriterEndDTD(writer);
389 if (count < 0)
390 return -1;
391 sum += count;
392 break;
393 default:
394 break;
395 }
396 }
397
398 return sum;
399}
400
401/**
402 * xmlTextWriterWriteFormatComment:
403 * @writer: the xmlTextWriterPtr
404 * @format: format string (see printf)
405 *
406 * Write an xml comment.
407 *
408 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
409 */
410int
411xmlTextWriterWriteFormatComment(xmlTextWriterPtr writer,
412 const char *format, ...)
413{
414 int rc;
415 va_list ap;
416
417 va_start(ap, format);
418
419 rc = xmlTextWriterWriteVFormatComment(writer, format, ap);
420
421 va_end(ap);
422 return rc;
423}
424
425/**
426 * xmlTextWriterWriteVFormatComment:
427 * @writer: the xmlTextWriterPtr
428 * @format: format string (see printf)
429 * @argptr: pointer to the first member of the variable argument list.
430 *
431 * Write an xml comment.
432 *
433 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
434 */
435int
436xmlTextWriterWriteVFormatComment(xmlTextWriterPtr writer,
437 const char *format, va_list argptr)
438{
439 int rc;
440 xmlChar *buf;
441
442 if (writer == NULL)
443 return -1;
444
445 buf = xmlTextWriterVSprintf(format, argptr);
446 if (buf == 0)
447 return 0;
448
449 rc = xmlTextWriterWriteComment(writer, buf);
450
451 xmlFree(buf);
452 return rc;
453}
454
455/**
456 * xmlTextWriterWriteComment:
457 * @writer: the xmlTextWriterPtr
458 * @content: comment string
459 *
460 * Write an xml comment.
461 *
462 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
463 */
464int
465xmlTextWriterWriteComment(xmlTextWriterPtr writer, const xmlChar * content)
466{
467 int count;
468 int sum;
469 xmlLinkPtr lk;
470 xmlTextWriterStackEntry *p;
471 xmlChar *buf;
472
473 if ((writer == NULL) || (writer->out == NULL))
474 return -1;
475
476 if (content == NULL)
477 return 0;
478
479 sum = 0;
480 lk = xmlListFront(writer->nodes);
481 if (lk != 0) {
482 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
483 if (p != 0) {
484 switch (p->state) {
485 case XML_TEXTWRITER_PI:
486 case XML_TEXTWRITER_PI_TEXT:
487 return -1;
488 case XML_TEXTWRITER_NONE:
489 case XML_TEXTWRITER_TEXT:
490 break;
491 case XML_TEXTWRITER_NAME:
492 count = xmlOutputBufferWriteString(writer->out, ">");
493 if (count < 0)
494 return -1;
495 sum += count;
496 p->state = XML_TEXTWRITER_TEXT;
497 break;
498 default:
499 break;
500 }
501 }
502 }
503
504 count = xmlOutputBufferWriteString(writer->out, "<!--");
505 if (count < 0)
506 return -1;
507 sum += count;
508 buf = xmlEncodeEntitiesReentrant(NULL, content);
509 if (buf != 0) {
510 count = xmlOutputBufferWriteString(writer->out, (const char *)buf);
511 xmlFree(buf);
512 } else
513 count = xmlOutputBufferWriteString(writer->out, (const char *)content);
514 if (count < 0)
515 return -1;
516 sum += count;
517 count = xmlOutputBufferWriteString(writer->out, "-->");
518 if (count < 0)
519 return -1;
520 sum += count;
521
522 return sum;
523}
524
525/**
526 * xmlTextWriterStartElement:
527 * @writer: the xmlTextWriterPtr
528 * @name: element name
529 *
530 * Start an xml element.
531 *
532 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
533 */
534int
535xmlTextWriterStartElement(xmlTextWriterPtr writer, const xmlChar * name)
536{
537 int count;
538 int sum;
539 xmlLinkPtr lk;
540 xmlTextWriterStackEntry *p;
541
542 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
543 return -1;
544
545 sum = 0;
546 lk = xmlListFront(writer->nodes);
547 if (lk != 0) {
548 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
549 if (p != 0) {
550 switch (p->state) {
551 case XML_TEXTWRITER_PI:
552 case XML_TEXTWRITER_PI_TEXT:
553 return -1;
554 case XML_TEXTWRITER_NONE:
555 break;
556 case XML_TEXTWRITER_NAME:
557 count = xmlOutputBufferWriteString(writer->out, ">");
558 if (count < 0)
559 return -1;
560 sum += count;
561 p->state = XML_TEXTWRITER_TEXT;
562 break;
563 default:
564 break;
565 }
566 }
567 }
568
569 p = (xmlTextWriterStackEntry *)
570 xmlMalloc(sizeof(xmlTextWriterStackEntry));
571 if (p == 0) {
572 xmlGenericError(xmlGenericErrorContext,
573 "xmlTextWriterStartElement : out of memory!\n");
574 return -1;
575 }
576
577 p->name = xmlStrdup(name);
578 if (p->name == 0) {
579 xmlGenericError(xmlGenericErrorContext,
580 "xmlTextWriterStartElement : out of memory!\n");
581 xmlFree(p);
582 return -1;
583 }
584 p->state = XML_TEXTWRITER_NAME;
585
586 xmlListPushFront(writer->nodes, p);
587
588 count = xmlOutputBufferWriteString(writer->out, "<");
589 if (count < 0)
590 return -1;
591 sum += count;
592 count = xmlOutputBufferWriteString(writer->out, (const char *)p->name);
593 if (count < 0)
594 return -1;
595 sum += count;
596
597 return sum;
598}
599
600/**
601 * xmlTextWriterStartElementNS:
602 * @writer: the xmlTextWriterPtr
603 * @prefix: namespace prefix or NULL
604 * @name: element local name
605 * @namespaceURI: namespace URI or NULL
606 *
607 * Start an xml element with namespace support.
608 *
609 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
610 */
611int
612xmlTextWriterStartElementNS(xmlTextWriterPtr writer,
613 const xmlChar * prefix, const xmlChar * name,
614 const xmlChar * namespaceURI)
615{
616 int count;
617 int sum;
618 xmlChar *buf;
619
620 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
621 return -1;
622
623 buf = 0;
624 if (prefix != 0) {
625 buf = xmlStrdup(prefix);
626 buf = xmlStrcat(buf, BAD_CAST ":");
627 }
628 buf = xmlStrcat(buf, name);
629
630 sum = 0;
631 count = xmlTextWriterStartElement(writer, buf);
632 xmlFree(buf);
633 if (count < 0)
634 return -1;
635 sum += count;
636
637 if (namespaceURI != 0) {
638 buf = xmlStrdup(BAD_CAST "xmlns");
639 if (prefix != 0) {
640 buf = xmlStrcat(buf, BAD_CAST ":");
641 buf = xmlStrcat(buf, prefix);
642 }
643
644 count = xmlTextWriterWriteAttribute(writer, buf, namespaceURI);
645 xmlFree(buf);
646 if (count < 0)
647 return -1;
648 sum += count;
649 }
650
651 return sum;
652}
653
654/**
655 * xmlTextWriterEndElement:
656 * @writer: the xmlTextWriterPtr
657 *
658 * End the current xml element.
659 *
660 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
661 */
662int
663xmlTextWriterEndElement(xmlTextWriterPtr writer)
664{
665 int count;
666 int sum;
667 xmlLinkPtr lk;
668 xmlTextWriterStackEntry *p;
669
670 if (writer == NULL)
671 return -1;
672
673 lk = xmlListFront(writer->nodes);
674 if (lk == 0)
675 return -1;
676
677 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
678 if (p == 0)
679 return -1;
680
681 sum = 0;
682 switch (p->state) {
683 case XML_TEXTWRITER_ATTRIBUTE:
684 count = xmlTextWriterEndAttribute(writer);
685 if (count < 0)
686 return -1;
687 sum += count;
688 /* fallthrough */
689 case XML_TEXTWRITER_NAME:
690 count = xmlOutputBufferWriteString(writer->out, "/>");
691 if (count < 0)
692 return -1;
693 sum += count;
694 break;
695 case XML_TEXTWRITER_TEXT:
696 count = xmlOutputBufferWriteString(writer->out, "</");
697 if (count < 0)
698 return -1;
699 sum += count;
700 count = xmlOutputBufferWriteString(writer->out,
701 (const char *)p->name);
702 if (count < 0)
703 return -1;
704 sum += count;
705 count = xmlOutputBufferWriteString(writer->out, ">");
706 if (count < 0)
707 return -1;
708 sum += count;
709 break;
710 default:
711 return -1;
712 }
713
714 xmlListPopFront(writer->nodes);
715 return sum;
716}
717
718/**
719 * xmlTextWriterFullEndElement:
720 * @writer: the xmlTextWriterPtr
721 *
722 * End the current xml element. Writes an end tag even if the element is empty
723 *
724 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
725 */
726int
727xmlTextWriterFullEndElement(xmlTextWriterPtr writer)
728{
729 int count;
730 int sum;
731 xmlLinkPtr lk;
732 xmlTextWriterStackEntry *p;
733
734 if (writer == NULL)
735 return -1;
736
737 lk = xmlListFront(writer->nodes);
738 if (lk == 0)
739 return -1;
740
741 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
742 if (p == 0)
743 return -1;
744
745 sum = 0;
746 switch (p->state) {
747 case XML_TEXTWRITER_ATTRIBUTE:
748 count = xmlTextWriterEndAttribute(writer);
749 if (count < 0)
750 return -1;
751 sum += count;
752 /* fallthrough */
753 case XML_TEXTWRITER_NAME:
754 count = xmlOutputBufferWriteString(writer->out, ">");
755 if (count < 0)
756 return -1;
757 sum += count;
758 /* fallthrough */
759 case XML_TEXTWRITER_TEXT:
760 count = xmlOutputBufferWriteString(writer->out, "</");
761 if (count < 0)
762 return -1;
763 sum += count;
764 count = xmlOutputBufferWriteString(writer->out,
765 (const char *) p->name);
766 if (count < 0)
767 return -1;
768 sum += count;
769 count = xmlOutputBufferWriteString(writer->out, ">");
770 if (count < 0)
771 return -1;
772 sum += count;
773 break;
774 default:
775 return -1;
776 }
777
778 xmlListPopFront(writer->nodes);
779 return sum;
780}
781
782/**
783 * xmlTextWriterWriteFormatRaw:
784 * @writer: the xmlTextWriterPtr
785 * @format: format string (see printf)
786 *
787 * Write a formatted raw xml text.
788 *
789 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
790 */
791int
792xmlTextWriterWriteFormatRaw(xmlTextWriterPtr writer, const char *format,
793 ...)
794{
795 int rc;
796 va_list ap;
797
798 va_start(ap, format);
799
800 rc = xmlTextWriterWriteVFormatRaw(writer, format, ap);
801
802 va_end(ap);
803 return rc;
804}
805
806/**
807 * xmlTextWriterWriteVFormatRaw:
808 * @writer: the xmlTextWriterPtr
809 * @format: format string (see printf)
810 * @argptr: pointer to the first member of the variable argument list.
811 *
812 * Write a formatted raw xml text.
813 *
814 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
815 */
816int
817xmlTextWriterWriteVFormatRaw(xmlTextWriterPtr writer, const char *format,
818 va_list argptr)
819{
820 int rc;
821 xmlChar *buf;
822
823 if (writer == NULL)
824 return -1;
825
826 buf = xmlTextWriterVSprintf(format, argptr);
827 if (buf == 0)
828 return 0;
829
830 rc = xmlTextWriterWriteRaw(writer, buf);
831
832 xmlFree(buf);
833 return rc;
834}
835
836/**
837 * xmlTextWriterWriteStringLen:
838 * @writer: the xmlTextWriterPtr
839 * @content: text string
840 * @len: length of the text string
841 *
842 * Write an xml text.
843 * TODO: what about entities and special chars??
844 *
845 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
846 */
847int
848xmlTextWriterWriteRawLen(xmlTextWriterPtr writer, const xmlChar * content,
849 int len)
850{
851 int count;
852 int sum;
853 xmlLinkPtr lk;
854 xmlTextWriterStackEntry *p;
855
856 if (writer == NULL)
857 return -1;
858
859 lk = xmlListFront(writer->nodes);
860 if (lk == 0)
861 return 0;
862
863 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
864 if (p == 0)
865 return 0;
866
867 sum = 0;
868 switch (p->state) {
869 case XML_TEXTWRITER_NONE:
870 return -1;
871 case XML_TEXTWRITER_NAME:
872 count = xmlOutputBufferWriteString(writer->out, ">");
873 if (count < 0)
874 return -1;
875 sum += count;
876 p->state = XML_TEXTWRITER_TEXT;
877 break;
878 case XML_TEXTWRITER_PI:
879 count = xmlOutputBufferWriteString(writer->out, " ");
880 if (count < 0)
881 return -1;
882 sum += count;
883 p->state = XML_TEXTWRITER_PI_TEXT;
884 break;
885 case XML_TEXTWRITER_DTD:
886 count = xmlOutputBufferWriteString(writer->out, " [");
887 if (count < 0)
888 return -1;
889 sum += count;
890 p->state = XML_TEXTWRITER_DTD_TEXT;
891 break;
892 default:
893 break;
894 }
895
896 count = xmlOutputBufferWrite(writer->out, len, (const char *) content);
897 if (count < 0)
898 return -1;
899 sum += count;
900
901 return sum;
902}
903
904/**
905 * xmlTextWriterWriteRaw:
906 * @writer: the xmlTextWriterPtr
907 * @content: text string
908 *
909 * Write a raw xml text.
910 *
911 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
912 */
913int
914xmlTextWriterWriteRaw(xmlTextWriterPtr writer, const xmlChar * content)
915{
916 return xmlTextWriterWriteRawLen(writer, content, xmlStrlen(content));
917}
918
919/**
920 * xmlTextWriterWriteFormatString:
921 * @writer: the xmlTextWriterPtr
922 * @format: format string (see printf)
923 *
924 * Write a formatted xml text.
925 *
926 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
927 */
928int
929xmlTextWriterWriteFormatString(xmlTextWriterPtr writer, const char *format,
930 ...)
931{
932 int rc;
933 va_list ap;
934
935 va_start(ap, format);
936
937 rc = xmlTextWriterWriteVFormatString(writer, format, ap);
938
939 va_end(ap);
940 return rc;
941}
942
943/**
944 * xmlTextWriterWriteVFormatString:
945 * @writer: the xmlTextWriterPtr
946 * @format: format string (see printf)
947 * @argptr: pointer to the first member of the variable argument list.
948 *
949 * Write a formatted xml text.
950 *
951 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
952 */
953int
954xmlTextWriterWriteVFormatString(xmlTextWriterPtr writer,
955 const char *format, va_list argptr)
956{
957 int rc;
958 xmlChar *buf;
959
960 if (writer == NULL)
961 return -1;
962
963 buf = xmlTextWriterVSprintf(format, argptr);
964 if (buf == 0)
965 return 0;
966
967 rc = xmlTextWriterWriteString(writer, buf);
968
969 xmlFree(buf);
970 return rc;
971}
972
973/**
974 * xmlTextWriterWriteString:
975 * @writer: the xmlTextWriterPtr
976 * @content: text string
977 *
978 * Write an xml text.
979 *
980 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
981 */
982int
983xmlTextWriterWriteString(xmlTextWriterPtr writer, const xmlChar * content)
984{
985 int count;
986 int sum;
987 xmlLinkPtr lk;
988 xmlTextWriterStackEntry *p;
989 xmlChar *buf = NULL;
990
991 if (writer == NULL)
992 return -1;
993
994 lk = xmlListFront(writer->nodes);
995 if (lk == 0)
996 return -1;
997
998 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
999 if (p == 0)
1000 return -1;
1001
1002 sum = 0;
1003 switch (p->state) {
1004 case XML_TEXTWRITER_NONE:
1005 return -1;
1006 case XML_TEXTWRITER_NAME:
1007 count = xmlOutputBufferWriteString(writer->out, ">");
1008 if (count < 0)
1009 return -1;
1010 sum += count;
1011 p->state = XML_TEXTWRITER_TEXT;
1012 goto encode;
1013 case XML_TEXTWRITER_PI:
1014 count = xmlOutputBufferWriteString(writer->out, " ");
1015 if (count < 0)
1016 return -1;
1017 sum += count;
1018 p->state = XML_TEXTWRITER_PI_TEXT;
1019 /* fallthrough */
1020 case XML_TEXTWRITER_PI_TEXT:
1021 case XML_TEXTWRITER_TEXT:
1022 case XML_TEXTWRITER_ATTRIBUTE:
1023 encode:
1024 buf = xmlEncodeEntitiesReentrant(NULL, content);
1025 break;
1026 case XML_TEXTWRITER_DTD:
1027 count = xmlOutputBufferWriteString(writer->out, " [");
1028 if (count < 0)
1029 return -1;
1030 sum += count;
1031 p->state = XML_TEXTWRITER_DTD_TEXT;
1032 /* fallthrough */
1033 case XML_TEXTWRITER_DTD_TEXT:
1034 case XML_TEXTWRITER_DTD_ELEM:
1035 case XML_TEXTWRITER_CDATA:
1036 buf = xmlStrdup(content);
1037 break;
1038 default:
1039 break;
1040 }
1041
1042 if (buf != 0) {
1043 count = xmlOutputBufferWriteString(writer->out, (const char *) buf);
1044 xmlFree(buf);
1045 } else
1046 count = -1;
1047 if (count < 0)
1048 return -1;
1049 sum += count;
1050
1051 return sum;
1052}
1053
1054/**
1055 * xmlOutputBufferWriteBase64:
1056 * @out: the xmlOutputBufferPtr
1057 * @data: binary data
1058 * @len: the number of bytes to encode
1059 *
1060 * Write base64 encoded data to an xmlOutputBuffer.
1061 * Adapted from John Walker's base64.c (http://www.fourmilab.ch/).
1062 *
1063 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1064 */
1065static int
1066xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len,
1067 const unsigned char *data)
1068{
1069 static unsigned char dtable[64] =
1070 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1071 int i;
1072 int linelen;
1073 int count;
1074 int sum;
1075
1076 linelen = 0;
1077 sum = 0;
1078
1079 i = 0;
1080 while (1) {
1081 unsigned char igroup[3];
1082 unsigned char ogroup[4];
1083 int c;
1084 int n;
1085
1086 igroup[0] = igroup[1] = igroup[2] = 0;
1087 for (n = 0; n < 3 && i < len; n++, i++) {
1088 c = data[i];
1089 igroup[n] = (unsigned char) c;
1090 }
1091
1092 if (n > 0) {
1093 ogroup[0] = dtable[igroup[0] >> 2];
1094 ogroup[1] = dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)];
1095 ogroup[2] =
1096 dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)];
1097 ogroup[3] = dtable[igroup[2] & 0x3F];
1098
1099 if (n < 3) {
1100 ogroup[3] = '=';
1101 if (n < 2) {
1102 ogroup[2] = '=';
1103 }
1104 }
1105
1106 if (linelen >= B64LINELEN) {
1107 count = xmlOutputBufferWrite(out, 2, B64CRLF);
1108 if (count == -1)
1109 return -1;
1110 sum += count;
1111 linelen = 0;
1112 }
1113 count = xmlOutputBufferWrite(out, 4, (const char *) ogroup);
1114 if (count == -1)
1115 return -1;
1116 sum += count;
1117
1118 linelen += 4;
1119 }
1120 }
1121
1122 count = xmlOutputBufferWrite(out, 2, B64CRLF);
1123 if (count == -1)
1124 return -1;
1125 sum += count;
1126
1127 return sum;
1128}
1129
1130/**
1131 * xmlTextWriterWriteBase64:
1132 * @writer: the xmlTextWriterPtr
1133 * @data: binary data
1134 * @start: the position within the data of the first byte to encode
1135 * @len: the number of bytes to encode
1136 *
1137 * Write an base64 encoded xml text.
1138 *
1139 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1140 */
1141int
1142xmlTextWriterWriteBase64(xmlTextWriterPtr writer, const char * data,
1143 int start, int len)
1144{
1145 int count;
1146 int sum;
1147 xmlLinkPtr lk;
1148 xmlTextWriterStackEntry *p;
1149
1150 if (writer == NULL)
1151 return -1;
1152
1153 lk = xmlListFront(writer->nodes);
1154 if (lk == 0)
1155 return 0;
1156
1157 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1158 if (p == 0)
1159 return 0;
1160
1161 sum = 0;
1162 switch (p->state) {
1163 case XML_TEXTWRITER_NONE:
1164 return -1;
1165 case XML_TEXTWRITER_NAME:
1166 count = xmlOutputBufferWriteString(writer->out, ">");
1167 if (count < 0)
1168 return -1;
1169 sum += count;
1170 p->state = XML_TEXTWRITER_TEXT;
1171 break;
1172 case XML_TEXTWRITER_PI:
1173 count = xmlOutputBufferWriteString(writer->out, " ");
1174 if (count < 0)
1175 return -1;
1176 sum += count;
1177 p->state = XML_TEXTWRITER_PI_TEXT;
1178 break;
1179 case XML_TEXTWRITER_DTD:
1180 count = xmlOutputBufferWriteString(writer->out, " [");
1181 if (count < 0)
1182 return -1;
1183 sum += count;
1184 p->state = XML_TEXTWRITER_DTD_TEXT;
1185 break;
1186 default:
1187 break;
1188 }
1189
1190 count =
1191 xmlOutputBufferWriteBase64(writer->out, len,
1192 (unsigned char *) data + start);
1193 if (count < 0)
1194 return -1;
1195 sum += count;
1196
1197 return sum;
1198}
1199
1200/**
1201 * xmlOutputBufferWriteBinHex:
1202 * @out: the xmlOutputBufferPtr
1203 * @data: binary data
1204 * @len: the number of bytes to encode
1205 *
1206 * Write hqx encoded data to an xmlOutputBuffer.
1207 * ::todo
1208 *
1209 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1210 */
1211static int
1212xmlOutputBufferWriteBinHex(xmlOutputBufferPtr out ATTRIBUTE_UNUSED,
1213 int len ATTRIBUTE_UNUSED,
1214 const unsigned char *data ATTRIBUTE_UNUSED)
1215{
1216 return -1;
1217}
1218
1219/**
1220 * xmlTextWriterWriteBinHex:
1221 * @writer: the xmlTextWriterPtr
1222 * @data: binary data
1223 * @start: the position within the data of the first byte to encode
1224 * @len: the number of bytes to encode
1225 *
1226 * Write a BinHex encoded xml text.
1227 *
1228 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1229 */
1230int
1231xmlTextWriterWriteBinHex(xmlTextWriterPtr writer, const char * data,
1232 int start, int len)
1233{
1234 int count;
1235 int sum;
1236 xmlLinkPtr lk;
1237 xmlTextWriterStackEntry *p;
1238
1239 if (writer == NULL)
1240 return -1;
1241
1242 lk = xmlListFront(writer->nodes);
1243 if (lk == 0)
1244 return 0;
1245
1246 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1247 if (p == 0)
1248 return 0;
1249
1250 sum = 0;
1251 switch (p->state) {
1252 case XML_TEXTWRITER_NONE:
1253 return -1;
1254 case XML_TEXTWRITER_NAME:
1255 count = xmlOutputBufferWriteString(writer->out, ">");
1256 if (count < 0)
1257 return -1;
1258 sum += count;
1259 p->state = XML_TEXTWRITER_TEXT;
1260 break;
1261 case XML_TEXTWRITER_PI:
1262 count = xmlOutputBufferWriteString(writer->out, " ");
1263 if (count < 0)
1264 return -1;
1265 sum += count;
1266 p->state = XML_TEXTWRITER_PI_TEXT;
1267 break;
1268 case XML_TEXTWRITER_DTD:
1269 count = xmlOutputBufferWriteString(writer->out, " [");
1270 if (count < 0)
1271 return -1;
1272 sum += count;
1273 p->state = XML_TEXTWRITER_DTD_TEXT;
1274 break;
1275 default:
1276 break;
1277 }
1278
1279 count =
1280 xmlOutputBufferWriteBinHex(writer->out, len,
1281 (unsigned char *) data + start);
1282 if (count < 0)
1283 return -1;
1284 sum += count;
1285
1286 return sum;
1287}
1288
1289/**
1290 * xmlTextWriterStartAttribute:
1291 * @writer: the xmlTextWriterPtr
1292 * @name: element name
1293 *
1294 * Start an xml attribute.
1295 *
1296 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1297 */
1298int
1299xmlTextWriterStartAttribute(xmlTextWriterPtr writer, const xmlChar * name)
1300{
1301 int count;
1302 int sum;
1303 xmlLinkPtr lk;
1304 xmlTextWriterStackEntry *p;
1305
1306 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1307 return -1;
1308
1309 sum = 0;
1310 lk = xmlListFront(writer->nodes);
1311 if (lk == 0)
1312 return -1;
1313
1314 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1315 if (p == 0)
1316 return -1;
1317
1318 switch (p->state) {
1319 case XML_TEXTWRITER_ATTRIBUTE:
1320 count = xmlTextWriterEndAttribute(writer);
1321 if (count < 0)
1322 return -1;
1323 sum += count;
1324 /* fallthrough */
1325 case XML_TEXTWRITER_NAME:
1326 count = xmlOutputBufferWriteString(writer->out, " ");
1327 if (count < 0)
1328 return -1;
1329 sum += count;
1330 count = xmlOutputBufferWriteString(writer->out, (const char *)name);
1331 if (count < 0)
1332 return -1;
1333 sum += count;
1334 count = xmlOutputBufferWriteString(writer->out, "=");
1335 if (count < 0)
1336 return -1;
1337 sum += count;
1338 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
1339 if (count < 0)
1340 return -1;
1341 sum += count;
1342 p->state = XML_TEXTWRITER_ATTRIBUTE;
1343 break;
1344 default:
1345 return -1;
1346 }
1347
1348 return sum;
1349}
1350
1351/**
1352 * xmlTextWriterStartAttributeNS:
1353 * @writer: the xmlTextWriterPtr
1354 * @prefix: namespace prefix or NULL
1355 * @name: element local name
1356 * @namespaceURI: namespace URI or NULL
1357 *
1358 * Start an xml attribute with namespace support.
1359 *
1360 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1361 */
1362int
1363xmlTextWriterStartAttributeNS(xmlTextWriterPtr writer,
1364 const xmlChar * prefix, const xmlChar * name,
1365 const xmlChar * namespaceURI)
1366{
1367 int count;
1368 int sum;
1369 xmlChar *buf;
1370 xmlTextWriterNsStackEntry *p;
1371
1372 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1373 return -1;
1374
1375 buf = 0;
1376 if (prefix != 0) {
1377 buf = xmlStrdup(prefix);
1378 buf = xmlStrcat(buf, BAD_CAST ":");
1379 }
1380 buf = xmlStrcat(buf, name);
1381
1382 sum = 0;
1383 count = xmlTextWriterStartAttribute(writer, buf);
1384 xmlFree(buf);
1385 if (count < 0)
1386 return -1;
1387 sum += count;
1388
1389 if (namespaceURI != 0) {
1390 buf = xmlStrdup(BAD_CAST "xmlns");
1391 if (prefix != 0) {
1392 buf = xmlStrcat(buf, BAD_CAST ":");
1393 buf = xmlStrcat(buf, prefix);
1394 }
1395
1396 p = (xmlTextWriterNsStackEntry *)
1397 xmlMalloc(sizeof(xmlTextWriterNsStackEntry));
1398 if (p == 0) {
1399 xmlGenericError(xmlGenericErrorContext,
1400 "xmlTextWriterStartAttributeNS : out of memory!\n");
1401 return -1;
1402 }
1403
1404 p->prefix = buf;
1405 p->uri = xmlStrdup(namespaceURI);
1406 if (p->uri == 0) {
1407 xmlGenericError(xmlGenericErrorContext,
1408 "xmlTextWriterStartAttributeNS : out of memory!\n");
1409 xmlFree(p);
1410 return -1;
1411 }
1412 p->elem = xmlListFront(writer->nodes);
1413
1414 xmlListPushFront(writer->nsstack, p);
1415 }
1416
1417 return sum;
1418}
1419
1420/**
1421 * xmlTextWriterEndAttribute:
1422 * @writer: the xmlTextWriterPtr
1423 *
1424 * End the current xml element.
1425 *
1426 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1427 */
1428int
1429xmlTextWriterEndAttribute(xmlTextWriterPtr writer)
1430{
1431 int count;
1432 int sum;
1433 xmlLinkPtr lk;
1434 xmlTextWriterStackEntry *p;
1435 xmlTextWriterNsStackEntry *np;
1436
1437 if (writer == NULL)
1438 return -1;
1439
1440 lk = xmlListFront(writer->nodes);
1441 if (lk == 0) {
1442 xmlListDelete(writer->nsstack);
1443 return -1;
1444 }
1445
1446 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1447 if (p == 0) {
1448 xmlListDelete(writer->nsstack);
1449 return -1;
1450 }
1451
1452 sum = 0;
1453 switch (p->state) {
1454 case XML_TEXTWRITER_ATTRIBUTE:
1455 p->state = XML_TEXTWRITER_NAME;
1456
1457 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
1458 if (count < 0) {
1459 xmlListDelete(writer->nsstack);
1460 return -1;
1461 }
1462 sum += count;
1463
1464 while (!xmlListEmpty(writer->nsstack)) {
1465 lk = xmlListFront(writer->nsstack);
1466 np = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
1467 if (np != 0) {
1468 count =
1469 xmlTextWriterWriteAttribute(writer, np->prefix,
1470 np->uri);
1471 if (count < 0) {
1472 xmlListDelete(writer->nsstack);
1473 return -1;
1474 }
1475 sum += count;
1476 }
1477
1478 xmlListPopFront(writer->nsstack);
1479 }
1480 break;
1481
1482 default:
1483 xmlListClear(writer->nsstack);
1484 return -1;
1485 }
1486
1487 return sum;
1488}
1489
1490/**
1491 * xmlTextWriterWriteFormatAttribute:
1492 * @writer: the xmlTextWriterPtr
1493 * @name: attribute name
1494 * @format: format string (see printf)
1495 *
1496 * Write a formatted xml attribute.
1497 *
1498 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1499 */
1500int
1501xmlTextWriterWriteFormatAttribute(xmlTextWriterPtr writer,
1502 const xmlChar * name, const char *format,
1503 ...)
1504{
1505 int rc;
1506 va_list ap;
1507
1508 va_start(ap, format);
1509
1510 rc = xmlTextWriterWriteVFormatAttribute(writer, name, format, ap);
1511
1512 va_end(ap);
1513 return rc;
1514}
1515
1516/**
1517 * xmlTextWriterWriteVFormatAttribute:
1518 * @writer: the xmlTextWriterPtr
1519 * @name: attribute name
1520 * @format: format string (see printf)
1521 * @argptr: pointer to the first member of the variable argument list.
1522 *
1523 * Write a formatted xml attribute.
1524 *
1525 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1526 */
1527int
1528xmlTextWriterWriteVFormatAttribute(xmlTextWriterPtr writer,
1529 const xmlChar * name,
1530 const char *format, va_list argptr)
1531{
1532 int rc;
1533 xmlChar *buf;
1534
1535 if (writer == NULL)
1536 return -1;
1537
1538 buf = xmlTextWriterVSprintf(format, argptr);
1539 if (buf == 0)
1540 return 0;
1541
1542 rc = xmlTextWriterWriteAttribute(writer, name, buf);
1543
1544 xmlFree(buf);
1545 return rc;
1546}
1547
1548/**
1549 * xmlTextWriterWriteAttribute:
1550 * @writer: the xmlTextWriterPtr
1551 * @name: attribute name
1552 * @content: attribute content
1553 *
1554 * Write an xml attribute.
1555 *
1556 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1557 */
1558int
1559xmlTextWriterWriteAttribute(xmlTextWriterPtr writer, const xmlChar * name,
1560 const xmlChar * content)
1561{
1562 int count;
1563 int sum;
1564
1565 sum = 0;
1566 count = xmlTextWriterStartAttribute(writer, name);
1567 if (count < 0)
1568 return -1;
1569 sum += count;
1570 count = xmlTextWriterWriteString(writer, content);
1571 if (count < 0)
1572 return -1;
1573 sum += count;
1574 count = xmlTextWriterEndAttribute(writer);
1575 if (count < 0)
1576 return -1;
1577 sum += count;
1578
1579 return sum;
1580}
1581
1582/**
1583 * xmlTextWriterWriteFormatAttributeNS:
1584 * @writer: the xmlTextWriterPtr
1585 * @prefix: namespace prefix
1586 * @name: attribute local name
1587 * @namespaceURI: namespace URI
1588 * @format: format string (see printf)
1589 *
1590 * Write a formatted xml attribute.with namespace support
1591 *
1592 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1593 */
1594int
1595xmlTextWriterWriteFormatAttributeNS(xmlTextWriterPtr writer,
1596 const xmlChar * prefix,
1597 const xmlChar * name,
1598 const xmlChar * namespaceURI,
1599 const char *format, ...)
1600{
1601 int rc;
1602 va_list ap;
1603
1604 va_start(ap, format);
1605
1606 rc = xmlTextWriterWriteVFormatAttributeNS(writer, prefix, name,
1607 namespaceURI, format, ap);
1608
1609 va_end(ap);
1610 return rc;
1611}
1612
1613/**
1614 * xmlTextWriterWriteVFormatAttributeNS:
1615 * @writer: the xmlTextWriterPtr
1616 * @prefix: namespace prefix
1617 * @name: attribute local name
1618 * @namespaceURI: namespace URI
1619 * @format: format string (see printf)
1620 * @argptr: pointer to the first member of the variable argument list.
1621 *
1622 * Write a formatted xml attribute.with namespace support
1623 *
1624 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1625 */
1626int
1627xmlTextWriterWriteVFormatAttributeNS(xmlTextWriterPtr writer,
1628 const xmlChar * prefix,
1629 const xmlChar * name,
1630 const xmlChar * namespaceURI,
1631 const char *format, va_list argptr)
1632{
1633 int rc;
1634 xmlChar *buf;
1635
1636 if (writer == NULL)
1637 return -1;
1638
1639 buf = xmlTextWriterVSprintf(format, argptr);
1640 if (buf == 0)
1641 return 0;
1642
1643 rc = xmlTextWriterWriteAttributeNS(writer, prefix, name, namespaceURI,
1644 buf);
1645
1646 xmlFree(buf);
1647 return rc;
1648}
1649
1650/**
1651 * xmlTextWriterWriteAttributeNS:
1652 * @writer: the xmlTextWriterPtr
1653 * @prefix: namespace prefix
1654 * @name: attribute local name
1655 * @namespaceURI: namespace URI
1656 * @content: attribute content
1657 *
1658 * Write an xml attribute.
1659 *
1660 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1661 */
1662int
1663xmlTextWriterWriteAttributeNS(xmlTextWriterPtr writer,
1664 const xmlChar * prefix, const xmlChar * name,
1665 const xmlChar * namespaceURI,
1666 const xmlChar * content)
1667{
1668 int count;
1669 int sum;
1670 xmlChar *buf;
1671
1672 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1673 return -1;
1674
1675 buf = 0;
1676 if (prefix != NULL) {
1677 buf = xmlStrdup(prefix);
1678 buf = xmlStrcat(buf, BAD_CAST ":");
1679 }
1680 buf = xmlStrcat(buf, name);
1681
1682 sum = 0;
1683 count = xmlTextWriterWriteAttribute(writer, buf, content);
1684 xmlFree(buf);
1685 if (count < 0)
1686 return -1;
1687 sum += count;
1688
1689 if (namespaceURI != NULL) {
1690 buf = 0;
1691 buf = xmlStrdup(BAD_CAST "xmlns");
1692 if (prefix != NULL) {
1693 buf = xmlStrcat(buf, BAD_CAST ":");
1694 buf = xmlStrcat(buf, prefix);
1695 }
1696 count = xmlTextWriterWriteAttribute(writer, buf, namespaceURI);
1697 xmlFree(buf);
1698 if (count < 0)
1699 return -1;
1700 sum += count;
1701 }
1702 return sum;
1703}
1704
1705/**
1706 * xmlTextWriterWriteFormatElement:
1707 * @writer: the xmlTextWriterPtr
1708 * @name: element name
1709 * @format: format string (see printf)
1710 *
1711 * Write a formatted xml element.
1712 *
1713 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1714 */
1715int
1716xmlTextWriterWriteFormatElement(xmlTextWriterPtr writer,
1717 const xmlChar * name, const char *format,
1718 ...)
1719{
1720 int rc;
1721 va_list ap;
1722
1723 va_start(ap, format);
1724
1725 rc = xmlTextWriterWriteVFormatElement(writer, name, format, ap);
1726
1727 va_end(ap);
1728 return rc;
1729}
1730
1731/**
1732 * xmlTextWriterWriteVFormatElement:
1733 * @writer: the xmlTextWriterPtr
1734 * @name: element name
1735 * @format: format string (see printf)
1736 * @argptr: pointer to the first member of the variable argument list.
1737 *
1738 * Write a formatted xml element.
1739 *
1740 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1741 */
1742int
1743xmlTextWriterWriteVFormatElement(xmlTextWriterPtr writer,
1744 const xmlChar * name, const char *format,
1745 va_list argptr)
1746{
1747 int rc;
1748 xmlChar *buf;
1749
1750 if (writer == NULL)
1751 return -1;
1752
1753 buf = xmlTextWriterVSprintf(format, argptr);
1754 if (buf == 0)
1755 return 0;
1756
1757 rc = xmlTextWriterWriteElement(writer, name, buf);
1758
1759 xmlFree(buf);
1760 return rc;
1761}
1762
1763/**
1764 * xmlTextWriterWriteElement:
1765 * @writer: the xmlTextWriterPtr
1766 * @name: element name
1767 * @content: element content
1768 *
1769 * Write an xml element.
1770 *
1771 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1772 */
1773int
1774xmlTextWriterWriteElement(xmlTextWriterPtr writer, const xmlChar * name,
1775 const xmlChar * content)
1776{
1777 int count;
1778 int sum;
1779
1780 sum = 0;
1781 count = xmlTextWriterStartElement(writer, name);
1782 if (count == -1)
1783 return -1;
1784 sum += count;
1785 count = xmlTextWriterWriteString(writer, content);
1786 if (count == -1)
1787 return -1;
1788 sum += count;
1789 count = xmlTextWriterEndElement(writer);
1790 if (count == -1)
1791 return -1;
1792 sum += count;
1793
1794 return sum;
1795}
1796
1797/**
1798 * xmlTextWriterWriteFormatElementNS:
1799 * @writer: the xmlTextWriterPtr
1800 * @prefix: namespace prefix
1801 * @name: element local name
1802 * @namespaceURI: namespace URI
1803 * @format: format string (see printf)
1804 *
1805 * Write a formatted xml element with namespace support.
1806 *
1807 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1808 */
1809int
1810xmlTextWriterWriteFormatElementNS(xmlTextWriterPtr writer,
1811 const xmlChar * prefix,
1812 const xmlChar * name,
1813 const xmlChar * namespaceURI,
1814 const char *format, ...)
1815{
1816 int rc;
1817 va_list ap;
1818
1819 va_start(ap, format);
1820
1821 rc = xmlTextWriterWriteVFormatElementNS(writer, prefix, name,
1822 namespaceURI, format, ap);
1823
1824 va_end(ap);
1825 return rc;
1826}
1827
1828/**
1829 * xmlTextWriterWriteVFormatElementNS:
1830 * @writer: the xmlTextWriterPtr
1831 * @prefix: namespace prefix
1832 * @name: element local name
1833 * @namespaceURI: namespace URI
1834 * @format: format string (see printf)
1835 * @argptr: pointer to the first member of the variable argument list.
1836 *
1837 * Write a formatted xml element with namespace support.
1838 *
1839 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1840 */
1841int
1842xmlTextWriterWriteVFormatElementNS(xmlTextWriterPtr writer,
1843 const xmlChar * prefix,
1844 const xmlChar * name,
1845 const xmlChar * namespaceURI,
1846 const char *format, va_list argptr)
1847{
1848 int rc;
1849 xmlChar *buf;
1850
1851 if (writer == NULL)
1852 return -1;
1853
1854 buf = xmlTextWriterVSprintf(format, argptr);
1855 if (buf == 0)
1856 return 0;
1857
1858 rc = xmlTextWriterWriteElementNS(writer, prefix, name, namespaceURI,
1859 buf);
1860
1861 xmlFree(buf);
1862 return rc;
1863}
1864
1865/**
1866 * xmlTextWriterWriteElementNS:
1867 * @writer: the xmlTextWriterPtr
1868 * @prefix: namespace prefix
1869 * @name: element local name
1870 * @namespaceURI: namespace URI
1871 * @content: element content
1872 *
1873 * Write an xml element with namespace support.
1874 *
1875 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1876 */
1877int
1878xmlTextWriterWriteElementNS(xmlTextWriterPtr writer,
1879 const xmlChar * prefix, const xmlChar * name,
1880 const xmlChar * namespaceURI,
1881 const xmlChar * content)
1882{
1883 int count;
1884 int sum;
1885
1886 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1887 return -1;
1888
1889 sum = 0;
1890 count =
1891 xmlTextWriterStartElementNS(writer, prefix, name, namespaceURI);
1892 if (count < 0)
1893 return -1;
1894 sum += count;
1895 count = xmlTextWriterWriteString(writer, content);
1896 if (count == -1)
1897 return -1;
1898 sum += count;
1899 count = xmlTextWriterEndElement(writer);
1900 if (count == -1)
1901 return -1;
1902 sum += count;
1903
1904 return sum;
1905}
1906
1907/**
1908 * xmlTextWriterStartPI:
1909 * @writer: the xmlTextWriterPtr
1910 * @target: PI target
1911 *
1912 * Start an xml PI.
1913 *
1914 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1915 */
1916int
1917xmlTextWriterStartPI(xmlTextWriterPtr writer, const xmlChar * target)
1918{
1919 int count;
1920 int sum;
1921 xmlLinkPtr lk;
1922 xmlTextWriterStackEntry *p;
1923
1924 if ((writer == NULL) || (target == NULL) || (*target == '\0'))
1925 return -1;
1926
1927 if (xmlStrcasecmp(target, (const xmlChar *) "xml") == 0) {
1928 xmlGenericError(xmlGenericErrorContext,
1929 "xmlTextWriterStartPI : target name [Xx][Mm][Ll] is reserved for xml standardization!\n");
1930 return -1;
1931 }
1932
1933 sum = 0;
1934 lk = xmlListFront(writer->nodes);
1935 if (lk != 0) {
1936 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1937 if (p != 0) {
1938 switch (p->state) {
1939 case XML_TEXTWRITER_ATTRIBUTE:
1940 count = xmlTextWriterEndAttribute(writer);
1941 if (count < 0)
1942 return -1;
1943 sum += count;
1944 /* fallthrough */
1945 case XML_TEXTWRITER_NAME:
1946 count = xmlOutputBufferWriteString(writer->out, ">");
1947 if (count < 0)
1948 return -1;
1949 sum += count;
1950 p->state = XML_TEXTWRITER_TEXT;
1951 break;
1952 case XML_TEXTWRITER_PI:
1953 case XML_TEXTWRITER_PI_TEXT:
1954 xmlGenericError(xmlGenericErrorContext,
1955 "xmlTextWriterStartPI : nested PI!\n");
1956 return -1;
1957 default:
1958 return -1;
1959 }
1960 }
1961 }
1962
1963 p = (xmlTextWriterStackEntry *)
1964 xmlMalloc(sizeof(xmlTextWriterStackEntry));
1965 if (p == 0) {
1966 xmlGenericError(xmlGenericErrorContext,
1967 "xmlTextWriterStartPI : out of memory!\n");
1968 return -1;
1969 }
1970
1971 p->name = xmlStrdup(target);
1972 if (p->name == 0) {
1973 xmlGenericError(xmlGenericErrorContext,
1974 "xmlTextWriterStartPI : out of memory!\n");
1975 xmlFree(p);
1976 return -1;
1977 }
1978 p->state = XML_TEXTWRITER_PI;
1979
1980 xmlListPushFront(writer->nodes, p);
1981
1982 count = xmlOutputBufferWriteString(writer->out, "<?");
1983 if (count < 0)
1984 return -1;
1985 sum += count;
1986 count = xmlOutputBufferWriteString(writer->out, (const char *) p->name);
1987 if (count < 0)
1988 return -1;
1989 sum += count;
1990
1991 return sum;
1992}
1993
1994/**
1995 * xmlTextWriterEndPI:
1996 * @writer: the xmlTextWriterPtr
1997 *
1998 * End the current xml PI.
1999 *
2000 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2001 */
2002int
2003xmlTextWriterEndPI(xmlTextWriterPtr writer)
2004{
2005 int count;
2006 int sum;
2007 xmlLinkPtr lk;
2008 xmlTextWriterStackEntry *p;
2009
2010 if (writer == NULL)
2011 return -1;
2012
2013 lk = xmlListFront(writer->nodes);
2014 if (lk == 0)
2015 return 0;
2016
2017 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2018 if (p == 0)
2019 return 0;
2020
2021 sum = 0;
2022 switch (p->state) {
2023 case XML_TEXTWRITER_PI:
2024 case XML_TEXTWRITER_PI_TEXT:
2025 count = xmlOutputBufferWriteString(writer->out, "?>");
2026 if (count < 0)
2027 return -1;
2028 sum += count;
2029 break;
2030 default:
2031 return -1;
2032 }
2033
2034 xmlListPopFront(writer->nodes);
2035 return sum;
2036}
2037
2038/**
2039 * xmlTextWriterWriteFormatPI:
2040 * @writer: the xmlTextWriterPtr
2041 * @target: PI target
2042 * @format: format string (see printf)
2043 *
2044 * Write a formatted PI.
2045 *
2046 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2047 */
2048int
2049xmlTextWriterWriteFormatPI(xmlTextWriterPtr writer, const xmlChar * target,
2050 const char *format, ...)
2051{
2052 int rc;
2053 va_list ap;
2054
2055 va_start(ap, format);
2056
2057 rc = xmlTextWriterWriteVFormatPI(writer, target, format, ap);
2058
2059 va_end(ap);
2060 return rc;
2061}
2062
2063/**
2064 * xmlTextWriterWriteVFormatPI:
2065 * @writer: the xmlTextWriterPtr
2066 * @target: PI target
2067 * @format: format string (see printf)
2068 *
2069 * Write a formatted xml PI.
2070 *
2071 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2072 */
2073int
2074xmlTextWriterWriteVFormatPI(xmlTextWriterPtr writer,
2075 const xmlChar * target, const char *format,
2076 va_list argptr)
2077{
2078 int rc;
2079 xmlChar *buf;
2080
2081 if (writer == NULL)
2082 return -1;
2083
2084 buf = xmlTextWriterVSprintf(format, argptr);
2085 if (buf == 0)
2086 return 0;
2087
2088 rc = xmlTextWriterWritePI(writer, target, buf);
2089
2090 xmlFree(buf);
2091 return rc;
2092}
2093
2094/**
2095 * xmlTextWriterWritePI:
2096 * @writer: the xmlTextWriterPtr
2097 * @target: PI target
2098 * @content: PI content
2099 *
2100 * Write an xml PI.
2101 *
2102 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2103 */
2104int
2105xmlTextWriterWritePI(xmlTextWriterPtr writer, const xmlChar * target,
2106 const xmlChar * content)
2107{
2108 int count;
2109 int sum;
2110
2111 sum = 0;
2112 count = xmlTextWriterStartPI(writer, target);
2113 if (count == -1)
2114 return -1;
2115 sum += count;
2116 if (content != 0) {
2117 count = xmlTextWriterWriteString(writer, content);
2118 if (count == -1)
2119 return -1;
2120 sum += count;
2121 }
2122 count = xmlTextWriterEndPI(writer);
2123 if (count == -1)
2124 return -1;
2125 sum += count;
2126
2127 return sum;
2128}
2129
2130/**
2131 * xmlTextWriterStartCDATA:
2132 * @writer: the xmlTextWriterPtr
2133 *
2134 * Start an xml CDATA section.
2135 *
2136 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2137 */
2138int
2139xmlTextWriterStartCDATA(xmlTextWriterPtr writer)
2140{
2141 int count;
2142 int sum;
2143 xmlLinkPtr lk;
2144 xmlTextWriterStackEntry *p;
2145
2146 if (writer == NULL)
2147 return -1;
2148
2149 sum = 0;
2150 lk = xmlListFront(writer->nodes);
2151 if (lk != 0) {
2152 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2153 if (p != 0) {
2154 switch (p->state) {
2155 case XML_TEXTWRITER_NONE:
2156 case XML_TEXTWRITER_PI:
2157 case XML_TEXTWRITER_PI_TEXT:
2158 break;
2159 case XML_TEXTWRITER_ATTRIBUTE:
2160 count = xmlTextWriterEndAttribute(writer);
2161 if (count < 0)
2162 return -1;
2163 sum += count;
2164 /* fallthrough */
2165 case XML_TEXTWRITER_NAME:
2166 count = xmlOutputBufferWriteString(writer->out, ">");
2167 if (count < 0)
2168 return -1;
2169 sum += count;
2170 p->state = XML_TEXTWRITER_TEXT;
2171 break;
2172 case XML_TEXTWRITER_CDATA:
2173 xmlGenericError(xmlGenericErrorContext,
2174 "xmlTextWriterStartCDATA : CDATA not allowed in this context!\n");
2175 return -1;
2176 default:
2177 return -1;
2178 }
2179 }
2180 }
2181
2182 p = (xmlTextWriterStackEntry *)
2183 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2184 if (p == 0) {
2185 xmlGenericError(xmlGenericErrorContext,
2186 "xmlTextWriterStartCDATA : out of memory!\n");
2187 return -1;
2188 }
2189
2190 p->name = 0;
2191 p->state = XML_TEXTWRITER_CDATA;
2192
2193 xmlListPushFront(writer->nodes, p);
2194
2195 count = xmlOutputBufferWriteString(writer->out, "<![CDATA[");
2196 if (count < 0)
2197 return -1;
2198 sum += count;
2199
2200 return sum;
2201}
2202
2203/**
2204 * xmlTextWriterEndCDATA:
2205 * @writer: the xmlTextWriterPtr
2206 *
2207 * End an xml CDATA section.
2208 *
2209 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2210 */
2211int
2212xmlTextWriterEndCDATA(xmlTextWriterPtr writer)
2213{
2214 int count;
2215 int sum;
2216 xmlLinkPtr lk;
2217 xmlTextWriterStackEntry *p;
2218
2219 if (writer == NULL)
2220 return -1;
2221
2222 lk = xmlListFront(writer->nodes);
2223 if (lk == 0)
2224 return -1;
2225
2226 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2227 if (p == 0)
2228 return -1;
2229
2230 sum = 0;
2231 switch (p->state) {
2232 case XML_TEXTWRITER_CDATA:
2233 count = xmlOutputBufferWriteString(writer->out, "]]>");
2234 if (count < 0)
2235 return -1;
2236 sum += count;
2237 break;
2238 default:
2239 return -1;
2240 }
2241
2242 xmlListPopFront(writer->nodes);
2243 return sum;
2244}
2245
2246/**
2247 * xmlTextWriterWriteFormatCDATA:
2248 * @writer: the xmlTextWriterPtr
2249 * @format: format string (see printf)
2250 *
2251 * Write a formatted xml CDATA.
2252 *
2253 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2254 */
2255int
2256xmlTextWriterWriteFormatCDATA(xmlTextWriterPtr writer, const char *format,
2257 ...)
2258{
2259 int rc;
2260 va_list ap;
2261
2262 va_start(ap, format);
2263
2264 rc = xmlTextWriterWriteVFormatCDATA(writer, format, ap);
2265
2266 va_end(ap);
2267 return rc;
2268}
2269
2270/**
2271 * xmlTextWriterWriteVFormatCDATA:
2272 * @writer: the xmlTextWriterPtr
2273 * @format: format string (see printf)
2274 *
2275 * Write a formatted xml CDATA.
2276 *
2277 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2278 */
2279int
2280xmlTextWriterWriteVFormatCDATA(xmlTextWriterPtr writer, const char *format,
2281 va_list argptr)
2282{
2283 int rc;
2284 xmlChar *buf;
2285
2286 if (writer == NULL)
2287 return -1;
2288
2289 buf = xmlTextWriterVSprintf(format, argptr);
2290 if (buf == 0)
2291 return 0;
2292
2293 rc = xmlTextWriterWriteCDATA(writer, buf);
2294
2295 xmlFree(buf);
2296 return rc;
2297}
2298
2299/**
2300 * xmlTextWriterWriteCDATA:
2301 * @writer: the xmlTextWriterPtr
2302 * @content: CDATA content
2303 *
2304 * Write an xml CDATA.
2305 *
2306 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2307 */
2308int
2309xmlTextWriterWriteCDATA(xmlTextWriterPtr writer, const xmlChar * content)
2310{
2311 int count;
2312 int sum;
2313
2314 sum = 0;
2315 count = xmlTextWriterStartCDATA(writer);
2316 if (count == -1)
2317 return -1;
2318 sum += count;
2319 if (content != 0) {
2320 count = xmlTextWriterWriteString(writer, content);
2321 if (count == -1)
2322 return -1;
2323 sum += count;
2324 }
2325 count = xmlTextWriterEndCDATA(writer);
2326 if (count == -1)
2327 return -1;
2328 sum += count;
2329
2330 return sum;
2331}
2332
2333/**
2334 * xmlTextWriterStartDTD:
2335 * @writer: the xmlTextWriterPtr
2336 * @name: the name of the DTD
2337 * @pubid: the public identifier, which is an alternative to the system identifier
2338 * @sysid: the system identifier, which is the URI of the DTD
2339 *
2340 * Start an xml DTD.
2341 *
2342 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2343 */
2344int
2345xmlTextWriterStartDTD(xmlTextWriterPtr writer,
2346 const xmlChar * name,
2347 const xmlChar * pubid, const xmlChar * sysid)
2348{
2349 int count;
2350 int sum;
2351 xmlLinkPtr lk;
2352 xmlTextWriterStackEntry *p;
2353
2354 if (writer == NULL || name == NULL || *name == '\0')
2355 return -1;
2356
2357 sum = 0;
2358 lk = xmlListFront(writer->nodes);
2359 if (lk != 0) {
2360 xmlGenericError(xmlGenericErrorContext,
2361 "xmlTextWriterStartDTD : DTD allowed only in prolog!\n");
2362 return -1;
2363 }
2364
2365 p = (xmlTextWriterStackEntry *)
2366 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2367 if (p == 0) {
2368 xmlGenericError(xmlGenericErrorContext,
2369 "xmlTextWriterStartDTD : out of memory!\n");
2370 return -1;
2371 }
2372
2373 p->name = xmlStrdup(name);
2374 if (p->name == 0) {
2375 xmlGenericError(xmlGenericErrorContext,
2376 "xmlTextWriterStartDTD : out of memory!\n");
2377 xmlFree(p);
2378 return -1;
2379 }
2380 p->state = XML_TEXTWRITER_DTD;
2381
2382 xmlListPushFront(writer->nodes, p);
2383
2384 count = xmlOutputBufferWriteString(writer->out, "<!DOCTYPE ");
2385 if (count < 0)
2386 return -1;
2387 sum += count;
2388 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
2389 if (count < 0)
2390 return -1;
2391 sum += count;
2392
2393 if (pubid != 0) {
2394 if (sysid == 0) {
2395 xmlGenericError(xmlGenericErrorContext,
2396 "xmlTextWriterStartDTD : system identifier needed!\n");
2397 return -1;
2398 }
2399
2400 count = xmlOutputBufferWriteString(writer->out, " PUBLIC \"");
2401 if (count < 0)
2402 return -1;
2403 sum += count;
2404
2405 count = xmlOutputBufferWriteString(writer->out, (const char *) pubid);
2406 if (count < 0)
2407 return -1;
2408 sum += count;
2409
2410 count = xmlOutputBufferWriteString(writer->out, "\"");
2411 if (count < 0)
2412 return -1;
2413 sum += count;
2414 }
2415
2416 if (sysid != 0) {
2417 if (pubid == 0) {
2418 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
2419 if (count < 0)
2420 return -1;
2421 sum += count;
2422 }
2423
2424 count = xmlOutputBufferWriteString(writer->out, " \"");
2425 if (count < 0)
2426 return -1;
2427 sum += count;
2428
2429 count = xmlOutputBufferWriteString(writer->out, (const char *) sysid);
2430 if (count < 0)
2431 return -1;
2432 sum += count;
2433
2434 count = xmlOutputBufferWriteString(writer->out, "\"");
2435 if (count < 0)
2436 return -1;
2437 sum += count;
2438 }
2439
2440 return sum;
2441}
2442
2443/**
2444 * xmlTextWriterEndDTD:
2445 * @writer: the xmlTextWriterPtr
2446 *
2447 * End an xml DTD.
2448 *
2449 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2450 */
2451int
2452xmlTextWriterEndDTD(xmlTextWriterPtr writer)
2453{
2454 int count;
2455 int sum;
2456 xmlLinkPtr lk;
2457 xmlTextWriterStackEntry *p;
2458
2459 if (writer == NULL)
2460 return -1;
2461
2462 sum = 0;
2463 lk = xmlListFront(writer->nodes);
2464 if (lk == 0)
2465 return -1;
2466
2467 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2468 if (p == 0)
2469 return -1;
2470
2471 switch (p->state) {
2472 case XML_TEXTWRITER_DTD_TEXT:
2473 count = xmlOutputBufferWriteString(writer->out, "]");
2474 if (count < 0)
2475 return -1;
2476 sum += count;
2477 /* fallthrough */
2478 case XML_TEXTWRITER_DTD:
2479 case XML_TEXTWRITER_DTD_ELEM:
2480 case XML_TEXTWRITER_DTD_ATTL:
2481 count = xmlOutputBufferWriteString(writer->out, ">");
2482 if (count < 0)
2483 return -1;
2484 sum += count;
2485 break;
2486 default:
2487 return -1;
2488 }
2489
2490 xmlListPopFront(writer->nodes);
2491 return sum;
2492}
2493
2494/**
2495 * xmlTextWriterWriteFormatDTD:
2496 * @writer: the xmlTextWriterPtr
2497 * @name: the name of the DTD
2498 * @pubid: the public identifier, which is an alternative to the system identifier
2499 * @sysid: the system identifier, which is the URI of the DTD
2500 * @format: format string (see printf)
2501 *
2502 * Write a DTD with a formatted markup declarations part.
2503 *
2504 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2505 */
2506int
2507xmlTextWriterWriteFormatDTD(xmlTextWriterPtr writer,
2508 const xmlChar * name,
2509 const xmlChar * pubid,
2510 const xmlChar * sysid, const char *format, ...)
2511{
2512 int rc;
2513 va_list ap;
2514
2515 va_start(ap, format);
2516
2517 rc = xmlTextWriterWriteVFormatDTD(writer, name, pubid, sysid, format,
2518 ap);
2519
2520 va_end(ap);
2521 return rc;
2522}
2523
2524/**
2525 * xmlTextWriterWriteVFormatDTD:
2526 * @writer: the xmlTextWriterPtr
2527 * @name: the name of the DTD
2528 * @pubid: the public identifier, which is an alternative to the system identifier
2529 * @sysid: the system identifier, which is the URI of the DTD
2530 * @format: format string (see printf)
2531 *
2532 * Write a DTD with a formatted markup declarations part.
2533 *
2534 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2535 */
2536int
2537xmlTextWriterWriteVFormatDTD(xmlTextWriterPtr writer,
2538 const xmlChar * name,
2539 const xmlChar * pubid,
2540 const xmlChar * sysid,
2541 const char *format, va_list argptr)
2542{
2543 int rc;
2544 xmlChar *buf;
2545
2546 if (writer == NULL)
2547 return -1;
2548
2549 buf = xmlTextWriterVSprintf(format, argptr);
2550 if (buf == 0)
2551 return 0;
2552
2553 rc = xmlTextWriterWriteDTD(writer, name, pubid, sysid, buf);
2554
2555 xmlFree(buf);
2556 return rc;
2557}
2558
2559/**
2560 * xmlTextWriterWriteDTD:
2561 * @writer: the xmlTextWriterPtr
2562 * @name: the name of the DTD
2563 * @pubid: the public identifier, which is an alternative to the system identifier
2564 * @sysid: the system identifier, which is the URI of the DTD
2565 * @format: format string (see printf)
2566 *
2567 * Write a DTD.
2568 *
2569 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2570 */
2571int
2572xmlTextWriterWriteDTD(xmlTextWriterPtr writer,
2573 const xmlChar * name,
2574 const xmlChar * pubid,
2575 const xmlChar * sysid, const xmlChar * subset)
2576{
2577 int count;
2578 int sum;
2579
2580 sum = 0;
2581 count = xmlTextWriterStartDTD(writer, name, pubid, sysid);
2582 if (count == -1)
2583 return -1;
2584 sum += count;
2585 if (subset != 0) {
2586 count = xmlTextWriterWriteString(writer, subset);
2587 if (count == -1)
2588 return -1;
2589 sum += count;
2590 }
2591 count = xmlTextWriterEndDTD(writer);
2592 if (count == -1)
2593 return -1;
2594 sum += count;
2595
2596 return sum;
2597}
2598
2599int
2600xmlTextWriterStartDTDElement(xmlTextWriterPtr writer, const xmlChar * name)
2601{
2602 int count;
2603 int sum;
2604 xmlLinkPtr lk;
2605 xmlTextWriterStackEntry *p;
2606
2607 if (writer == NULL || name == NULL || *name == '\0')
2608 return -1;
2609
2610 sum = 0;
2611 lk = xmlListFront(writer->nodes);
2612 if (lk == 0) {
2613 return -1;
2614 }
2615
2616 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2617 if (p == 0)
2618 return -1;
2619
2620 switch (p->state) {
2621 case XML_TEXTWRITER_DTD:
2622 count = xmlOutputBufferWriteString(writer->out, " [");
2623 if (count < 0)
2624 return -1;
2625 sum += count;
2626 p->state = XML_TEXTWRITER_DTD_TEXT;
2627 /* fallthrough */
2628 case XML_TEXTWRITER_DTD_TEXT:
2629 break;
2630 case XML_TEXTWRITER_DTD_ELEM:
2631 count = xmlTextWriterEndDTDElement(writer);
2632 if (count < 0)
2633 return -1;
2634 sum += count;
2635 break;
2636 default:
2637 return -1;
2638 }
2639
2640 p = (xmlTextWriterStackEntry *)
2641 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2642 if (p == 0) {
2643 xmlGenericError(xmlGenericErrorContext,
2644 "xmlTextWriterStartDTDElement : out of memory!\n");
2645 return -1;
2646 }
2647
2648 p->name = xmlStrdup(name);
2649 if (p->name == 0) {
2650 xmlGenericError(xmlGenericErrorContext,
2651 "xmlTextWriterStartDTDElement : out of memory!\n");
2652 xmlFree(p);
2653 return -1;
2654 }
2655 p->state = XML_TEXTWRITER_DTD_ELEM;
2656
2657 xmlListPushFront(writer->nodes, p);
2658
2659 count = xmlOutputBufferWriteString(writer->out, "<!ELEMENT ");
2660 if (count < 0)
2661 return -1;
2662 sum += count;
2663 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
2664 if (count < 0)
2665 return -1;
2666 sum += count;
2667
2668 return sum;
2669}
2670
2671int
2672xmlTextWriterWriteFormatDTDElement(xmlTextWriterPtr writer,
2673 const xmlChar * name,
2674 const char *format, ...)
2675{
2676 int rc;
2677 va_list ap;
2678
2679 va_start(ap, format);
2680
2681 rc = xmlTextWriterWriteVFormatDTDElement(writer, name, format, ap);
2682
2683 va_end(ap);
2684 return rc;
2685}
2686
2687int
2688xmlTextWriterWriteVFormatDTDElement(xmlTextWriterPtr writer,
2689 const xmlChar * name,
2690 const char *format, va_list argptr)
2691{
2692 int rc;
2693 xmlChar *buf;
2694
2695 if (writer == NULL)
2696 return -1;
2697
2698 buf = xmlTextWriterVSprintf(format, argptr);
2699 if (buf == 0)
2700 return 0;
2701
2702 rc = xmlTextWriterWriteDTDElement(writer, name, buf);
2703
2704 xmlFree(buf);
2705 return rc;
2706}
2707
2708int
2709xmlTextWriterWriteDTDElement(xmlTextWriterPtr writer,
2710 const xmlChar * name, const xmlChar * content)
2711{
2712 int count;
2713 int sum;
2714
2715 if (content == NULL)
2716 return -1;
2717
2718 sum = 0;
2719 count = xmlTextWriterStartDTDElement(writer, name);
2720 if (count == -1)
2721 return -1;
2722 sum += count;
2723
2724 count = xmlTextWriterWriteString(writer, BAD_CAST " ");
2725 if (count == -1)
2726 return -1;
2727 sum += count;
2728 count = xmlTextWriterWriteString(writer, content);
2729 if (count == -1)
2730 return -1;
2731 sum += count;
2732
2733 count = xmlTextWriterEndDTDElement(writer);
2734 if (count == -1)
2735 return -1;
2736 sum += count;
2737
2738 return sum;
2739}
2740
2741int
2742xmlTextWriterStartDTDAttlist(xmlTextWriterPtr writer, const xmlChar * name)
2743{
2744 int count;
2745 int sum;
2746 xmlLinkPtr lk;
2747 xmlTextWriterStackEntry *p;
2748
2749 if (writer == NULL || name == NULL || *name == '\0')
2750 return -1;
2751
2752 sum = 0;
2753 lk = xmlListFront(writer->nodes);
2754 if (lk == 0) {
2755 return -1;
2756 }
2757
2758 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2759 if (p == 0)
2760 return -1;
2761
2762 switch (p->state) {
2763 case XML_TEXTWRITER_DTD:
2764 count = xmlOutputBufferWriteString(writer->out, " [");
2765 if (count < 0)
2766 return -1;
2767 sum += count;
2768 p->state = XML_TEXTWRITER_DTD_TEXT;
2769 /* fallthrough */
2770 case XML_TEXTWRITER_DTD_TEXT:
2771 break;
2772 case XML_TEXTWRITER_DTD_ELEM:
2773 case XML_TEXTWRITER_DTD_ATTL:
2774 case XML_TEXTWRITER_DTD_ENTY:
2775 count = xmlTextWriterEndDTD(writer);
2776 if (count < 0)
2777 return -1;
2778 sum += count;
2779 break;
2780 default:
2781 return -1;
2782 }
2783
2784 p = (xmlTextWriterStackEntry *)
2785 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2786 if (p == 0) {
2787 xmlGenericError(xmlGenericErrorContext,
2788 "xmlTextWriterStartDTDAttlist : out of memory!\n");
2789 return -1;
2790 }
2791
2792 p->name = xmlStrdup(name);
2793 if (p->name == 0) {
2794 xmlGenericError(xmlGenericErrorContext,
2795 "xmlTextWriterStartDTDAttlist : out of memory!\n");
2796 xmlFree(p);
2797 return -1;
2798 }
2799 p->state = XML_TEXTWRITER_DTD_ATTL;
2800
2801 xmlListPushFront(writer->nodes, p);
2802
2803 count = xmlOutputBufferWriteString(writer->out, "<!ATTLIST ");
2804 if (count < 0)
2805 return -1;
2806 sum += count;
2807 count = xmlOutputBufferWriteString(writer->out, (const char *)name);
2808 if (count < 0)
2809 return -1;
2810 sum += count;
2811
2812 return sum;
2813}
2814
2815int
2816xmlTextWriterWriteFormatDTDAttlist(xmlTextWriterPtr writer,
2817 const xmlChar * name,
2818 const char *format, ...)
2819{
2820 int rc;
2821 va_list ap;
2822
2823 va_start(ap, format);
2824
2825 rc = xmlTextWriterWriteVFormatDTDAttlist(writer, name, format, ap);
2826
2827 va_end(ap);
2828 return rc;
2829}
2830
2831int
2832xmlTextWriterWriteVFormatDTDAttlist(xmlTextWriterPtr writer,
2833 const xmlChar * name,
2834 const char *format, va_list argptr)
2835{
2836 int rc;
2837 xmlChar *buf;
2838
2839 if (writer == NULL)
2840 return -1;
2841
2842 buf = xmlTextWriterVSprintf(format, argptr);
2843 if (buf == 0)
2844 return 0;
2845
2846 rc = xmlTextWriterWriteDTDAttlist(writer, name, buf);
2847
2848 xmlFree(buf);
2849 return rc;
2850}
2851
2852int
2853xmlTextWriterWriteDTDAttlist(xmlTextWriterPtr writer,
2854 const xmlChar * name, const xmlChar * content)
2855{
2856 int count;
2857 int sum;
2858
2859 if (content == NULL)
2860 return -1;
2861
2862 sum = 0;
2863 count = xmlTextWriterStartDTDAttlist(writer, name);
2864 if (count == -1)
2865 return -1;
2866 sum += count;
2867
2868 count = xmlTextWriterWriteString(writer, BAD_CAST " ");
2869 if (count == -1)
2870 return -1;
2871 sum += count;
2872 count = xmlTextWriterWriteString(writer, content);
2873 if (count == -1)
2874 return -1;
2875 sum += count;
2876
2877 count = xmlTextWriterEndDTDAttlist(writer);
2878 if (count == -1)
2879 return -1;
2880 sum += count;
2881
2882 return sum;
2883}
2884
2885int
2886xmlTextWriterStartDTDEntity(xmlTextWriterPtr writer,
2887 int pe, const xmlChar * name)
2888{
2889 int count;
2890 int sum;
2891 xmlLinkPtr lk;
2892 xmlTextWriterStackEntry *p;
2893
2894 if (writer == NULL || name == NULL || *name == '\0')
2895 return -1;
2896
2897 sum = 0;
2898 lk = xmlListFront(writer->nodes);
2899 if (lk == 0) {
2900 return -1;
2901 }
2902
2903 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2904 if (p == 0)
2905 return -1;
2906
2907 switch (p->state) {
2908 case XML_TEXTWRITER_DTD:
2909 count = xmlOutputBufferWriteString(writer->out, " [");
2910 if (count < 0)
2911 return -1;
2912 sum += count;
2913 p->state = XML_TEXTWRITER_DTD_TEXT;
2914 /* fallthrough */
2915 case XML_TEXTWRITER_DTD_TEXT:
2916 break;
2917 case XML_TEXTWRITER_DTD_ELEM:
2918 case XML_TEXTWRITER_DTD_ATTL:
2919 case XML_TEXTWRITER_DTD_ENTY:
2920 count = xmlTextWriterEndDTD(writer);
2921 if (count < 0)
2922 return -1;
2923 sum += count;
2924 break;
2925 default:
2926 return -1;
2927 }
2928
2929 p = (xmlTextWriterStackEntry *)
2930 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2931 if (p == 0) {
2932 xmlGenericError(xmlGenericErrorContext,
2933 "xmlTextWriterStartDTDElement : out of memory!\n");
2934 return -1;
2935 }
2936
2937 p->name = xmlStrdup(name);
2938 if (p->name == 0) {
2939 xmlGenericError(xmlGenericErrorContext,
2940 "xmlTextWriterStartDTDElement : out of memory!\n");
2941 xmlFree(p);
2942 return -1;
2943 }
2944 p->state = XML_TEXTWRITER_DTD_ENTY;
2945
2946 xmlListPushFront(writer->nodes, p);
2947
2948 count = xmlOutputBufferWriteString(writer->out, "<!ENTITY ");
2949 if (count < 0)
2950 return -1;
2951 sum += count;
2952
2953 if (pe != 0) {
2954 count = xmlOutputBufferWriteString(writer->out, " % ");
2955 if (count < 0)
2956 return -1;
2957 sum += count;
2958 }
2959
2960 count = xmlOutputBufferWriteString(writer->out, (const char *)name);
2961 if (count < 0)
2962 return -1;
2963 sum += count;
2964
2965 return sum;
2966}
2967
2968int
2969xmlTextWriterWriteFormatDTDInternalEntity(xmlTextWriterPtr writer,
2970 int pe,
2971 const xmlChar * name,
2972 const char *format, ...)
2973{
2974 int rc;
2975 va_list ap;
2976
2977 va_start(ap, format);
2978
2979 rc = xmlTextWriterWriteVFormatDTDInternalEntity(writer, pe, name,
2980 format, ap);
2981
2982 va_end(ap);
2983 return rc;
2984}
2985
2986int
2987xmlTextWriterWriteVFormatDTDInternalEntity(xmlTextWriterPtr writer,
2988 int pe,
2989 const xmlChar * name,
2990 const char *format,
2991 va_list argptr)
2992{
2993 int rc;
2994 xmlChar *buf;
2995
2996 if (writer == NULL)
2997 return -1;
2998
2999 buf = xmlTextWriterVSprintf(format, argptr);
3000 if (buf == 0)
3001 return 0;
3002
3003 rc = xmlTextWriterWriteDTDInternalEntity(writer, pe, name, buf);
3004
3005 xmlFree(buf);
3006 return rc;
3007}
3008
3009int
3010xmlTextWriterWriteDTDEntity(xmlTextWriterPtr writer,
3011 int pe,
3012 const xmlChar * name,
3013 const xmlChar * pubid,
3014 const xmlChar * sysid,
3015 const xmlChar * ndataid,
3016 const xmlChar * content)
3017{
3018 if (((content == NULL) && (pubid == NULL) && (sysid == NULL))
3019 || ((content != NULL) && ((pubid != NULL) || (sysid != NULL))))
3020 return -1;
3021 if ((pe != 0) && (ndataid != NULL))
3022 return -1;
3023
3024 if (content != 0)
3025 return xmlTextWriterWriteDTDInternalEntity(writer, pe, name,
3026 content);
3027
3028 return xmlTextWriterWriteDTDExternalEntity(writer, pe, name, pubid,
3029 sysid, ndataid);
3030}
3031
3032int
3033xmlTextWriterWriteDTDInternalEntity(xmlTextWriterPtr writer,
3034 int pe,
3035 const xmlChar * name,
3036 const xmlChar * content)
3037{
3038 int count;
3039 int sum;
3040
3041 if ((name == NULL) || (*name == '\0') || (content == NULL))
3042 return -1;
3043
3044 sum = 0;
3045 count = xmlTextWriterStartDTDEntity(writer, pe, name);
3046 if (count == -1)
3047 return -1;
3048 sum += count;
3049
3050 count = xmlTextWriterWriteString(writer, BAD_CAST " ");
3051 if (count == -1)
3052 return -1;
3053 sum += count;
3054 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3055 if (count < 0)
3056 return -1;
3057 sum += count;
3058 count = xmlTextWriterWriteString(writer, content);
3059 if (count == -1)
3060 return -1;
3061 sum += count;
3062 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3063 if (count < 0)
3064 return -1;
3065 sum += count;
3066
3067 count = xmlTextWriterEndDTDEntity(writer);
3068 if (count == -1)
3069 return -1;
3070 sum += count;
3071
3072 return sum;
3073}
3074
3075int
3076xmlTextWriterWriteDTDExternalEntity(xmlTextWriterPtr writer,
3077 int pe,
3078 const xmlChar * name,
3079 const xmlChar * pubid,
3080 const xmlChar * sysid,
3081 const xmlChar * ndataid)
3082{
3083 int count;
3084 int sum;
3085
3086 if ((name == NULL) || (*name == '\0')
3087 || ((pubid == NULL) && (sysid == NULL)))
3088 return -1;
3089 if ((pe != 0) && (ndataid != NULL))
3090 return -1;
3091
3092 sum = 0;
3093 count = xmlTextWriterStartDTDEntity(writer, pe, name);
3094 if (count == -1)
3095 return -1;
3096 sum += count;
3097
3098 if (pubid != 0) {
3099 if (sysid == 0) {
3100 xmlGenericError(xmlGenericErrorContext,
3101 "xmlTextWriterWriteDTDEntity : system identifier needed!\n");
3102 return -1;
3103 }
3104
3105 count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
3106 if (count < 0)
3107 return -1;
3108 sum += count;
3109
3110 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3111 if (count < 0)
3112 return -1;
3113 sum += count;
3114
3115 count = xmlOutputBufferWriteString(writer->out, (const char *) pubid);
3116 if (count < 0)
3117 return -1;
3118 sum += count;
3119
3120 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3121 if (count < 0)
3122 return -1;
3123 sum += count;
3124 }
3125
3126 if (sysid != 0) {
3127 if (pubid == 0) {
3128 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
3129 if (count < 0)
3130 return -1;
3131 sum += count;
3132 }
3133
3134 count = xmlOutputBufferWriteString(writer->out, " ");
3135 if (count < 0)
3136 return -1;
3137 sum += count;
3138
3139 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3140 if (count < 0)
3141 return -1;
3142 sum += count;
3143
3144 count = xmlOutputBufferWriteString(writer->out, (const char *) sysid);
3145 if (count < 0)
3146 return -1;
3147 sum += count;
3148
3149 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3150 if (count < 0)
3151 return -1;
3152 sum += count;
3153 }
3154
3155 if (ndataid != NULL) {
3156 count = xmlOutputBufferWriteString(writer->out, " NDATA ");
3157 if (count < 0)
3158 return -1;
3159 sum += count;
3160
3161 count = xmlOutputBufferWriteString(writer->out, (const char *) ndataid);
3162 if (count < 0)
3163 return -1;
3164 sum += count;
3165 }
3166
3167 count = xmlTextWriterEndDTDEntity(writer);
3168 if (count == -1)
3169 return -1;
3170 sum += count;
3171
3172 return sum;
3173}
3174
3175int
3176xmlTextWriterWriteDTDNotation(xmlTextWriterPtr writer,
3177 const xmlChar * name,
3178 const xmlChar * pubid, const xmlChar * sysid)
3179{
3180 int count;
3181 int sum;
3182 xmlLinkPtr lk;
3183 xmlTextWriterStackEntry *p;
3184
3185 if (writer == NULL || name == NULL || *name == '\0')
3186 return -1;
3187
3188 sum = 0;
3189 lk = xmlListFront(writer->nodes);
3190 if (lk == 0) {
3191 return -1;
3192 }
3193
3194 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3195 if (p == 0)
3196 return -1;
3197
3198 switch (p->state) {
3199 case XML_TEXTWRITER_DTD:
3200 count = xmlOutputBufferWriteString(writer->out, " [");
3201 if (count < 0)
3202 return -1;
3203 sum += count;
3204 p->state = XML_TEXTWRITER_DTD_TEXT;
3205 /* fallthrough */
3206 case XML_TEXTWRITER_DTD_TEXT:
3207 break;
3208 case XML_TEXTWRITER_DTD_ELEM:
3209 case XML_TEXTWRITER_DTD_ATTL:
3210 case XML_TEXTWRITER_DTD_ENTY:
3211 count = xmlTextWriterEndDTD(writer);
3212 if (count < 0)
3213 return -1;
3214 sum += count;
3215 break;
3216 default:
3217 return -1;
3218 }
3219
3220 count = xmlOutputBufferWriteString(writer->out, "<!NOTATION ");
3221 if (count < 0)
3222 return -1;
3223 sum += count;
3224 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
3225 if (count < 0)
3226 return -1;
3227 sum += count;
3228
3229 if (pubid != 0) {
3230 count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
3231 if (count < 0)
3232 return -1;
3233 sum += count;
3234 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3235 if (count < 0)
3236 return -1;
3237 sum += count;
3238 count = xmlOutputBufferWriteString(writer->out, (const char *) pubid);
3239 if (count < 0)
3240 return -1;
3241 sum += count;
3242 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3243 if (count < 0)
3244 return -1;
3245 sum += count;
3246 }
3247
3248 if (sysid != 0) {
3249 if (pubid == 0) {
3250 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
3251 if (count < 0)
3252 return -1;
3253 sum += count;
3254 }
3255 count = xmlOutputBufferWriteString(writer->out, " ");
3256 if (count < 0)
3257 return -1;
3258 sum += count;
3259 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3260 if (count < 0)
3261 return -1;
3262 sum += count;
3263 count = xmlOutputBufferWriteString(writer->out, (const char *) sysid);
3264 if (count < 0)
3265 return -1;
3266 sum += count;
3267 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3268 if (count < 0)
3269 return -1;
3270 sum += count;
3271 }
3272
3273 count = xmlOutputBufferWriteString(writer->out, ">");
3274 if (count < 0)
3275 return -1;
3276 sum += count;
3277
3278 return sum;
3279}
3280
3281/**
3282 * xmlTextWriterFlush:
3283 * @writer: the xmlTextWriterPtr
3284 *
3285 * Flush the output buffer.
3286 *
3287 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3288 */
3289int
3290xmlTextWriterFlush(xmlTextWriterPtr writer)
3291{
3292 int count;
3293
3294 if (writer == NULL)
3295 return -1;
3296
3297 if (writer->out == NULL)
3298 count = 0;
3299 else
3300 count = xmlOutputBufferFlush(writer->out);
3301
3302 return count;
3303}
3304
3305/**
3306 * misc
3307 */
3308
3309/**
3310 * xmlFreeTextWriterStackEntry:
3311 * @lk: the xmlLinkPtr
3312 *
3313 * Free callback for the xmlList.
3314 */
3315static void
3316xmlFreeTextWriterStackEntry(xmlLinkPtr lk)
3317{
3318 xmlTextWriterStackEntry *p;
3319
3320 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3321 if (p == 0)
3322 return;
3323
3324 if (p->name != 0)
3325 xmlFree(p->name);
3326 xmlFree(p);
3327}
3328
3329/**
3330 * xmlCmpTextWriterStackEntry:
3331 * @data0: the first data
3332 * @data1: the second data
3333 *
3334 * Compare callback for the xmlList.
3335 *
3336 * Returns -1, 0, 1
3337 */
3338static int
3339xmlCmpTextWriterStackEntry(const void *data0, const void *data1)
3340{
3341 xmlTextWriterStackEntry *p0;
3342 xmlTextWriterStackEntry *p1;
3343
3344 if (data0 == data1)
3345 return 0;
3346
3347 if (data0 == 0)
3348 return -1;
3349
3350 if (data1 == 0)
3351 return 1;
3352
3353 p0 = (xmlTextWriterStackEntry *) data0;
3354 p1 = (xmlTextWriterStackEntry *) data1;
3355
3356 return xmlStrcmp(p0->name, p1->name);
3357}
3358
3359/**
3360 * misc
3361 */
3362
3363/**
3364 * xmlFreeTextWriterNsStackEntry:
3365 * @lk: the xmlLinkPtr
3366 *
3367 * Free callback for the xmlList.
3368 */
3369static void
3370xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk)
3371{
3372 xmlTextWriterNsStackEntry *p;
3373
3374 p = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
3375 if (p == 0)
3376 return;
3377
3378 if (p->prefix != 0)
3379 xmlFree(p->prefix);
3380 if (p->uri != 0)
3381 xmlFree(p->uri);
3382
3383 xmlFree(p);
3384}
3385
3386/**
3387 * xmlCmpTextWriterNsStackEntry:
3388 * @data0: the first data
3389 * @data1: the second data
3390 *
3391 * Compare callback for the xmlList.
3392 *
3393 * Returns -1, 0, 1
3394 */
3395static int
3396xmlCmpTextWriterNsStackEntry(const void *data0, const void *data1)
3397{
3398 xmlTextWriterNsStackEntry *p0;
3399 xmlTextWriterNsStackEntry *p1;
3400 int rc;
3401
3402 if (data0 == data1)
3403 return 0;
3404
3405 if (data0 == 0)
3406 return -1;
3407
3408 if (data1 == 0)
3409 return 1;
3410
3411 p0 = (xmlTextWriterNsStackEntry *) data0;
3412 p1 = (xmlTextWriterNsStackEntry *) data1;
3413
3414 rc = xmlStrcmp(p0->prefix, p1->prefix);
3415
3416 if (rc == 0)
3417 rc = p0->elem == p1->elem;
3418
3419 return rc;
3420}
3421
3422/**
3423 * xmlTextWriterWriteMemCallback:
3424 * @context: the xmlBufferPtr
3425 * @str: the data to write
3426 * @len: the length of the data
3427 *
3428 * Write callback for the xmlOutputBuffer with target xmlBuffer
3429 *
3430 * Returns -1, 0, 1
3431 */
3432static int
3433xmlTextWriterWriteMemCallback(void *context, const xmlChar * str, int len)
3434{
3435 xmlBufferPtr buf = (xmlBufferPtr) context;
3436
3437 xmlBufferAdd(buf, str, len);
3438
3439 return len;
3440}
3441
3442/**
3443 * xmlTextWriterCloseMemCallback:
3444 * @context: the xmlBufferPtr
3445 *
3446 * Close callback for the xmlOutputBuffer with target xmlBuffer
3447 *
3448 * Returns -1, 0, 1
3449 */
3450static int
3451xmlTextWriterCloseMemCallback(void *context ATTRIBUTE_UNUSED)
3452{
3453 return 0;
3454}
3455
3456/**
3457 * xmlTextWriterVSprintf:
3458 * @format: see printf
3459 * @argptr: pointer to the first member of the variable argument list.
3460 *
3461 * Utility function for formatted output
3462 *
3463 * Returns a new xmlChar buffer with the data or NULL on error. This buffer must be freed.
3464 */
3465static xmlChar *
3466xmlTextWriterVSprintf(const char *format, va_list argptr)
3467{
3468 int size;
3469 int count;
3470 xmlChar *buf;
3471
3472 size = BUFSIZ;
3473 buf = (xmlChar *) xmlMalloc(size);
3474 if (buf == NULL) {
3475 xmlGenericError(xmlGenericErrorContext,
3476 "xmlTextWriterVSprintf : out of memory!\n");
3477 return NULL;
3478 }
3479
3480 while (((count = vsnprintf((char *) buf, size, format, argptr)) < 0)
3481 || (count == size - 1) || (count == size) || (count > size)) {
3482 xmlFree(buf);
3483 size += BUFSIZ;
3484 buf = (xmlChar *) xmlMalloc(size);
3485 if (buf == NULL) {
3486 xmlGenericError(xmlGenericErrorContext,
3487 "xmlTextWriterVSprintf : out of memory!\n");
3488 return NULL;
3489 }
3490 }
3491
3492 return buf;
3493}
3494
3495#endif