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