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