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