blob: 21897ee258c05facd3252fefbc38c78590b65561 [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 }
Daniel Veillard929714b2003-10-22 12:34:36 +00001120
1121 if (i >= len)
1122 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001123 }
1124
1125 count = xmlOutputBufferWrite(out, 2, B64CRLF);
1126 if (count == -1)
1127 return -1;
1128 sum += count;
1129
1130 return sum;
1131}
1132
1133/**
1134 * xmlTextWriterWriteBase64:
1135 * @writer: the xmlTextWriterPtr
1136 * @data: binary data
1137 * @start: the position within the data of the first byte to encode
1138 * @len: the number of bytes to encode
1139 *
1140 * Write an base64 encoded xml text.
1141 *
1142 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1143 */
1144int
1145xmlTextWriterWriteBase64(xmlTextWriterPtr writer, const char * data,
1146 int start, int len)
1147{
1148 int count;
1149 int sum;
1150 xmlLinkPtr lk;
1151 xmlTextWriterStackEntry *p;
1152
1153 if (writer == NULL)
1154 return -1;
1155
1156 lk = xmlListFront(writer->nodes);
1157 if (lk == 0)
1158 return 0;
1159
1160 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1161 if (p == 0)
1162 return 0;
1163
1164 sum = 0;
1165 switch (p->state) {
1166 case XML_TEXTWRITER_NONE:
1167 return -1;
1168 case XML_TEXTWRITER_NAME:
1169 count = xmlOutputBufferWriteString(writer->out, ">");
1170 if (count < 0)
1171 return -1;
1172 sum += count;
1173 p->state = XML_TEXTWRITER_TEXT;
1174 break;
1175 case XML_TEXTWRITER_PI:
1176 count = xmlOutputBufferWriteString(writer->out, " ");
1177 if (count < 0)
1178 return -1;
1179 sum += count;
1180 p->state = XML_TEXTWRITER_PI_TEXT;
1181 break;
1182 case XML_TEXTWRITER_DTD:
1183 count = xmlOutputBufferWriteString(writer->out, " [");
1184 if (count < 0)
1185 return -1;
1186 sum += count;
1187 p->state = XML_TEXTWRITER_DTD_TEXT;
1188 break;
1189 default:
1190 break;
1191 }
1192
1193 count =
1194 xmlOutputBufferWriteBase64(writer->out, len,
1195 (unsigned char *) data + start);
1196 if (count < 0)
1197 return -1;
1198 sum += count;
1199
1200 return sum;
1201}
1202
1203/**
1204 * xmlOutputBufferWriteBinHex:
1205 * @out: the xmlOutputBufferPtr
1206 * @data: binary data
1207 * @len: the number of bytes to encode
1208 *
1209 * Write hqx encoded data to an xmlOutputBuffer.
1210 * ::todo
1211 *
1212 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1213 */
1214static int
1215xmlOutputBufferWriteBinHex(xmlOutputBufferPtr out ATTRIBUTE_UNUSED,
1216 int len ATTRIBUTE_UNUSED,
1217 const unsigned char *data ATTRIBUTE_UNUSED)
1218{
1219 return -1;
1220}
1221
1222/**
1223 * xmlTextWriterWriteBinHex:
1224 * @writer: the xmlTextWriterPtr
1225 * @data: binary data
1226 * @start: the position within the data of the first byte to encode
1227 * @len: the number of bytes to encode
1228 *
1229 * Write a BinHex encoded xml text.
1230 *
1231 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1232 */
1233int
1234xmlTextWriterWriteBinHex(xmlTextWriterPtr writer, const char * data,
1235 int start, int len)
1236{
1237 int count;
1238 int sum;
1239 xmlLinkPtr lk;
1240 xmlTextWriterStackEntry *p;
1241
1242 if (writer == NULL)
1243 return -1;
1244
1245 lk = xmlListFront(writer->nodes);
1246 if (lk == 0)
1247 return 0;
1248
1249 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1250 if (p == 0)
1251 return 0;
1252
1253 sum = 0;
1254 switch (p->state) {
1255 case XML_TEXTWRITER_NONE:
1256 return -1;
1257 case XML_TEXTWRITER_NAME:
1258 count = xmlOutputBufferWriteString(writer->out, ">");
1259 if (count < 0)
1260 return -1;
1261 sum += count;
1262 p->state = XML_TEXTWRITER_TEXT;
1263 break;
1264 case XML_TEXTWRITER_PI:
1265 count = xmlOutputBufferWriteString(writer->out, " ");
1266 if (count < 0)
1267 return -1;
1268 sum += count;
1269 p->state = XML_TEXTWRITER_PI_TEXT;
1270 break;
1271 case XML_TEXTWRITER_DTD:
1272 count = xmlOutputBufferWriteString(writer->out, " [");
1273 if (count < 0)
1274 return -1;
1275 sum += count;
1276 p->state = XML_TEXTWRITER_DTD_TEXT;
1277 break;
1278 default:
1279 break;
1280 }
1281
1282 count =
1283 xmlOutputBufferWriteBinHex(writer->out, len,
1284 (unsigned char *) data + start);
1285 if (count < 0)
1286 return -1;
1287 sum += count;
1288
1289 return sum;
1290}
1291
1292/**
1293 * xmlTextWriterStartAttribute:
1294 * @writer: the xmlTextWriterPtr
1295 * @name: element name
1296 *
1297 * Start an xml attribute.
1298 *
1299 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1300 */
1301int
1302xmlTextWriterStartAttribute(xmlTextWriterPtr writer, const xmlChar * name)
1303{
1304 int count;
1305 int sum;
1306 xmlLinkPtr lk;
1307 xmlTextWriterStackEntry *p;
1308
1309 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1310 return -1;
1311
1312 sum = 0;
1313 lk = xmlListFront(writer->nodes);
1314 if (lk == 0)
1315 return -1;
1316
1317 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1318 if (p == 0)
1319 return -1;
1320
1321 switch (p->state) {
1322 case XML_TEXTWRITER_ATTRIBUTE:
1323 count = xmlTextWriterEndAttribute(writer);
1324 if (count < 0)
1325 return -1;
1326 sum += count;
1327 /* fallthrough */
1328 case XML_TEXTWRITER_NAME:
1329 count = xmlOutputBufferWriteString(writer->out, " ");
1330 if (count < 0)
1331 return -1;
1332 sum += count;
1333 count = xmlOutputBufferWriteString(writer->out, (const char *)name);
1334 if (count < 0)
1335 return -1;
1336 sum += count;
1337 count = xmlOutputBufferWriteString(writer->out, "=");
1338 if (count < 0)
1339 return -1;
1340 sum += count;
1341 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
1342 if (count < 0)
1343 return -1;
1344 sum += count;
1345 p->state = XML_TEXTWRITER_ATTRIBUTE;
1346 break;
1347 default:
1348 return -1;
1349 }
1350
1351 return sum;
1352}
1353
1354/**
1355 * xmlTextWriterStartAttributeNS:
1356 * @writer: the xmlTextWriterPtr
1357 * @prefix: namespace prefix or NULL
1358 * @name: element local name
1359 * @namespaceURI: namespace URI or NULL
1360 *
1361 * Start an xml attribute with namespace support.
1362 *
1363 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1364 */
1365int
1366xmlTextWriterStartAttributeNS(xmlTextWriterPtr writer,
1367 const xmlChar * prefix, const xmlChar * name,
1368 const xmlChar * namespaceURI)
1369{
1370 int count;
1371 int sum;
1372 xmlChar *buf;
1373 xmlTextWriterNsStackEntry *p;
1374
1375 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1376 return -1;
1377
1378 buf = 0;
1379 if (prefix != 0) {
1380 buf = xmlStrdup(prefix);
1381 buf = xmlStrcat(buf, BAD_CAST ":");
1382 }
1383 buf = xmlStrcat(buf, name);
1384
1385 sum = 0;
1386 count = xmlTextWriterStartAttribute(writer, buf);
1387 xmlFree(buf);
1388 if (count < 0)
1389 return -1;
1390 sum += count;
1391
1392 if (namespaceURI != 0) {
1393 buf = xmlStrdup(BAD_CAST "xmlns");
1394 if (prefix != 0) {
1395 buf = xmlStrcat(buf, BAD_CAST ":");
1396 buf = xmlStrcat(buf, prefix);
1397 }
1398
1399 p = (xmlTextWriterNsStackEntry *)
1400 xmlMalloc(sizeof(xmlTextWriterNsStackEntry));
1401 if (p == 0) {
1402 xmlGenericError(xmlGenericErrorContext,
1403 "xmlTextWriterStartAttributeNS : out of memory!\n");
1404 return -1;
1405 }
1406
1407 p->prefix = buf;
1408 p->uri = xmlStrdup(namespaceURI);
1409 if (p->uri == 0) {
1410 xmlGenericError(xmlGenericErrorContext,
1411 "xmlTextWriterStartAttributeNS : out of memory!\n");
1412 xmlFree(p);
1413 return -1;
1414 }
1415 p->elem = xmlListFront(writer->nodes);
1416
1417 xmlListPushFront(writer->nsstack, p);
1418 }
1419
1420 return sum;
1421}
1422
1423/**
1424 * xmlTextWriterEndAttribute:
1425 * @writer: the xmlTextWriterPtr
1426 *
1427 * End the current xml element.
1428 *
1429 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1430 */
1431int
1432xmlTextWriterEndAttribute(xmlTextWriterPtr writer)
1433{
1434 int count;
1435 int sum;
1436 xmlLinkPtr lk;
1437 xmlTextWriterStackEntry *p;
1438 xmlTextWriterNsStackEntry *np;
1439
1440 if (writer == NULL)
1441 return -1;
1442
1443 lk = xmlListFront(writer->nodes);
1444 if (lk == 0) {
1445 xmlListDelete(writer->nsstack);
1446 return -1;
1447 }
1448
1449 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1450 if (p == 0) {
1451 xmlListDelete(writer->nsstack);
1452 return -1;
1453 }
1454
1455 sum = 0;
1456 switch (p->state) {
1457 case XML_TEXTWRITER_ATTRIBUTE:
1458 p->state = XML_TEXTWRITER_NAME;
1459
1460 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
1461 if (count < 0) {
1462 xmlListDelete(writer->nsstack);
1463 return -1;
1464 }
1465 sum += count;
1466
1467 while (!xmlListEmpty(writer->nsstack)) {
1468 lk = xmlListFront(writer->nsstack);
1469 np = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
1470 if (np != 0) {
1471 count =
1472 xmlTextWriterWriteAttribute(writer, np->prefix,
1473 np->uri);
1474 if (count < 0) {
1475 xmlListDelete(writer->nsstack);
1476 return -1;
1477 }
1478 sum += count;
1479 }
1480
1481 xmlListPopFront(writer->nsstack);
1482 }
1483 break;
1484
1485 default:
1486 xmlListClear(writer->nsstack);
1487 return -1;
1488 }
1489
1490 return sum;
1491}
1492
1493/**
1494 * xmlTextWriterWriteFormatAttribute:
1495 * @writer: the xmlTextWriterPtr
1496 * @name: attribute name
1497 * @format: format string (see printf)
1498 *
1499 * Write a formatted xml attribute.
1500 *
1501 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1502 */
1503int
1504xmlTextWriterWriteFormatAttribute(xmlTextWriterPtr writer,
1505 const xmlChar * name, const char *format,
1506 ...)
1507{
1508 int rc;
1509 va_list ap;
1510
1511 va_start(ap, format);
1512
1513 rc = xmlTextWriterWriteVFormatAttribute(writer, name, format, ap);
1514
1515 va_end(ap);
1516 return rc;
1517}
1518
1519/**
1520 * xmlTextWriterWriteVFormatAttribute:
1521 * @writer: the xmlTextWriterPtr
1522 * @name: attribute name
1523 * @format: format string (see printf)
1524 * @argptr: pointer to the first member of the variable argument list.
1525 *
1526 * Write a formatted xml attribute.
1527 *
1528 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1529 */
1530int
1531xmlTextWriterWriteVFormatAttribute(xmlTextWriterPtr writer,
1532 const xmlChar * name,
1533 const char *format, va_list argptr)
1534{
1535 int rc;
1536 xmlChar *buf;
1537
1538 if (writer == NULL)
1539 return -1;
1540
1541 buf = xmlTextWriterVSprintf(format, argptr);
1542 if (buf == 0)
1543 return 0;
1544
1545 rc = xmlTextWriterWriteAttribute(writer, name, buf);
1546
1547 xmlFree(buf);
1548 return rc;
1549}
1550
1551/**
1552 * xmlTextWriterWriteAttribute:
1553 * @writer: the xmlTextWriterPtr
1554 * @name: attribute name
1555 * @content: attribute content
1556 *
1557 * Write an xml attribute.
1558 *
1559 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1560 */
1561int
1562xmlTextWriterWriteAttribute(xmlTextWriterPtr writer, const xmlChar * name,
1563 const xmlChar * content)
1564{
1565 int count;
1566 int sum;
1567
1568 sum = 0;
1569 count = xmlTextWriterStartAttribute(writer, name);
1570 if (count < 0)
1571 return -1;
1572 sum += count;
1573 count = xmlTextWriterWriteString(writer, content);
1574 if (count < 0)
1575 return -1;
1576 sum += count;
1577 count = xmlTextWriterEndAttribute(writer);
1578 if (count < 0)
1579 return -1;
1580 sum += count;
1581
1582 return sum;
1583}
1584
1585/**
1586 * xmlTextWriterWriteFormatAttributeNS:
1587 * @writer: the xmlTextWriterPtr
1588 * @prefix: namespace prefix
1589 * @name: attribute local name
1590 * @namespaceURI: namespace URI
1591 * @format: format string (see printf)
1592 *
1593 * Write a formatted xml attribute.with namespace support
1594 *
1595 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1596 */
1597int
1598xmlTextWriterWriteFormatAttributeNS(xmlTextWriterPtr writer,
1599 const xmlChar * prefix,
1600 const xmlChar * name,
1601 const xmlChar * namespaceURI,
1602 const char *format, ...)
1603{
1604 int rc;
1605 va_list ap;
1606
1607 va_start(ap, format);
1608
1609 rc = xmlTextWriterWriteVFormatAttributeNS(writer, prefix, name,
1610 namespaceURI, format, ap);
1611
1612 va_end(ap);
1613 return rc;
1614}
1615
1616/**
1617 * xmlTextWriterWriteVFormatAttributeNS:
1618 * @writer: the xmlTextWriterPtr
1619 * @prefix: namespace prefix
1620 * @name: attribute local name
1621 * @namespaceURI: namespace URI
1622 * @format: format string (see printf)
1623 * @argptr: pointer to the first member of the variable argument list.
1624 *
1625 * Write a formatted xml attribute.with namespace support
1626 *
1627 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1628 */
1629int
1630xmlTextWriterWriteVFormatAttributeNS(xmlTextWriterPtr writer,
1631 const xmlChar * prefix,
1632 const xmlChar * name,
1633 const xmlChar * namespaceURI,
1634 const char *format, va_list argptr)
1635{
1636 int rc;
1637 xmlChar *buf;
1638
1639 if (writer == NULL)
1640 return -1;
1641
1642 buf = xmlTextWriterVSprintf(format, argptr);
1643 if (buf == 0)
1644 return 0;
1645
1646 rc = xmlTextWriterWriteAttributeNS(writer, prefix, name, namespaceURI,
1647 buf);
1648
1649 xmlFree(buf);
1650 return rc;
1651}
1652
1653/**
1654 * xmlTextWriterWriteAttributeNS:
1655 * @writer: the xmlTextWriterPtr
1656 * @prefix: namespace prefix
1657 * @name: attribute local name
1658 * @namespaceURI: namespace URI
1659 * @content: attribute content
1660 *
1661 * Write an xml attribute.
1662 *
1663 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1664 */
1665int
1666xmlTextWriterWriteAttributeNS(xmlTextWriterPtr writer,
1667 const xmlChar * prefix, const xmlChar * name,
1668 const xmlChar * namespaceURI,
1669 const xmlChar * content)
1670{
1671 int count;
1672 int sum;
1673 xmlChar *buf;
1674
1675 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1676 return -1;
1677
1678 buf = 0;
1679 if (prefix != NULL) {
1680 buf = xmlStrdup(prefix);
1681 buf = xmlStrcat(buf, BAD_CAST ":");
1682 }
1683 buf = xmlStrcat(buf, name);
1684
1685 sum = 0;
1686 count = xmlTextWriterWriteAttribute(writer, buf, content);
1687 xmlFree(buf);
1688 if (count < 0)
1689 return -1;
1690 sum += count;
1691
1692 if (namespaceURI != NULL) {
1693 buf = 0;
1694 buf = xmlStrdup(BAD_CAST "xmlns");
1695 if (prefix != NULL) {
1696 buf = xmlStrcat(buf, BAD_CAST ":");
1697 buf = xmlStrcat(buf, prefix);
1698 }
1699 count = xmlTextWriterWriteAttribute(writer, buf, namespaceURI);
1700 xmlFree(buf);
1701 if (count < 0)
1702 return -1;
1703 sum += count;
1704 }
1705 return sum;
1706}
1707
1708/**
1709 * xmlTextWriterWriteFormatElement:
1710 * @writer: the xmlTextWriterPtr
1711 * @name: element name
1712 * @format: format string (see printf)
1713 *
1714 * Write a formatted xml element.
1715 *
1716 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1717 */
1718int
1719xmlTextWriterWriteFormatElement(xmlTextWriterPtr writer,
1720 const xmlChar * name, const char *format,
1721 ...)
1722{
1723 int rc;
1724 va_list ap;
1725
1726 va_start(ap, format);
1727
1728 rc = xmlTextWriterWriteVFormatElement(writer, name, format, ap);
1729
1730 va_end(ap);
1731 return rc;
1732}
1733
1734/**
1735 * xmlTextWriterWriteVFormatElement:
1736 * @writer: the xmlTextWriterPtr
1737 * @name: element name
1738 * @format: format string (see printf)
1739 * @argptr: pointer to the first member of the variable argument list.
1740 *
1741 * Write a formatted xml element.
1742 *
1743 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1744 */
1745int
1746xmlTextWriterWriteVFormatElement(xmlTextWriterPtr writer,
1747 const xmlChar * name, const char *format,
1748 va_list argptr)
1749{
1750 int rc;
1751 xmlChar *buf;
1752
1753 if (writer == NULL)
1754 return -1;
1755
1756 buf = xmlTextWriterVSprintf(format, argptr);
1757 if (buf == 0)
1758 return 0;
1759
1760 rc = xmlTextWriterWriteElement(writer, name, buf);
1761
1762 xmlFree(buf);
1763 return rc;
1764}
1765
1766/**
1767 * xmlTextWriterWriteElement:
1768 * @writer: the xmlTextWriterPtr
1769 * @name: element name
1770 * @content: element content
1771 *
1772 * Write an xml element.
1773 *
1774 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1775 */
1776int
1777xmlTextWriterWriteElement(xmlTextWriterPtr writer, const xmlChar * name,
1778 const xmlChar * content)
1779{
1780 int count;
1781 int sum;
1782
1783 sum = 0;
1784 count = xmlTextWriterStartElement(writer, name);
1785 if (count == -1)
1786 return -1;
1787 sum += count;
1788 count = xmlTextWriterWriteString(writer, content);
1789 if (count == -1)
1790 return -1;
1791 sum += count;
1792 count = xmlTextWriterEndElement(writer);
1793 if (count == -1)
1794 return -1;
1795 sum += count;
1796
1797 return sum;
1798}
1799
1800/**
1801 * xmlTextWriterWriteFormatElementNS:
1802 * @writer: the xmlTextWriterPtr
1803 * @prefix: namespace prefix
1804 * @name: element local name
1805 * @namespaceURI: namespace URI
1806 * @format: format string (see printf)
1807 *
1808 * Write a formatted xml element with namespace support.
1809 *
1810 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1811 */
1812int
1813xmlTextWriterWriteFormatElementNS(xmlTextWriterPtr writer,
1814 const xmlChar * prefix,
1815 const xmlChar * name,
1816 const xmlChar * namespaceURI,
1817 const char *format, ...)
1818{
1819 int rc;
1820 va_list ap;
1821
1822 va_start(ap, format);
1823
1824 rc = xmlTextWriterWriteVFormatElementNS(writer, prefix, name,
1825 namespaceURI, format, ap);
1826
1827 va_end(ap);
1828 return rc;
1829}
1830
1831/**
1832 * xmlTextWriterWriteVFormatElementNS:
1833 * @writer: the xmlTextWriterPtr
1834 * @prefix: namespace prefix
1835 * @name: element local name
1836 * @namespaceURI: namespace URI
1837 * @format: format string (see printf)
1838 * @argptr: pointer to the first member of the variable argument list.
1839 *
1840 * Write a formatted xml element with namespace support.
1841 *
1842 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1843 */
1844int
1845xmlTextWriterWriteVFormatElementNS(xmlTextWriterPtr writer,
1846 const xmlChar * prefix,
1847 const xmlChar * name,
1848 const xmlChar * namespaceURI,
1849 const char *format, va_list argptr)
1850{
1851 int rc;
1852 xmlChar *buf;
1853
1854 if (writer == NULL)
1855 return -1;
1856
1857 buf = xmlTextWriterVSprintf(format, argptr);
1858 if (buf == 0)
1859 return 0;
1860
1861 rc = xmlTextWriterWriteElementNS(writer, prefix, name, namespaceURI,
1862 buf);
1863
1864 xmlFree(buf);
1865 return rc;
1866}
1867
1868/**
1869 * xmlTextWriterWriteElementNS:
1870 * @writer: the xmlTextWriterPtr
1871 * @prefix: namespace prefix
1872 * @name: element local name
1873 * @namespaceURI: namespace URI
1874 * @content: element content
1875 *
1876 * Write an xml element with namespace support.
1877 *
1878 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1879 */
1880int
1881xmlTextWriterWriteElementNS(xmlTextWriterPtr writer,
1882 const xmlChar * prefix, const xmlChar * name,
1883 const xmlChar * namespaceURI,
1884 const xmlChar * content)
1885{
1886 int count;
1887 int sum;
1888
1889 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1890 return -1;
1891
1892 sum = 0;
1893 count =
1894 xmlTextWriterStartElementNS(writer, prefix, name, namespaceURI);
1895 if (count < 0)
1896 return -1;
1897 sum += count;
1898 count = xmlTextWriterWriteString(writer, content);
1899 if (count == -1)
1900 return -1;
1901 sum += count;
1902 count = xmlTextWriterEndElement(writer);
1903 if (count == -1)
1904 return -1;
1905 sum += count;
1906
1907 return sum;
1908}
1909
1910/**
1911 * xmlTextWriterStartPI:
1912 * @writer: the xmlTextWriterPtr
1913 * @target: PI target
1914 *
1915 * Start an xml PI.
1916 *
1917 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1918 */
1919int
1920xmlTextWriterStartPI(xmlTextWriterPtr writer, const xmlChar * target)
1921{
1922 int count;
1923 int sum;
1924 xmlLinkPtr lk;
1925 xmlTextWriterStackEntry *p;
1926
1927 if ((writer == NULL) || (target == NULL) || (*target == '\0'))
1928 return -1;
1929
1930 if (xmlStrcasecmp(target, (const xmlChar *) "xml") == 0) {
1931 xmlGenericError(xmlGenericErrorContext,
1932 "xmlTextWriterStartPI : target name [Xx][Mm][Ll] is reserved for xml standardization!\n");
1933 return -1;
1934 }
1935
1936 sum = 0;
1937 lk = xmlListFront(writer->nodes);
1938 if (lk != 0) {
1939 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1940 if (p != 0) {
1941 switch (p->state) {
1942 case XML_TEXTWRITER_ATTRIBUTE:
1943 count = xmlTextWriterEndAttribute(writer);
1944 if (count < 0)
1945 return -1;
1946 sum += count;
1947 /* fallthrough */
1948 case XML_TEXTWRITER_NAME:
1949 count = xmlOutputBufferWriteString(writer->out, ">");
1950 if (count < 0)
1951 return -1;
1952 sum += count;
1953 p->state = XML_TEXTWRITER_TEXT;
1954 break;
1955 case XML_TEXTWRITER_PI:
1956 case XML_TEXTWRITER_PI_TEXT:
1957 xmlGenericError(xmlGenericErrorContext,
1958 "xmlTextWriterStartPI : nested PI!\n");
1959 return -1;
1960 default:
1961 return -1;
1962 }
1963 }
1964 }
1965
1966 p = (xmlTextWriterStackEntry *)
1967 xmlMalloc(sizeof(xmlTextWriterStackEntry));
1968 if (p == 0) {
1969 xmlGenericError(xmlGenericErrorContext,
1970 "xmlTextWriterStartPI : out of memory!\n");
1971 return -1;
1972 }
1973
1974 p->name = xmlStrdup(target);
1975 if (p->name == 0) {
1976 xmlGenericError(xmlGenericErrorContext,
1977 "xmlTextWriterStartPI : out of memory!\n");
1978 xmlFree(p);
1979 return -1;
1980 }
1981 p->state = XML_TEXTWRITER_PI;
1982
1983 xmlListPushFront(writer->nodes, p);
1984
1985 count = xmlOutputBufferWriteString(writer->out, "<?");
1986 if (count < 0)
1987 return -1;
1988 sum += count;
1989 count = xmlOutputBufferWriteString(writer->out, (const char *) p->name);
1990 if (count < 0)
1991 return -1;
1992 sum += count;
1993
1994 return sum;
1995}
1996
1997/**
1998 * xmlTextWriterEndPI:
1999 * @writer: the xmlTextWriterPtr
2000 *
2001 * End the current xml PI.
2002 *
2003 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2004 */
2005int
2006xmlTextWriterEndPI(xmlTextWriterPtr writer)
2007{
2008 int count;
2009 int sum;
2010 xmlLinkPtr lk;
2011 xmlTextWriterStackEntry *p;
2012
2013 if (writer == NULL)
2014 return -1;
2015
2016 lk = xmlListFront(writer->nodes);
2017 if (lk == 0)
2018 return 0;
2019
2020 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2021 if (p == 0)
2022 return 0;
2023
2024 sum = 0;
2025 switch (p->state) {
2026 case XML_TEXTWRITER_PI:
2027 case XML_TEXTWRITER_PI_TEXT:
2028 count = xmlOutputBufferWriteString(writer->out, "?>");
2029 if (count < 0)
2030 return -1;
2031 sum += count;
2032 break;
2033 default:
2034 return -1;
2035 }
2036
2037 xmlListPopFront(writer->nodes);
2038 return sum;
2039}
2040
2041/**
2042 * xmlTextWriterWriteFormatPI:
2043 * @writer: the xmlTextWriterPtr
2044 * @target: PI target
2045 * @format: format string (see printf)
2046 *
2047 * Write a formatted PI.
2048 *
2049 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2050 */
2051int
2052xmlTextWriterWriteFormatPI(xmlTextWriterPtr writer, const xmlChar * target,
2053 const char *format, ...)
2054{
2055 int rc;
2056 va_list ap;
2057
2058 va_start(ap, format);
2059
2060 rc = xmlTextWriterWriteVFormatPI(writer, target, format, ap);
2061
2062 va_end(ap);
2063 return rc;
2064}
2065
2066/**
2067 * xmlTextWriterWriteVFormatPI:
2068 * @writer: the xmlTextWriterPtr
2069 * @target: PI target
2070 * @format: format string (see printf)
2071 *
2072 * Write a formatted xml PI.
2073 *
2074 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2075 */
2076int
2077xmlTextWriterWriteVFormatPI(xmlTextWriterPtr writer,
2078 const xmlChar * target, const char *format,
2079 va_list argptr)
2080{
2081 int rc;
2082 xmlChar *buf;
2083
2084 if (writer == NULL)
2085 return -1;
2086
2087 buf = xmlTextWriterVSprintf(format, argptr);
2088 if (buf == 0)
2089 return 0;
2090
2091 rc = xmlTextWriterWritePI(writer, target, buf);
2092
2093 xmlFree(buf);
2094 return rc;
2095}
2096
2097/**
2098 * xmlTextWriterWritePI:
2099 * @writer: the xmlTextWriterPtr
2100 * @target: PI target
2101 * @content: PI content
2102 *
2103 * Write an xml PI.
2104 *
2105 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2106 */
2107int
2108xmlTextWriterWritePI(xmlTextWriterPtr writer, const xmlChar * target,
2109 const xmlChar * content)
2110{
2111 int count;
2112 int sum;
2113
2114 sum = 0;
2115 count = xmlTextWriterStartPI(writer, target);
2116 if (count == -1)
2117 return -1;
2118 sum += count;
2119 if (content != 0) {
2120 count = xmlTextWriterWriteString(writer, content);
2121 if (count == -1)
2122 return -1;
2123 sum += count;
2124 }
2125 count = xmlTextWriterEndPI(writer);
2126 if (count == -1)
2127 return -1;
2128 sum += count;
2129
2130 return sum;
2131}
2132
2133/**
2134 * xmlTextWriterStartCDATA:
2135 * @writer: the xmlTextWriterPtr
2136 *
2137 * Start an xml CDATA section.
2138 *
2139 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2140 */
2141int
2142xmlTextWriterStartCDATA(xmlTextWriterPtr writer)
2143{
2144 int count;
2145 int sum;
2146 xmlLinkPtr lk;
2147 xmlTextWriterStackEntry *p;
2148
2149 if (writer == NULL)
2150 return -1;
2151
2152 sum = 0;
2153 lk = xmlListFront(writer->nodes);
2154 if (lk != 0) {
2155 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2156 if (p != 0) {
2157 switch (p->state) {
2158 case XML_TEXTWRITER_NONE:
2159 case XML_TEXTWRITER_PI:
2160 case XML_TEXTWRITER_PI_TEXT:
2161 break;
2162 case XML_TEXTWRITER_ATTRIBUTE:
2163 count = xmlTextWriterEndAttribute(writer);
2164 if (count < 0)
2165 return -1;
2166 sum += count;
2167 /* fallthrough */
2168 case XML_TEXTWRITER_NAME:
2169 count = xmlOutputBufferWriteString(writer->out, ">");
2170 if (count < 0)
2171 return -1;
2172 sum += count;
2173 p->state = XML_TEXTWRITER_TEXT;
2174 break;
2175 case XML_TEXTWRITER_CDATA:
2176 xmlGenericError(xmlGenericErrorContext,
2177 "xmlTextWriterStartCDATA : CDATA not allowed in this context!\n");
2178 return -1;
2179 default:
2180 return -1;
2181 }
2182 }
2183 }
2184
2185 p = (xmlTextWriterStackEntry *)
2186 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2187 if (p == 0) {
2188 xmlGenericError(xmlGenericErrorContext,
2189 "xmlTextWriterStartCDATA : out of memory!\n");
2190 return -1;
2191 }
2192
2193 p->name = 0;
2194 p->state = XML_TEXTWRITER_CDATA;
2195
2196 xmlListPushFront(writer->nodes, p);
2197
2198 count = xmlOutputBufferWriteString(writer->out, "<![CDATA[");
2199 if (count < 0)
2200 return -1;
2201 sum += count;
2202
2203 return sum;
2204}
2205
2206/**
2207 * xmlTextWriterEndCDATA:
2208 * @writer: the xmlTextWriterPtr
2209 *
2210 * End an xml CDATA section.
2211 *
2212 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2213 */
2214int
2215xmlTextWriterEndCDATA(xmlTextWriterPtr writer)
2216{
2217 int count;
2218 int sum;
2219 xmlLinkPtr lk;
2220 xmlTextWriterStackEntry *p;
2221
2222 if (writer == NULL)
2223 return -1;
2224
2225 lk = xmlListFront(writer->nodes);
2226 if (lk == 0)
2227 return -1;
2228
2229 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2230 if (p == 0)
2231 return -1;
2232
2233 sum = 0;
2234 switch (p->state) {
2235 case XML_TEXTWRITER_CDATA:
2236 count = xmlOutputBufferWriteString(writer->out, "]]>");
2237 if (count < 0)
2238 return -1;
2239 sum += count;
2240 break;
2241 default:
2242 return -1;
2243 }
2244
2245 xmlListPopFront(writer->nodes);
2246 return sum;
2247}
2248
2249/**
2250 * xmlTextWriterWriteFormatCDATA:
2251 * @writer: the xmlTextWriterPtr
2252 * @format: format string (see printf)
2253 *
2254 * Write a formatted xml CDATA.
2255 *
2256 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2257 */
2258int
2259xmlTextWriterWriteFormatCDATA(xmlTextWriterPtr writer, const char *format,
2260 ...)
2261{
2262 int rc;
2263 va_list ap;
2264
2265 va_start(ap, format);
2266
2267 rc = xmlTextWriterWriteVFormatCDATA(writer, format, ap);
2268
2269 va_end(ap);
2270 return rc;
2271}
2272
2273/**
2274 * xmlTextWriterWriteVFormatCDATA:
2275 * @writer: the xmlTextWriterPtr
2276 * @format: format string (see printf)
2277 *
2278 * Write a formatted xml CDATA.
2279 *
2280 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2281 */
2282int
2283xmlTextWriterWriteVFormatCDATA(xmlTextWriterPtr writer, const char *format,
2284 va_list argptr)
2285{
2286 int rc;
2287 xmlChar *buf;
2288
2289 if (writer == NULL)
2290 return -1;
2291
2292 buf = xmlTextWriterVSprintf(format, argptr);
2293 if (buf == 0)
2294 return 0;
2295
2296 rc = xmlTextWriterWriteCDATA(writer, buf);
2297
2298 xmlFree(buf);
2299 return rc;
2300}
2301
2302/**
2303 * xmlTextWriterWriteCDATA:
2304 * @writer: the xmlTextWriterPtr
2305 * @content: CDATA content
2306 *
2307 * Write an xml CDATA.
2308 *
2309 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2310 */
2311int
2312xmlTextWriterWriteCDATA(xmlTextWriterPtr writer, const xmlChar * content)
2313{
2314 int count;
2315 int sum;
2316
2317 sum = 0;
2318 count = xmlTextWriterStartCDATA(writer);
2319 if (count == -1)
2320 return -1;
2321 sum += count;
2322 if (content != 0) {
2323 count = xmlTextWriterWriteString(writer, content);
2324 if (count == -1)
2325 return -1;
2326 sum += count;
2327 }
2328 count = xmlTextWriterEndCDATA(writer);
2329 if (count == -1)
2330 return -1;
2331 sum += count;
2332
2333 return sum;
2334}
2335
2336/**
2337 * xmlTextWriterStartDTD:
2338 * @writer: the xmlTextWriterPtr
2339 * @name: the name of the DTD
2340 * @pubid: the public identifier, which is an alternative to the system identifier
2341 * @sysid: the system identifier, which is the URI of the DTD
2342 *
2343 * Start an xml DTD.
2344 *
2345 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2346 */
2347int
2348xmlTextWriterStartDTD(xmlTextWriterPtr writer,
2349 const xmlChar * name,
2350 const xmlChar * pubid, const xmlChar * sysid)
2351{
2352 int count;
2353 int sum;
2354 xmlLinkPtr lk;
2355 xmlTextWriterStackEntry *p;
2356
2357 if (writer == NULL || name == NULL || *name == '\0')
2358 return -1;
2359
2360 sum = 0;
2361 lk = xmlListFront(writer->nodes);
2362 if (lk != 0) {
2363 xmlGenericError(xmlGenericErrorContext,
2364 "xmlTextWriterStartDTD : DTD allowed only in prolog!\n");
2365 return -1;
2366 }
2367
2368 p = (xmlTextWriterStackEntry *)
2369 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2370 if (p == 0) {
2371 xmlGenericError(xmlGenericErrorContext,
2372 "xmlTextWriterStartDTD : out of memory!\n");
2373 return -1;
2374 }
2375
2376 p->name = xmlStrdup(name);
2377 if (p->name == 0) {
2378 xmlGenericError(xmlGenericErrorContext,
2379 "xmlTextWriterStartDTD : out of memory!\n");
2380 xmlFree(p);
2381 return -1;
2382 }
2383 p->state = XML_TEXTWRITER_DTD;
2384
2385 xmlListPushFront(writer->nodes, p);
2386
2387 count = xmlOutputBufferWriteString(writer->out, "<!DOCTYPE ");
2388 if (count < 0)
2389 return -1;
2390 sum += count;
2391 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
2392 if (count < 0)
2393 return -1;
2394 sum += count;
2395
2396 if (pubid != 0) {
2397 if (sysid == 0) {
2398 xmlGenericError(xmlGenericErrorContext,
2399 "xmlTextWriterStartDTD : system identifier needed!\n");
2400 return -1;
2401 }
2402
2403 count = xmlOutputBufferWriteString(writer->out, " PUBLIC \"");
2404 if (count < 0)
2405 return -1;
2406 sum += count;
2407
2408 count = xmlOutputBufferWriteString(writer->out, (const char *) pubid);
2409 if (count < 0)
2410 return -1;
2411 sum += count;
2412
2413 count = xmlOutputBufferWriteString(writer->out, "\"");
2414 if (count < 0)
2415 return -1;
2416 sum += count;
2417 }
2418
2419 if (sysid != 0) {
2420 if (pubid == 0) {
2421 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
2422 if (count < 0)
2423 return -1;
2424 sum += count;
2425 }
2426
2427 count = xmlOutputBufferWriteString(writer->out, " \"");
2428 if (count < 0)
2429 return -1;
2430 sum += count;
2431
2432 count = xmlOutputBufferWriteString(writer->out, (const char *) sysid);
2433 if (count < 0)
2434 return -1;
2435 sum += count;
2436
2437 count = xmlOutputBufferWriteString(writer->out, "\"");
2438 if (count < 0)
2439 return -1;
2440 sum += count;
2441 }
2442
2443 return sum;
2444}
2445
2446/**
2447 * xmlTextWriterEndDTD:
2448 * @writer: the xmlTextWriterPtr
2449 *
2450 * End an xml DTD.
2451 *
2452 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2453 */
2454int
2455xmlTextWriterEndDTD(xmlTextWriterPtr writer)
2456{
2457 int count;
2458 int sum;
2459 xmlLinkPtr lk;
2460 xmlTextWriterStackEntry *p;
2461
2462 if (writer == NULL)
2463 return -1;
2464
2465 sum = 0;
2466 lk = xmlListFront(writer->nodes);
2467 if (lk == 0)
2468 return -1;
2469
2470 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2471 if (p == 0)
2472 return -1;
2473
2474 switch (p->state) {
2475 case XML_TEXTWRITER_DTD_TEXT:
2476 count = xmlOutputBufferWriteString(writer->out, "]");
2477 if (count < 0)
2478 return -1;
2479 sum += count;
2480 /* fallthrough */
2481 case XML_TEXTWRITER_DTD:
2482 case XML_TEXTWRITER_DTD_ELEM:
2483 case XML_TEXTWRITER_DTD_ATTL:
2484 count = xmlOutputBufferWriteString(writer->out, ">");
2485 if (count < 0)
2486 return -1;
2487 sum += count;
2488 break;
2489 default:
2490 return -1;
2491 }
2492
2493 xmlListPopFront(writer->nodes);
2494 return sum;
2495}
2496
2497/**
2498 * xmlTextWriterWriteFormatDTD:
2499 * @writer: the xmlTextWriterPtr
2500 * @name: the name of the DTD
2501 * @pubid: the public identifier, which is an alternative to the system identifier
2502 * @sysid: the system identifier, which is the URI of the DTD
2503 * @format: format string (see printf)
2504 *
2505 * Write a DTD with a formatted markup declarations part.
2506 *
2507 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2508 */
2509int
2510xmlTextWriterWriteFormatDTD(xmlTextWriterPtr writer,
2511 const xmlChar * name,
2512 const xmlChar * pubid,
2513 const xmlChar * sysid, const char *format, ...)
2514{
2515 int rc;
2516 va_list ap;
2517
2518 va_start(ap, format);
2519
2520 rc = xmlTextWriterWriteVFormatDTD(writer, name, pubid, sysid, format,
2521 ap);
2522
2523 va_end(ap);
2524 return rc;
2525}
2526
2527/**
2528 * xmlTextWriterWriteVFormatDTD:
2529 * @writer: the xmlTextWriterPtr
2530 * @name: the name of the DTD
2531 * @pubid: the public identifier, which is an alternative to the system identifier
2532 * @sysid: the system identifier, which is the URI of the DTD
2533 * @format: format string (see printf)
2534 *
2535 * Write a DTD with a formatted markup declarations part.
2536 *
2537 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2538 */
2539int
2540xmlTextWriterWriteVFormatDTD(xmlTextWriterPtr writer,
2541 const xmlChar * name,
2542 const xmlChar * pubid,
2543 const xmlChar * sysid,
2544 const char *format, va_list argptr)
2545{
2546 int rc;
2547 xmlChar *buf;
2548
2549 if (writer == NULL)
2550 return -1;
2551
2552 buf = xmlTextWriterVSprintf(format, argptr);
2553 if (buf == 0)
2554 return 0;
2555
2556 rc = xmlTextWriterWriteDTD(writer, name, pubid, sysid, buf);
2557
2558 xmlFree(buf);
2559 return rc;
2560}
2561
2562/**
2563 * xmlTextWriterWriteDTD:
2564 * @writer: the xmlTextWriterPtr
2565 * @name: the name of the DTD
2566 * @pubid: the public identifier, which is an alternative to the system identifier
2567 * @sysid: the system identifier, which is the URI of the DTD
2568 * @format: format string (see printf)
2569 *
2570 * Write a DTD.
2571 *
2572 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2573 */
2574int
2575xmlTextWriterWriteDTD(xmlTextWriterPtr writer,
2576 const xmlChar * name,
2577 const xmlChar * pubid,
2578 const xmlChar * sysid, const xmlChar * subset)
2579{
2580 int count;
2581 int sum;
2582
2583 sum = 0;
2584 count = xmlTextWriterStartDTD(writer, name, pubid, sysid);
2585 if (count == -1)
2586 return -1;
2587 sum += count;
2588 if (subset != 0) {
2589 count = xmlTextWriterWriteString(writer, subset);
2590 if (count == -1)
2591 return -1;
2592 sum += count;
2593 }
2594 count = xmlTextWriterEndDTD(writer);
2595 if (count == -1)
2596 return -1;
2597 sum += count;
2598
2599 return sum;
2600}
2601
2602int
2603xmlTextWriterStartDTDElement(xmlTextWriterPtr writer, const xmlChar * name)
2604{
2605 int count;
2606 int sum;
2607 xmlLinkPtr lk;
2608 xmlTextWriterStackEntry *p;
2609
2610 if (writer == NULL || name == NULL || *name == '\0')
2611 return -1;
2612
2613 sum = 0;
2614 lk = xmlListFront(writer->nodes);
2615 if (lk == 0) {
2616 return -1;
2617 }
2618
2619 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2620 if (p == 0)
2621 return -1;
2622
2623 switch (p->state) {
2624 case XML_TEXTWRITER_DTD:
2625 count = xmlOutputBufferWriteString(writer->out, " [");
2626 if (count < 0)
2627 return -1;
2628 sum += count;
2629 p->state = XML_TEXTWRITER_DTD_TEXT;
2630 /* fallthrough */
2631 case XML_TEXTWRITER_DTD_TEXT:
2632 break;
2633 case XML_TEXTWRITER_DTD_ELEM:
2634 count = xmlTextWriterEndDTDElement(writer);
2635 if (count < 0)
2636 return -1;
2637 sum += count;
2638 break;
2639 default:
2640 return -1;
2641 }
2642
2643 p = (xmlTextWriterStackEntry *)
2644 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2645 if (p == 0) {
2646 xmlGenericError(xmlGenericErrorContext,
2647 "xmlTextWriterStartDTDElement : out of memory!\n");
2648 return -1;
2649 }
2650
2651 p->name = xmlStrdup(name);
2652 if (p->name == 0) {
2653 xmlGenericError(xmlGenericErrorContext,
2654 "xmlTextWriterStartDTDElement : out of memory!\n");
2655 xmlFree(p);
2656 return -1;
2657 }
2658 p->state = XML_TEXTWRITER_DTD_ELEM;
2659
2660 xmlListPushFront(writer->nodes, p);
2661
2662 count = xmlOutputBufferWriteString(writer->out, "<!ELEMENT ");
2663 if (count < 0)
2664 return -1;
2665 sum += count;
2666 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
2667 if (count < 0)
2668 return -1;
2669 sum += count;
2670
2671 return sum;
2672}
2673
2674int
2675xmlTextWriterWriteFormatDTDElement(xmlTextWriterPtr writer,
2676 const xmlChar * name,
2677 const char *format, ...)
2678{
2679 int rc;
2680 va_list ap;
2681
2682 va_start(ap, format);
2683
2684 rc = xmlTextWriterWriteVFormatDTDElement(writer, name, format, ap);
2685
2686 va_end(ap);
2687 return rc;
2688}
2689
2690int
2691xmlTextWriterWriteVFormatDTDElement(xmlTextWriterPtr writer,
2692 const xmlChar * name,
2693 const char *format, va_list argptr)
2694{
2695 int rc;
2696 xmlChar *buf;
2697
2698 if (writer == NULL)
2699 return -1;
2700
2701 buf = xmlTextWriterVSprintf(format, argptr);
2702 if (buf == 0)
2703 return 0;
2704
2705 rc = xmlTextWriterWriteDTDElement(writer, name, buf);
2706
2707 xmlFree(buf);
2708 return rc;
2709}
2710
2711int
2712xmlTextWriterWriteDTDElement(xmlTextWriterPtr writer,
2713 const xmlChar * name, const xmlChar * content)
2714{
2715 int count;
2716 int sum;
2717
2718 if (content == NULL)
2719 return -1;
2720
2721 sum = 0;
2722 count = xmlTextWriterStartDTDElement(writer, name);
2723 if (count == -1)
2724 return -1;
2725 sum += count;
2726
2727 count = xmlTextWriterWriteString(writer, BAD_CAST " ");
2728 if (count == -1)
2729 return -1;
2730 sum += count;
2731 count = xmlTextWriterWriteString(writer, content);
2732 if (count == -1)
2733 return -1;
2734 sum += count;
2735
2736 count = xmlTextWriterEndDTDElement(writer);
2737 if (count == -1)
2738 return -1;
2739 sum += count;
2740
2741 return sum;
2742}
2743
2744int
2745xmlTextWriterStartDTDAttlist(xmlTextWriterPtr writer, const xmlChar * name)
2746{
2747 int count;
2748 int sum;
2749 xmlLinkPtr lk;
2750 xmlTextWriterStackEntry *p;
2751
2752 if (writer == NULL || name == NULL || *name == '\0')
2753 return -1;
2754
2755 sum = 0;
2756 lk = xmlListFront(writer->nodes);
2757 if (lk == 0) {
2758 return -1;
2759 }
2760
2761 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2762 if (p == 0)
2763 return -1;
2764
2765 switch (p->state) {
2766 case XML_TEXTWRITER_DTD:
2767 count = xmlOutputBufferWriteString(writer->out, " [");
2768 if (count < 0)
2769 return -1;
2770 sum += count;
2771 p->state = XML_TEXTWRITER_DTD_TEXT;
2772 /* fallthrough */
2773 case XML_TEXTWRITER_DTD_TEXT:
2774 break;
2775 case XML_TEXTWRITER_DTD_ELEM:
2776 case XML_TEXTWRITER_DTD_ATTL:
2777 case XML_TEXTWRITER_DTD_ENTY:
2778 count = xmlTextWriterEndDTD(writer);
2779 if (count < 0)
2780 return -1;
2781 sum += count;
2782 break;
2783 default:
2784 return -1;
2785 }
2786
2787 p = (xmlTextWriterStackEntry *)
2788 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2789 if (p == 0) {
2790 xmlGenericError(xmlGenericErrorContext,
2791 "xmlTextWriterStartDTDAttlist : out of memory!\n");
2792 return -1;
2793 }
2794
2795 p->name = xmlStrdup(name);
2796 if (p->name == 0) {
2797 xmlGenericError(xmlGenericErrorContext,
2798 "xmlTextWriterStartDTDAttlist : out of memory!\n");
2799 xmlFree(p);
2800 return -1;
2801 }
2802 p->state = XML_TEXTWRITER_DTD_ATTL;
2803
2804 xmlListPushFront(writer->nodes, p);
2805
2806 count = xmlOutputBufferWriteString(writer->out, "<!ATTLIST ");
2807 if (count < 0)
2808 return -1;
2809 sum += count;
2810 count = xmlOutputBufferWriteString(writer->out, (const char *)name);
2811 if (count < 0)
2812 return -1;
2813 sum += count;
2814
2815 return sum;
2816}
2817
2818int
2819xmlTextWriterWriteFormatDTDAttlist(xmlTextWriterPtr writer,
2820 const xmlChar * name,
2821 const char *format, ...)
2822{
2823 int rc;
2824 va_list ap;
2825
2826 va_start(ap, format);
2827
2828 rc = xmlTextWriterWriteVFormatDTDAttlist(writer, name, format, ap);
2829
2830 va_end(ap);
2831 return rc;
2832}
2833
2834int
2835xmlTextWriterWriteVFormatDTDAttlist(xmlTextWriterPtr writer,
2836 const xmlChar * name,
2837 const char *format, va_list argptr)
2838{
2839 int rc;
2840 xmlChar *buf;
2841
2842 if (writer == NULL)
2843 return -1;
2844
2845 buf = xmlTextWriterVSprintf(format, argptr);
2846 if (buf == 0)
2847 return 0;
2848
2849 rc = xmlTextWriterWriteDTDAttlist(writer, name, buf);
2850
2851 xmlFree(buf);
2852 return rc;
2853}
2854
2855int
2856xmlTextWriterWriteDTDAttlist(xmlTextWriterPtr writer,
2857 const xmlChar * name, const xmlChar * content)
2858{
2859 int count;
2860 int sum;
2861
2862 if (content == NULL)
2863 return -1;
2864
2865 sum = 0;
2866 count = xmlTextWriterStartDTDAttlist(writer, name);
2867 if (count == -1)
2868 return -1;
2869 sum += count;
2870
2871 count = xmlTextWriterWriteString(writer, BAD_CAST " ");
2872 if (count == -1)
2873 return -1;
2874 sum += count;
2875 count = xmlTextWriterWriteString(writer, content);
2876 if (count == -1)
2877 return -1;
2878 sum += count;
2879
2880 count = xmlTextWriterEndDTDAttlist(writer);
2881 if (count == -1)
2882 return -1;
2883 sum += count;
2884
2885 return sum;
2886}
2887
2888int
2889xmlTextWriterStartDTDEntity(xmlTextWriterPtr writer,
2890 int pe, const xmlChar * name)
2891{
2892 int count;
2893 int sum;
2894 xmlLinkPtr lk;
2895 xmlTextWriterStackEntry *p;
2896
2897 if (writer == NULL || name == NULL || *name == '\0')
2898 return -1;
2899
2900 sum = 0;
2901 lk = xmlListFront(writer->nodes);
2902 if (lk == 0) {
2903 return -1;
2904 }
2905
2906 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2907 if (p == 0)
2908 return -1;
2909
2910 switch (p->state) {
2911 case XML_TEXTWRITER_DTD:
2912 count = xmlOutputBufferWriteString(writer->out, " [");
2913 if (count < 0)
2914 return -1;
2915 sum += count;
2916 p->state = XML_TEXTWRITER_DTD_TEXT;
2917 /* fallthrough */
2918 case XML_TEXTWRITER_DTD_TEXT:
2919 break;
2920 case XML_TEXTWRITER_DTD_ELEM:
2921 case XML_TEXTWRITER_DTD_ATTL:
2922 case XML_TEXTWRITER_DTD_ENTY:
2923 count = xmlTextWriterEndDTD(writer);
2924 if (count < 0)
2925 return -1;
2926 sum += count;
2927 break;
2928 default:
2929 return -1;
2930 }
2931
2932 p = (xmlTextWriterStackEntry *)
2933 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2934 if (p == 0) {
2935 xmlGenericError(xmlGenericErrorContext,
2936 "xmlTextWriterStartDTDElement : out of memory!\n");
2937 return -1;
2938 }
2939
2940 p->name = xmlStrdup(name);
2941 if (p->name == 0) {
2942 xmlGenericError(xmlGenericErrorContext,
2943 "xmlTextWriterStartDTDElement : out of memory!\n");
2944 xmlFree(p);
2945 return -1;
2946 }
2947 p->state = XML_TEXTWRITER_DTD_ENTY;
2948
2949 xmlListPushFront(writer->nodes, p);
2950
2951 count = xmlOutputBufferWriteString(writer->out, "<!ENTITY ");
2952 if (count < 0)
2953 return -1;
2954 sum += count;
2955
2956 if (pe != 0) {
2957 count = xmlOutputBufferWriteString(writer->out, " % ");
2958 if (count < 0)
2959 return -1;
2960 sum += count;
2961 }
2962
2963 count = xmlOutputBufferWriteString(writer->out, (const char *)name);
2964 if (count < 0)
2965 return -1;
2966 sum += count;
2967
2968 return sum;
2969}
2970
2971int
2972xmlTextWriterWriteFormatDTDInternalEntity(xmlTextWriterPtr writer,
2973 int pe,
2974 const xmlChar * name,
2975 const char *format, ...)
2976{
2977 int rc;
2978 va_list ap;
2979
2980 va_start(ap, format);
2981
2982 rc = xmlTextWriterWriteVFormatDTDInternalEntity(writer, pe, name,
2983 format, ap);
2984
2985 va_end(ap);
2986 return rc;
2987}
2988
2989int
2990xmlTextWriterWriteVFormatDTDInternalEntity(xmlTextWriterPtr writer,
2991 int pe,
2992 const xmlChar * name,
2993 const char *format,
2994 va_list argptr)
2995{
2996 int rc;
2997 xmlChar *buf;
2998
2999 if (writer == NULL)
3000 return -1;
3001
3002 buf = xmlTextWriterVSprintf(format, argptr);
3003 if (buf == 0)
3004 return 0;
3005
3006 rc = xmlTextWriterWriteDTDInternalEntity(writer, pe, name, buf);
3007
3008 xmlFree(buf);
3009 return rc;
3010}
3011
3012int
3013xmlTextWriterWriteDTDEntity(xmlTextWriterPtr writer,
3014 int pe,
3015 const xmlChar * name,
3016 const xmlChar * pubid,
3017 const xmlChar * sysid,
3018 const xmlChar * ndataid,
3019 const xmlChar * content)
3020{
3021 if (((content == NULL) && (pubid == NULL) && (sysid == NULL))
3022 || ((content != NULL) && ((pubid != NULL) || (sysid != NULL))))
3023 return -1;
3024 if ((pe != 0) && (ndataid != NULL))
3025 return -1;
3026
3027 if (content != 0)
3028 return xmlTextWriterWriteDTDInternalEntity(writer, pe, name,
3029 content);
3030
3031 return xmlTextWriterWriteDTDExternalEntity(writer, pe, name, pubid,
3032 sysid, ndataid);
3033}
3034
3035int
3036xmlTextWriterWriteDTDInternalEntity(xmlTextWriterPtr writer,
3037 int pe,
3038 const xmlChar * name,
3039 const xmlChar * content)
3040{
3041 int count;
3042 int sum;
3043
3044 if ((name == NULL) || (*name == '\0') || (content == NULL))
3045 return -1;
3046
3047 sum = 0;
3048 count = xmlTextWriterStartDTDEntity(writer, pe, name);
3049 if (count == -1)
3050 return -1;
3051 sum += count;
3052
3053 count = xmlTextWriterWriteString(writer, BAD_CAST " ");
3054 if (count == -1)
3055 return -1;
3056 sum += count;
3057 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3058 if (count < 0)
3059 return -1;
3060 sum += count;
3061 count = xmlTextWriterWriteString(writer, content);
3062 if (count == -1)
3063 return -1;
3064 sum += count;
3065 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3066 if (count < 0)
3067 return -1;
3068 sum += count;
3069
3070 count = xmlTextWriterEndDTDEntity(writer);
3071 if (count == -1)
3072 return -1;
3073 sum += count;
3074
3075 return sum;
3076}
3077
3078int
3079xmlTextWriterWriteDTDExternalEntity(xmlTextWriterPtr writer,
3080 int pe,
3081 const xmlChar * name,
3082 const xmlChar * pubid,
3083 const xmlChar * sysid,
3084 const xmlChar * ndataid)
3085{
3086 int count;
3087 int sum;
3088
3089 if ((name == NULL) || (*name == '\0')
3090 || ((pubid == NULL) && (sysid == NULL)))
3091 return -1;
3092 if ((pe != 0) && (ndataid != NULL))
3093 return -1;
3094
3095 sum = 0;
3096 count = xmlTextWriterStartDTDEntity(writer, pe, name);
3097 if (count == -1)
3098 return -1;
3099 sum += count;
3100
3101 if (pubid != 0) {
3102 if (sysid == 0) {
3103 xmlGenericError(xmlGenericErrorContext,
3104 "xmlTextWriterWriteDTDEntity : system identifier needed!\n");
3105 return -1;
3106 }
3107
3108 count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
3109 if (count < 0)
3110 return -1;
3111 sum += count;
3112
3113 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3114 if (count < 0)
3115 return -1;
3116 sum += count;
3117
3118 count = xmlOutputBufferWriteString(writer->out, (const char *) pubid);
3119 if (count < 0)
3120 return -1;
3121 sum += count;
3122
3123 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3124 if (count < 0)
3125 return -1;
3126 sum += count;
3127 }
3128
3129 if (sysid != 0) {
3130 if (pubid == 0) {
3131 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
3132 if (count < 0)
3133 return -1;
3134 sum += count;
3135 }
3136
3137 count = xmlOutputBufferWriteString(writer->out, " ");
3138 if (count < 0)
3139 return -1;
3140 sum += count;
3141
3142 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3143 if (count < 0)
3144 return -1;
3145 sum += count;
3146
3147 count = xmlOutputBufferWriteString(writer->out, (const char *) sysid);
3148 if (count < 0)
3149 return -1;
3150 sum += count;
3151
3152 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3153 if (count < 0)
3154 return -1;
3155 sum += count;
3156 }
3157
3158 if (ndataid != NULL) {
3159 count = xmlOutputBufferWriteString(writer->out, " NDATA ");
3160 if (count < 0)
3161 return -1;
3162 sum += count;
3163
3164 count = xmlOutputBufferWriteString(writer->out, (const char *) ndataid);
3165 if (count < 0)
3166 return -1;
3167 sum += count;
3168 }
3169
3170 count = xmlTextWriterEndDTDEntity(writer);
3171 if (count == -1)
3172 return -1;
3173 sum += count;
3174
3175 return sum;
3176}
3177
3178int
3179xmlTextWriterWriteDTDNotation(xmlTextWriterPtr writer,
3180 const xmlChar * name,
3181 const xmlChar * pubid, const xmlChar * sysid)
3182{
3183 int count;
3184 int sum;
3185 xmlLinkPtr lk;
3186 xmlTextWriterStackEntry *p;
3187
3188 if (writer == NULL || name == NULL || *name == '\0')
3189 return -1;
3190
3191 sum = 0;
3192 lk = xmlListFront(writer->nodes);
3193 if (lk == 0) {
3194 return -1;
3195 }
3196
3197 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3198 if (p == 0)
3199 return -1;
3200
3201 switch (p->state) {
3202 case XML_TEXTWRITER_DTD:
3203 count = xmlOutputBufferWriteString(writer->out, " [");
3204 if (count < 0)
3205 return -1;
3206 sum += count;
3207 p->state = XML_TEXTWRITER_DTD_TEXT;
3208 /* fallthrough */
3209 case XML_TEXTWRITER_DTD_TEXT:
3210 break;
3211 case XML_TEXTWRITER_DTD_ELEM:
3212 case XML_TEXTWRITER_DTD_ATTL:
3213 case XML_TEXTWRITER_DTD_ENTY:
3214 count = xmlTextWriterEndDTD(writer);
3215 if (count < 0)
3216 return -1;
3217 sum += count;
3218 break;
3219 default:
3220 return -1;
3221 }
3222
3223 count = xmlOutputBufferWriteString(writer->out, "<!NOTATION ");
3224 if (count < 0)
3225 return -1;
3226 sum += count;
3227 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
3228 if (count < 0)
3229 return -1;
3230 sum += count;
3231
3232 if (pubid != 0) {
3233 count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
3234 if (count < 0)
3235 return -1;
3236 sum += count;
3237 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3238 if (count < 0)
3239 return -1;
3240 sum += count;
3241 count = xmlOutputBufferWriteString(writer->out, (const char *) pubid);
3242 if (count < 0)
3243 return -1;
3244 sum += count;
3245 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3246 if (count < 0)
3247 return -1;
3248 sum += count;
3249 }
3250
3251 if (sysid != 0) {
3252 if (pubid == 0) {
3253 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
3254 if (count < 0)
3255 return -1;
3256 sum += count;
3257 }
3258 count = xmlOutputBufferWriteString(writer->out, " ");
3259 if (count < 0)
3260 return -1;
3261 sum += count;
3262 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3263 if (count < 0)
3264 return -1;
3265 sum += count;
3266 count = xmlOutputBufferWriteString(writer->out, (const char *) sysid);
3267 if (count < 0)
3268 return -1;
3269 sum += count;
3270 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3271 if (count < 0)
3272 return -1;
3273 sum += count;
3274 }
3275
3276 count = xmlOutputBufferWriteString(writer->out, ">");
3277 if (count < 0)
3278 return -1;
3279 sum += count;
3280
3281 return sum;
3282}
3283
3284/**
3285 * xmlTextWriterFlush:
3286 * @writer: the xmlTextWriterPtr
3287 *
3288 * Flush the output buffer.
3289 *
3290 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3291 */
3292int
3293xmlTextWriterFlush(xmlTextWriterPtr writer)
3294{
3295 int count;
3296
3297 if (writer == NULL)
3298 return -1;
3299
3300 if (writer->out == NULL)
3301 count = 0;
3302 else
3303 count = xmlOutputBufferFlush(writer->out);
3304
3305 return count;
3306}
3307
3308/**
3309 * misc
3310 */
3311
3312/**
3313 * xmlFreeTextWriterStackEntry:
3314 * @lk: the xmlLinkPtr
3315 *
3316 * Free callback for the xmlList.
3317 */
3318static void
3319xmlFreeTextWriterStackEntry(xmlLinkPtr lk)
3320{
3321 xmlTextWriterStackEntry *p;
3322
3323 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3324 if (p == 0)
3325 return;
3326
3327 if (p->name != 0)
3328 xmlFree(p->name);
3329 xmlFree(p);
3330}
3331
3332/**
3333 * xmlCmpTextWriterStackEntry:
3334 * @data0: the first data
3335 * @data1: the second data
3336 *
3337 * Compare callback for the xmlList.
3338 *
3339 * Returns -1, 0, 1
3340 */
3341static int
3342xmlCmpTextWriterStackEntry(const void *data0, const void *data1)
3343{
3344 xmlTextWriterStackEntry *p0;
3345 xmlTextWriterStackEntry *p1;
3346
3347 if (data0 == data1)
3348 return 0;
3349
3350 if (data0 == 0)
3351 return -1;
3352
3353 if (data1 == 0)
3354 return 1;
3355
3356 p0 = (xmlTextWriterStackEntry *) data0;
3357 p1 = (xmlTextWriterStackEntry *) data1;
3358
3359 return xmlStrcmp(p0->name, p1->name);
3360}
3361
3362/**
3363 * misc
3364 */
3365
3366/**
3367 * xmlFreeTextWriterNsStackEntry:
3368 * @lk: the xmlLinkPtr
3369 *
3370 * Free callback for the xmlList.
3371 */
3372static void
3373xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk)
3374{
3375 xmlTextWriterNsStackEntry *p;
3376
3377 p = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
3378 if (p == 0)
3379 return;
3380
3381 if (p->prefix != 0)
3382 xmlFree(p->prefix);
3383 if (p->uri != 0)
3384 xmlFree(p->uri);
3385
3386 xmlFree(p);
3387}
3388
3389/**
3390 * xmlCmpTextWriterNsStackEntry:
3391 * @data0: the first data
3392 * @data1: the second data
3393 *
3394 * Compare callback for the xmlList.
3395 *
3396 * Returns -1, 0, 1
3397 */
3398static int
3399xmlCmpTextWriterNsStackEntry(const void *data0, const void *data1)
3400{
3401 xmlTextWriterNsStackEntry *p0;
3402 xmlTextWriterNsStackEntry *p1;
3403 int rc;
3404
3405 if (data0 == data1)
3406 return 0;
3407
3408 if (data0 == 0)
3409 return -1;
3410
3411 if (data1 == 0)
3412 return 1;
3413
3414 p0 = (xmlTextWriterNsStackEntry *) data0;
3415 p1 = (xmlTextWriterNsStackEntry *) data1;
3416
3417 rc = xmlStrcmp(p0->prefix, p1->prefix);
3418
3419 if (rc == 0)
3420 rc = p0->elem == p1->elem;
3421
3422 return rc;
3423}
3424
3425/**
3426 * xmlTextWriterWriteMemCallback:
3427 * @context: the xmlBufferPtr
3428 * @str: the data to write
3429 * @len: the length of the data
3430 *
3431 * Write callback for the xmlOutputBuffer with target xmlBuffer
3432 *
3433 * Returns -1, 0, 1
3434 */
3435static int
3436xmlTextWriterWriteMemCallback(void *context, const xmlChar * str, int len)
3437{
3438 xmlBufferPtr buf = (xmlBufferPtr) context;
3439
3440 xmlBufferAdd(buf, str, len);
3441
3442 return len;
3443}
3444
3445/**
3446 * xmlTextWriterCloseMemCallback:
3447 * @context: the xmlBufferPtr
3448 *
3449 * Close callback for the xmlOutputBuffer with target xmlBuffer
3450 *
3451 * Returns -1, 0, 1
3452 */
3453static int
3454xmlTextWriterCloseMemCallback(void *context ATTRIBUTE_UNUSED)
3455{
3456 return 0;
3457}
3458
3459/**
3460 * xmlTextWriterVSprintf:
3461 * @format: see printf
3462 * @argptr: pointer to the first member of the variable argument list.
3463 *
3464 * Utility function for formatted output
3465 *
3466 * Returns a new xmlChar buffer with the data or NULL on error. This buffer must be freed.
3467 */
3468static xmlChar *
3469xmlTextWriterVSprintf(const char *format, va_list argptr)
3470{
3471 int size;
3472 int count;
3473 xmlChar *buf;
3474
3475 size = BUFSIZ;
3476 buf = (xmlChar *) xmlMalloc(size);
3477 if (buf == NULL) {
3478 xmlGenericError(xmlGenericErrorContext,
3479 "xmlTextWriterVSprintf : out of memory!\n");
3480 return NULL;
3481 }
3482
3483 while (((count = vsnprintf((char *) buf, size, format, argptr)) < 0)
3484 || (count == size - 1) || (count == size) || (count > size)) {
3485 xmlFree(buf);
3486 size += BUFSIZ;
3487 buf = (xmlChar *) xmlMalloc(size);
3488 if (buf == NULL) {
3489 xmlGenericError(xmlGenericErrorContext,
3490 "xmlTextWriterVSprintf : out of memory!\n");
3491 return NULL;
3492 }
3493 }
3494
3495 return buf;
3496}
3497
3498#endif