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