[CRT] spawn: define a unicode environment when needed
[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 xmlChar * 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((xmlListDeallocator)
194 xmlFreeTextWriterStackEntry,
195 (xmlListDataCompare)
196 xmlCmpTextWriterStackEntry);
197 if (ret->nodes == NULL) {
198 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
199 "xmlNewTextWriter : out of memory!\n");
200 xmlFree(ret);
201 return NULL;
202 }
203
204 ret->nsstack = xmlListCreate((xmlListDeallocator)
205 xmlFreeTextWriterNsStackEntry,
206 (xmlListDataCompare)
207 xmlCmpTextWriterNsStackEntry);
208 if (ret->nsstack == NULL) {
209 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
210 "xmlNewTextWriter : out of memory!\n");
211 xmlListDelete(ret->nodes);
212 xmlFree(ret);
213 return NULL;
214 }
215
216 ret->out = out;
217 ret->ichar = xmlStrdup(BAD_CAST " ");
218 ret->qchar = '"';
219
220 if (!ret->ichar) {
221 xmlListDelete(ret->nodes);
222 xmlListDelete(ret->nsstack);
223 xmlFree(ret);
224 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
225 "xmlNewTextWriter : out of memory!\n");
226 return NULL;
227 }
228
229 ret->doc = xmlNewDoc(NULL);
230
231 ret->no_doc_free = 0;
232
233 return ret;
234 }
235
236 /**
237 * xmlNewTextWriterFilename:
238 * @uri: the URI of the resource for the output
239 * @compression: compress the output?
240 *
241 * Create a new xmlNewTextWriter structure with @uri as output
242 *
243 * Returns the new xmlTextWriterPtr or NULL in case of error
244 */
245 xmlTextWriterPtr
246 xmlNewTextWriterFilename(const char *uri, int compression)
247 {
248 xmlTextWriterPtr ret;
249 xmlOutputBufferPtr out;
250
251 out = xmlOutputBufferCreateFilename(uri, NULL, compression);
252 if (out == NULL) {
253 xmlWriterErrMsg(NULL, XML_IO_EIO,
254 "xmlNewTextWriterFilename : cannot open uri\n");
255 return NULL;
256 }
257
258 ret = xmlNewTextWriter(out);
259 if (ret == NULL) {
260 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
261 "xmlNewTextWriterFilename : out of memory!\n");
262 xmlOutputBufferClose(out);
263 return NULL;
264 }
265
266 ret->indent = 0;
267 ret->doindent = 0;
268 return ret;
269 }
270
271 /**
272 * xmlNewTextWriterMemory:
273 * @buf: xmlBufferPtr
274 * @compression: compress the output?
275 *
276 * Create a new xmlNewTextWriter structure with @buf as output
277 * TODO: handle compression
278 *
279 * Returns the new xmlTextWriterPtr or NULL in case of error
280 */
281 xmlTextWriterPtr
282 xmlNewTextWriterMemory(xmlBufferPtr buf, int compression ATTRIBUTE_UNUSED)
283 {
284 xmlTextWriterPtr ret;
285 xmlOutputBufferPtr out;
286
287 /*::todo handle compression */
288 out = xmlOutputBufferCreateBuffer(buf, NULL);
289
290 if (out == NULL) {
291 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
292 "xmlNewTextWriterMemory : out of memory!\n");
293 return NULL;
294 }
295
296 ret = xmlNewTextWriter(out);
297 if (ret == NULL) {
298 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
299 "xmlNewTextWriterMemory : out of memory!\n");
300 xmlOutputBufferClose(out);
301 return NULL;
302 }
303
304 return ret;
305 }
306
307 /**
308 * xmlNewTextWriterPushParser:
309 * @ctxt: xmlParserCtxtPtr to hold the new XML document tree
310 * @compression: compress the output?
311 *
312 * Create a new xmlNewTextWriter structure with @ctxt as output
313 * NOTE: the @ctxt context will be freed with the resulting writer
314 * (if the call succeeds).
315 * TODO: handle compression
316 *
317 * Returns the new xmlTextWriterPtr or NULL in case of error
318 */
319 xmlTextWriterPtr
320 xmlNewTextWriterPushParser(xmlParserCtxtPtr ctxt,
321 int compression ATTRIBUTE_UNUSED)
322 {
323 xmlTextWriterPtr ret;
324 xmlOutputBufferPtr out;
325
326 if (ctxt == NULL) {
327 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
328 "xmlNewTextWriterPushParser : invalid context!\n");
329 return NULL;
330 }
331
332 out = xmlOutputBufferCreateIO((xmlOutputWriteCallback)
333 xmlTextWriterWriteDocCallback,
334 (xmlOutputCloseCallback)
335 xmlTextWriterCloseDocCallback,
336 (void *) ctxt, NULL);
337 if (out == NULL) {
338 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
339 "xmlNewTextWriterPushParser : error at xmlOutputBufferCreateIO!\n");
340 return NULL;
341 }
342
343 ret = xmlNewTextWriter(out);
344 if (ret == NULL) {
345 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
346 "xmlNewTextWriterPushParser : error at xmlNewTextWriter!\n");
347 xmlOutputBufferClose(out);
348 return NULL;
349 }
350
351 ret->ctxt = ctxt;
352
353 return ret;
354 }
355
356 /**
357 * xmlNewTextWriterDoc:
358 * @doc: address of a xmlDocPtr to hold the new XML document tree
359 * @compression: compress the output?
360 *
361 * Create a new xmlNewTextWriter structure with @*doc as output
362 *
363 * Returns the new xmlTextWriterPtr or NULL in case of error
364 */
365 xmlTextWriterPtr
366 xmlNewTextWriterDoc(xmlDocPtr * doc, int compression)
367 {
368 xmlTextWriterPtr ret;
369 xmlSAXHandler saxHandler;
370 xmlParserCtxtPtr ctxt;
371
372 memset(&saxHandler, '\0', sizeof(saxHandler));
373 xmlSAX2InitDefaultSAXHandler(&saxHandler, 1);
374 saxHandler.startDocument = xmlTextWriterStartDocumentCallback;
375 saxHandler.startElement = xmlSAX2StartElement;
376 saxHandler.endElement = xmlSAX2EndElement;
377
378 ctxt = xmlCreatePushParserCtxt(&saxHandler, NULL, NULL, 0, NULL);
379 if (ctxt == NULL) {
380 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
381 "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\n");
382 return NULL;
383 }
384 /*
385 * For some reason this seems to completely break if node names
386 * are interned.
387 */
388 ctxt->dictNames = 0;
389
390 ctxt->myDoc = xmlNewDoc(BAD_CAST XML_DEFAULT_VERSION);
391 if (ctxt->myDoc == NULL) {
392 xmlFreeParserCtxt(ctxt);
393 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
394 "xmlNewTextWriterDoc : error at xmlNewDoc!\n");
395 return NULL;
396 }
397
398 ret = xmlNewTextWriterPushParser(ctxt, compression);
399 if (ret == NULL) {
400 xmlFreeDoc(ctxt->myDoc);
401 xmlFreeParserCtxt(ctxt);
402 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
403 "xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n");
404 return NULL;
405 }
406
407 xmlSetDocCompressMode(ctxt->myDoc, compression);
408
409 if (doc != NULL) {
410 *doc = ctxt->myDoc;
411 ret->no_doc_free = 1;
412 }
413
414 return ret;
415 }
416
417 /**
418 * xmlNewTextWriterTree:
419 * @doc: xmlDocPtr
420 * @node: xmlNodePtr or NULL for doc->children
421 * @compression: compress the output?
422 *
423 * Create a new xmlNewTextWriter structure with @doc as output
424 * starting at @node
425 *
426 * Returns the new xmlTextWriterPtr or NULL in case of error
427 */
428 xmlTextWriterPtr
429 xmlNewTextWriterTree(xmlDocPtr doc, xmlNodePtr node, int compression)
430 {
431 xmlTextWriterPtr ret;
432 xmlSAXHandler saxHandler;
433 xmlParserCtxtPtr ctxt;
434
435 if (doc == NULL) {
436 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
437 "xmlNewTextWriterTree : invalid document tree!\n");
438 return NULL;
439 }
440
441 memset(&saxHandler, '\0', sizeof(saxHandler));
442 xmlSAX2InitDefaultSAXHandler(&saxHandler, 1);
443 saxHandler.startDocument = xmlTextWriterStartDocumentCallback;
444 saxHandler.startElement = xmlSAX2StartElement;
445 saxHandler.endElement = xmlSAX2EndElement;
446
447 ctxt = xmlCreatePushParserCtxt(&saxHandler, NULL, NULL, 0, NULL);
448 if (ctxt == NULL) {
449 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
450 "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\n");
451 return NULL;
452 }
453 /*
454 * For some reason this seems to completely break if node names
455 * are interned.
456 */
457 ctxt->dictNames = 0;
458
459 ret = xmlNewTextWriterPushParser(ctxt, compression);
460 if (ret == NULL) {
461 xmlFreeParserCtxt(ctxt);
462 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
463 "xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n");
464 return NULL;
465 }
466
467 ctxt->myDoc = doc;
468 ctxt->node = node;
469 ret->no_doc_free = 1;
470
471 xmlSetDocCompressMode(doc, compression);
472
473 return ret;
474 }
475
476 /**
477 * xmlFreeTextWriter:
478 * @writer: the xmlTextWriterPtr
479 *
480 * Deallocate all the resources associated to the writer
481 */
482 void
483 xmlFreeTextWriter(xmlTextWriterPtr writer)
484 {
485 if (writer == NULL)
486 return;
487
488 if (writer->out != NULL)
489 xmlOutputBufferClose(writer->out);
490
491 if (writer->nodes != NULL)
492 xmlListDelete(writer->nodes);
493
494 if (writer->nsstack != NULL)
495 xmlListDelete(writer->nsstack);
496
497 if (writer->ctxt != NULL) {
498 if ((writer->ctxt->myDoc != NULL) && (writer->no_doc_free == 0)) {
499 xmlFreeDoc(writer->ctxt->myDoc);
500 writer->ctxt->myDoc = NULL;
501 }
502 xmlFreeParserCtxt(writer->ctxt);
503 }
504
505 if (writer->doc != NULL)
506 xmlFreeDoc(writer->doc);
507
508 if (writer->ichar != NULL)
509 xmlFree(writer->ichar);
510 xmlFree(writer);
511 }
512
513 /**
514 * xmlTextWriterStartDocument:
515 * @writer: the xmlTextWriterPtr
516 * @version: the xml version ("1.0") or NULL for default ("1.0")
517 * @encoding: the encoding or NULL for default
518 * @standalone: "yes" or "no" or NULL for default
519 *
520 * Start a new xml document
521 *
522 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
523 */
524 int
525 xmlTextWriterStartDocument(xmlTextWriterPtr writer, const char *version,
526 const char *encoding, const char *standalone)
527 {
528 int count;
529 int sum;
530 xmlLinkPtr lk;
531 xmlCharEncodingHandlerPtr encoder;
532
533 if ((writer == NULL) || (writer->out == NULL)) {
534 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
535 "xmlTextWriterStartDocument : invalid writer!\n");
536 return -1;
537 }
538
539 lk = xmlListFront(writer->nodes);
540 if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) {
541 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
542 "xmlTextWriterStartDocument : not allowed in this context!\n");
543 return -1;
544 }
545
546 encoder = NULL;
547 if (encoding != NULL) {
548 encoder = xmlFindCharEncodingHandler(encoding);
549 if (encoder == NULL) {
550 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
551 "xmlTextWriterStartDocument : out of memory!\n");
552 return -1;
553 }
554 }
555
556 writer->out->encoder = encoder;
557 if (encoder != NULL) {
558 if (writer->out->conv == NULL) {
559 writer->out->conv = xmlBufCreateSize(4000);
560 }
561 xmlCharEncOutput(writer->out, 1);
562 if ((writer->doc != NULL) && (writer->doc->encoding == NULL))
563 writer->doc->encoding = xmlStrdup((xmlChar *)writer->out->encoder->name);
564 } else
565 writer->out->conv = NULL;
566
567 sum = 0;
568 count = xmlOutputBufferWriteString(writer->out, "<?xml version=");
569 if (count < 0)
570 return -1;
571 sum += count;
572 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
573 if (count < 0)
574 return -1;
575 sum += count;
576 if (version != 0)
577 count = xmlOutputBufferWriteString(writer->out, version);
578 else
579 count = xmlOutputBufferWriteString(writer->out, "1.0");
580 if (count < 0)
581 return -1;
582 sum += count;
583 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
584 if (count < 0)
585 return -1;
586 sum += count;
587 if (writer->out->encoder != 0) {
588 count = xmlOutputBufferWriteString(writer->out, " encoding=");
589 if (count < 0)
590 return -1;
591 sum += count;
592 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
593 if (count < 0)
594 return -1;
595 sum += count;
596 count =
597 xmlOutputBufferWriteString(writer->out,
598 writer->out->encoder->name);
599 if (count < 0)
600 return -1;
601 sum += count;
602 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
603 if (count < 0)
604 return -1;
605 sum += count;
606 }
607
608 if (standalone != 0) {
609 count = xmlOutputBufferWriteString(writer->out, " standalone=");
610 if (count < 0)
611 return -1;
612 sum += count;
613 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
614 if (count < 0)
615 return -1;
616 sum += count;
617 count = xmlOutputBufferWriteString(writer->out, standalone);
618 if (count < 0)
619 return -1;
620 sum += count;
621 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
622 if (count < 0)
623 return -1;
624 sum += count;
625 }
626
627 count = xmlOutputBufferWriteString(writer->out, "?>\n");
628 if (count < 0)
629 return -1;
630 sum += count;
631
632 return sum;
633 }
634
635 /**
636 * xmlTextWriterEndDocument:
637 * @writer: the xmlTextWriterPtr
638 *
639 * End an xml document. All open elements are closed, and
640 * the content is flushed to the output.
641 *
642 * Returns the bytes written or -1 in case of error
643 */
644 int
645 xmlTextWriterEndDocument(xmlTextWriterPtr writer)
646 {
647 int count;
648 int sum;
649 xmlLinkPtr lk;
650 xmlTextWriterStackEntry *p;
651
652 if (writer == NULL) {
653 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
654 "xmlTextWriterEndDocument : invalid writer!\n");
655 return -1;
656 }
657
658 sum = 0;
659 while ((lk = xmlListFront(writer->nodes)) != NULL) {
660 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
661 if (p == 0)
662 break;
663 switch (p->state) {
664 case XML_TEXTWRITER_NAME:
665 case XML_TEXTWRITER_ATTRIBUTE:
666 case XML_TEXTWRITER_TEXT:
667 count = xmlTextWriterEndElement(writer);
668 if (count < 0)
669 return -1;
670 sum += count;
671 break;
672 case XML_TEXTWRITER_PI:
673 case XML_TEXTWRITER_PI_TEXT:
674 count = xmlTextWriterEndPI(writer);
675 if (count < 0)
676 return -1;
677 sum += count;
678 break;
679 case XML_TEXTWRITER_CDATA:
680 count = xmlTextWriterEndCDATA(writer);
681 if (count < 0)
682 return -1;
683 sum += count;
684 break;
685 case XML_TEXTWRITER_DTD:
686 case XML_TEXTWRITER_DTD_TEXT:
687 case XML_TEXTWRITER_DTD_ELEM:
688 case XML_TEXTWRITER_DTD_ELEM_TEXT:
689 case XML_TEXTWRITER_DTD_ATTL:
690 case XML_TEXTWRITER_DTD_ATTL_TEXT:
691 case XML_TEXTWRITER_DTD_ENTY:
692 case XML_TEXTWRITER_DTD_ENTY_TEXT:
693 case XML_TEXTWRITER_DTD_PENT:
694 count = xmlTextWriterEndDTD(writer);
695 if (count < 0)
696 return -1;
697 sum += count;
698 break;
699 case XML_TEXTWRITER_COMMENT:
700 count = xmlTextWriterEndComment(writer);
701 if (count < 0)
702 return -1;
703 sum += count;
704 break;
705 default:
706 break;
707 }
708 }
709
710 if (!writer->indent) {
711 count = xmlOutputBufferWriteString(writer->out, "\n");
712 if (count < 0)
713 return -1;
714 sum += count;
715 }
716
717 sum += xmlTextWriterFlush(writer);
718
719 return sum;
720 }
721
722 /**
723 * xmlTextWriterStartComment:
724 * @writer: the xmlTextWriterPtr
725 *
726 * Start an xml comment.
727 *
728 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
729 */
730 int
731 xmlTextWriterStartComment(xmlTextWriterPtr writer)
732 {
733 int count;
734 int sum;
735 xmlLinkPtr lk;
736 xmlTextWriterStackEntry *p;
737
738 if (writer == NULL) {
739 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
740 "xmlTextWriterStartComment : invalid writer!\n");
741 return -1;
742 }
743
744 sum = 0;
745 lk = xmlListFront(writer->nodes);
746 if (lk != 0) {
747 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
748 if (p != 0) {
749 switch (p->state) {
750 case XML_TEXTWRITER_TEXT:
751 case XML_TEXTWRITER_NONE:
752 break;
753 case XML_TEXTWRITER_NAME:
754 /* Output namespace declarations */
755 count = xmlTextWriterOutputNSDecl(writer);
756 if (count < 0)
757 return -1;
758 sum += count;
759 count = xmlOutputBufferWriteString(writer->out, ">");
760 if (count < 0)
761 return -1;
762 sum += count;
763 if (writer->indent) {
764 count =
765 xmlOutputBufferWriteString(writer->out, "\n");
766 if (count < 0)
767 return -1;
768 sum += count;
769 }
770 p->state = XML_TEXTWRITER_TEXT;
771 break;
772 default:
773 return -1;
774 }
775 }
776 }
777
778 p = (xmlTextWriterStackEntry *)
779 xmlMalloc(sizeof(xmlTextWriterStackEntry));
780 if (p == 0) {
781 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
782 "xmlTextWriterStartElement : out of memory!\n");
783 return -1;
784 }
785
786 p->name = NULL;
787 p->state = XML_TEXTWRITER_COMMENT;
788
789 xmlListPushFront(writer->nodes, p);
790
791 if (writer->indent) {
792 count = xmlTextWriterWriteIndent(writer);
793 if (count < 0)
794 return -1;
795 sum += count;
796 }
797
798 count = xmlOutputBufferWriteString(writer->out, "<!--");
799 if (count < 0)
800 return -1;
801 sum += count;
802
803 return sum;
804 }
805
806 /**
807 * xmlTextWriterEndComment:
808 * @writer: the xmlTextWriterPtr
809 *
810 * End the current xml coment.
811 *
812 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
813 */
814 int
815 xmlTextWriterEndComment(xmlTextWriterPtr writer)
816 {
817 int count;
818 int sum;
819 xmlLinkPtr lk;
820 xmlTextWriterStackEntry *p;
821
822 if (writer == NULL) {
823 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
824 "xmlTextWriterEndComment : invalid writer!\n");
825 return -1;
826 }
827
828 lk = xmlListFront(writer->nodes);
829 if (lk == 0) {
830 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
831 "xmlTextWriterEndComment : not allowed in this context!\n");
832 return -1;
833 }
834
835 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
836 if (p == 0)
837 return -1;
838
839 sum = 0;
840 switch (p->state) {
841 case XML_TEXTWRITER_COMMENT:
842 count = xmlOutputBufferWriteString(writer->out, "-->");
843 if (count < 0)
844 return -1;
845 sum += count;
846 break;
847 default:
848 return -1;
849 }
850
851 if (writer->indent) {
852 count = xmlOutputBufferWriteString(writer->out, "\n");
853 if (count < 0)
854 return -1;
855 sum += count;
856 }
857
858 xmlListPopFront(writer->nodes);
859 return sum;
860 }
861
862 /**
863 * xmlTextWriterWriteFormatComment:
864 * @writer: the xmlTextWriterPtr
865 * @format: format string (see printf)
866 * @...: extra parameters for the format
867 *
868 * Write an xml comment.
869 *
870 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
871 */
872 int XMLCDECL
873 xmlTextWriterWriteFormatComment(xmlTextWriterPtr writer,
874 const char *format, ...)
875 {
876 int rc;
877 va_list ap;
878
879 va_start(ap, format);
880
881 rc = xmlTextWriterWriteVFormatComment(writer, format, ap);
882
883 va_end(ap);
884 return rc;
885 }
886
887 /**
888 * xmlTextWriterWriteVFormatComment:
889 * @writer: the xmlTextWriterPtr
890 * @format: format string (see printf)
891 * @argptr: pointer to the first member of the variable argument list.
892 *
893 * Write an xml comment.
894 *
895 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
896 */
897 int
898 xmlTextWriterWriteVFormatComment(xmlTextWriterPtr writer,
899 const char *format, va_list argptr)
900 {
901 int rc;
902 xmlChar *buf;
903
904 if (writer == NULL) {
905 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
906 "xmlTextWriterWriteVFormatComment : invalid writer!\n");
907 return -1;
908 }
909
910 buf = xmlTextWriterVSprintf(format, argptr);
911 if (buf == NULL)
912 return -1;
913
914 rc = xmlTextWriterWriteComment(writer, buf);
915
916 xmlFree(buf);
917 return rc;
918 }
919
920 /**
921 * xmlTextWriterWriteComment:
922 * @writer: the xmlTextWriterPtr
923 * @content: comment string
924 *
925 * Write an xml comment.
926 *
927 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
928 */
929 int
930 xmlTextWriterWriteComment(xmlTextWriterPtr writer, const xmlChar * content)
931 {
932 int count;
933 int sum;
934
935 sum = 0;
936 count = xmlTextWriterStartComment(writer);
937 if (count < 0)
938 return -1;
939 sum += count;
940 count = xmlTextWriterWriteString(writer, content);
941 if (count < 0)
942 return -1;
943 sum += count;
944 count = xmlTextWriterEndComment(writer);
945 if (count < 0)
946 return -1;
947 sum += count;
948
949 return sum;
950 }
951
952 /**
953 * xmlTextWriterStartElement:
954 * @writer: the xmlTextWriterPtr
955 * @name: element name
956 *
957 * Start an xml element.
958 *
959 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
960 */
961 int
962 xmlTextWriterStartElement(xmlTextWriterPtr writer, const xmlChar * name)
963 {
964 int count;
965 int sum;
966 xmlLinkPtr lk;
967 xmlTextWriterStackEntry *p;
968
969 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
970 return -1;
971
972 sum = 0;
973 lk = xmlListFront(writer->nodes);
974 if (lk != 0) {
975 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
976 if (p != 0) {
977 switch (p->state) {
978 case XML_TEXTWRITER_PI:
979 case XML_TEXTWRITER_PI_TEXT:
980 return -1;
981 case XML_TEXTWRITER_NONE:
982 break;
983 case XML_TEXTWRITER_ATTRIBUTE:
984 count = xmlTextWriterEndAttribute(writer);
985 if (count < 0)
986 return -1;
987 sum += count;
988 /* fallthrough */
989 case XML_TEXTWRITER_NAME:
990 /* Output namespace declarations */
991 count = xmlTextWriterOutputNSDecl(writer);
992 if (count < 0)
993 return -1;
994 sum += count;
995 count = xmlOutputBufferWriteString(writer->out, ">");
996 if (count < 0)
997 return -1;
998 sum += count;
999 if (writer->indent)
1000 count =
1001 xmlOutputBufferWriteString(writer->out, "\n");
1002 p->state = XML_TEXTWRITER_TEXT;
1003 break;
1004 default:
1005 break;
1006 }
1007 }
1008 }
1009
1010 p = (xmlTextWriterStackEntry *)
1011 xmlMalloc(sizeof(xmlTextWriterStackEntry));
1012 if (p == 0) {
1013 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
1014 "xmlTextWriterStartElement : out of memory!\n");
1015 return -1;
1016 }
1017
1018 p->name = xmlStrdup(name);
1019 if (p->name == 0) {
1020 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
1021 "xmlTextWriterStartElement : out of memory!\n");
1022 xmlFree(p);
1023 return -1;
1024 }
1025 p->state = XML_TEXTWRITER_NAME;
1026
1027 xmlListPushFront(writer->nodes, p);
1028
1029 if (writer->indent) {
1030 count = xmlTextWriterWriteIndent(writer);
1031 sum += count;
1032 }
1033
1034 count = xmlOutputBufferWriteString(writer->out, "<");
1035 if (count < 0)
1036 return -1;
1037 sum += count;
1038 count =
1039 xmlOutputBufferWriteString(writer->out, (const char *) p->name);
1040 if (count < 0)
1041 return -1;
1042 sum += count;
1043
1044 return sum;
1045 }
1046
1047 /**
1048 * xmlTextWriterStartElementNS:
1049 * @writer: the xmlTextWriterPtr
1050 * @prefix: namespace prefix or NULL
1051 * @name: element local name
1052 * @namespaceURI: namespace URI or NULL
1053 *
1054 * Start an xml element with namespace support.
1055 *
1056 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1057 */
1058 int
1059 xmlTextWriterStartElementNS(xmlTextWriterPtr writer,
1060 const xmlChar * prefix, const xmlChar * name,
1061 const xmlChar * namespaceURI)
1062 {
1063 int count;
1064 int sum;
1065 xmlChar *buf;
1066
1067 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1068 return -1;
1069
1070 buf = NULL;
1071 if (prefix != 0) {
1072 buf = xmlStrdup(prefix);
1073 buf = xmlStrcat(buf, BAD_CAST ":");
1074 }
1075 buf = xmlStrcat(buf, name);
1076
1077 sum = 0;
1078 count = xmlTextWriterStartElement(writer, buf);
1079 xmlFree(buf);
1080 if (count < 0)
1081 return -1;
1082 sum += count;
1083
1084 if (namespaceURI != 0) {
1085 xmlTextWriterNsStackEntry *p = (xmlTextWriterNsStackEntry *)
1086 xmlMalloc(sizeof(xmlTextWriterNsStackEntry));
1087 if (p == 0) {
1088 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
1089 "xmlTextWriterStartElementNS : out of memory!\n");
1090 return -1;
1091 }
1092
1093 buf = xmlStrdup(BAD_CAST "xmlns");
1094 if (prefix != 0) {
1095 buf = xmlStrcat(buf, BAD_CAST ":");
1096 buf = xmlStrcat(buf, prefix);
1097 }
1098
1099 p->prefix = buf;
1100 p->uri = xmlStrdup(namespaceURI);
1101 if (p->uri == 0) {
1102 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
1103 "xmlTextWriterStartElementNS : out of memory!\n");
1104 xmlFree(p);
1105 return -1;
1106 }
1107 p->elem = xmlListFront(writer->nodes);
1108
1109 xmlListPushFront(writer->nsstack, p);
1110 }
1111
1112 return sum;
1113 }
1114
1115 /**
1116 * xmlTextWriterEndElement:
1117 * @writer: the xmlTextWriterPtr
1118 *
1119 * End the current xml element.
1120 *
1121 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1122 */
1123 int
1124 xmlTextWriterEndElement(xmlTextWriterPtr writer)
1125 {
1126 int count;
1127 int sum;
1128 xmlLinkPtr lk;
1129 xmlTextWriterStackEntry *p;
1130
1131 if (writer == NULL)
1132 return -1;
1133
1134 lk = xmlListFront(writer->nodes);
1135 if (lk == 0) {
1136 xmlListDelete(writer->nsstack);
1137 writer->nsstack = NULL;
1138 return -1;
1139 }
1140
1141 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1142 if (p == 0) {
1143 xmlListDelete(writer->nsstack);
1144 writer->nsstack = NULL;
1145 return -1;
1146 }
1147
1148 sum = 0;
1149 switch (p->state) {
1150 case XML_TEXTWRITER_ATTRIBUTE:
1151 count = xmlTextWriterEndAttribute(writer);
1152 if (count < 0) {
1153 xmlListDelete(writer->nsstack);
1154 writer->nsstack = NULL;
1155 return -1;
1156 }
1157 sum += count;
1158 /* fallthrough */
1159 case XML_TEXTWRITER_NAME:
1160 /* Output namespace declarations */
1161 count = xmlTextWriterOutputNSDecl(writer);
1162 if (count < 0)
1163 return -1;
1164 sum += count;
1165
1166 if (writer->indent) /* next element needs indent */
1167 writer->doindent = 1;
1168 count = xmlOutputBufferWriteString(writer->out, "/>");
1169 if (count < 0)
1170 return -1;
1171 sum += count;
1172 break;
1173 case XML_TEXTWRITER_TEXT:
1174 if ((writer->indent) && (writer->doindent)) {
1175 count = xmlTextWriterWriteIndent(writer);
1176 sum += count;
1177 writer->doindent = 1;
1178 } else
1179 writer->doindent = 1;
1180 count = xmlOutputBufferWriteString(writer->out, "</");
1181 if (count < 0)
1182 return -1;
1183 sum += count;
1184 count = xmlOutputBufferWriteString(writer->out,
1185 (const char *) p->name);
1186 if (count < 0)
1187 return -1;
1188 sum += count;
1189 count = xmlOutputBufferWriteString(writer->out, ">");
1190 if (count < 0)
1191 return -1;
1192 sum += count;
1193 break;
1194 default:
1195 return -1;
1196 }
1197
1198 if (writer->indent) {
1199 count = xmlOutputBufferWriteString(writer->out, "\n");
1200 sum += count;
1201 }
1202
1203 xmlListPopFront(writer->nodes);
1204 return sum;
1205 }
1206
1207 /**
1208 * xmlTextWriterFullEndElement:
1209 * @writer: the xmlTextWriterPtr
1210 *
1211 * End the current xml element. Writes an end tag even if the element is empty
1212 *
1213 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1214 */
1215 int
1216 xmlTextWriterFullEndElement(xmlTextWriterPtr writer)
1217 {
1218 int count;
1219 int sum;
1220 xmlLinkPtr lk;
1221 xmlTextWriterStackEntry *p;
1222
1223 if (writer == NULL)
1224 return -1;
1225
1226 lk = xmlListFront(writer->nodes);
1227 if (lk == 0)
1228 return -1;
1229
1230 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1231 if (p == 0)
1232 return -1;
1233
1234 sum = 0;
1235 switch (p->state) {
1236 case XML_TEXTWRITER_ATTRIBUTE:
1237 count = xmlTextWriterEndAttribute(writer);
1238 if (count < 0)
1239 return -1;
1240 sum += count;
1241 /* fallthrough */
1242 case XML_TEXTWRITER_NAME:
1243 /* Output namespace declarations */
1244 count = xmlTextWriterOutputNSDecl(writer);
1245 if (count < 0)
1246 return -1;
1247 sum += count;
1248
1249 count = xmlOutputBufferWriteString(writer->out, ">");
1250 if (count < 0)
1251 return -1;
1252 sum += count;
1253 if (writer->indent)
1254 writer->doindent = 0;
1255 /* fallthrough */
1256 case XML_TEXTWRITER_TEXT:
1257 if ((writer->indent) && (writer->doindent)) {
1258 count = xmlTextWriterWriteIndent(writer);
1259 sum += count;
1260 writer->doindent = 1;
1261 } else
1262 writer->doindent = 1;
1263 count = xmlOutputBufferWriteString(writer->out, "</");
1264 if (count < 0)
1265 return -1;
1266 sum += count;
1267 count = xmlOutputBufferWriteString(writer->out,
1268 (const char *) p->name);
1269 if (count < 0)
1270 return -1;
1271 sum += count;
1272 count = xmlOutputBufferWriteString(writer->out, ">");
1273 if (count < 0)
1274 return -1;
1275 sum += count;
1276 break;
1277 default:
1278 return -1;
1279 }
1280
1281 if (writer->indent) {
1282 count = xmlOutputBufferWriteString(writer->out, "\n");
1283 sum += count;
1284 }
1285
1286 xmlListPopFront(writer->nodes);
1287 return sum;
1288 }
1289
1290 /**
1291 * xmlTextWriterWriteFormatRaw:
1292 * @writer: the xmlTextWriterPtr
1293 * @format: format string (see printf)
1294 * @...: extra parameters for the format
1295 *
1296 * Write a formatted raw xml text.
1297 *
1298 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1299 */
1300 int XMLCDECL
1301 xmlTextWriterWriteFormatRaw(xmlTextWriterPtr writer, const char *format,
1302 ...)
1303 {
1304 int rc;
1305 va_list ap;
1306
1307 va_start(ap, format);
1308
1309 rc = xmlTextWriterWriteVFormatRaw(writer, format, ap);
1310
1311 va_end(ap);
1312 return rc;
1313 }
1314
1315 /**
1316 * xmlTextWriterWriteVFormatRaw:
1317 * @writer: the xmlTextWriterPtr
1318 * @format: format string (see printf)
1319 * @argptr: pointer to the first member of the variable argument list.
1320 *
1321 * Write a formatted raw xml text.
1322 *
1323 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1324 */
1325 int
1326 xmlTextWriterWriteVFormatRaw(xmlTextWriterPtr writer, const char *format,
1327 va_list argptr)
1328 {
1329 int rc;
1330 xmlChar *buf;
1331
1332 if (writer == NULL)
1333 return -1;
1334
1335 buf = xmlTextWriterVSprintf(format, argptr);
1336 if (buf == NULL)
1337 return -1;
1338
1339 rc = xmlTextWriterWriteRaw(writer, buf);
1340
1341 xmlFree(buf);
1342 return rc;
1343 }
1344
1345 /**
1346 * xmlTextWriterWriteRawLen:
1347 * @writer: the xmlTextWriterPtr
1348 * @content: text string
1349 * @len: length of the text string
1350 *
1351 * Write an xml text.
1352 * TODO: what about entities and special chars??
1353 *
1354 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1355 */
1356 int
1357 xmlTextWriterWriteRawLen(xmlTextWriterPtr writer, const xmlChar * content,
1358 int len)
1359 {
1360 int count;
1361 int sum;
1362 xmlLinkPtr lk;
1363 xmlTextWriterStackEntry *p;
1364
1365 if (writer == NULL) {
1366 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
1367 "xmlTextWriterWriteRawLen : invalid writer!\n");
1368 return -1;
1369 }
1370
1371 if ((content == NULL) || (len < 0)) {
1372 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
1373 "xmlTextWriterWriteRawLen : invalid content!\n");
1374 return -1;
1375 }
1376
1377 sum = 0;
1378 lk = xmlListFront(writer->nodes);
1379 if (lk != 0) {
1380 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1381 count = xmlTextWriterHandleStateDependencies(writer, p);
1382 if (count < 0)
1383 return -1;
1384 sum += count;
1385 }
1386
1387 if (writer->indent)
1388 writer->doindent = 0;
1389
1390 if (content != NULL) {
1391 count =
1392 xmlOutputBufferWrite(writer->out, len, (const char *) content);
1393 if (count < 0)
1394 return -1;
1395 sum += count;
1396 }
1397
1398 return sum;
1399 }
1400
1401 /**
1402 * xmlTextWriterWriteRaw:
1403 * @writer: the xmlTextWriterPtr
1404 * @content: text string
1405 *
1406 * Write a raw xml text.
1407 *
1408 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1409 */
1410 int
1411 xmlTextWriterWriteRaw(xmlTextWriterPtr writer, const xmlChar * content)
1412 {
1413 return xmlTextWriterWriteRawLen(writer, content, xmlStrlen(content));
1414 }
1415
1416 /**
1417 * xmlTextWriterWriteFormatString:
1418 * @writer: the xmlTextWriterPtr
1419 * @format: format string (see printf)
1420 * @...: extra parameters for the format
1421 *
1422 * Write a formatted xml text.
1423 *
1424 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1425 */
1426 int XMLCDECL
1427 xmlTextWriterWriteFormatString(xmlTextWriterPtr writer, const char *format,
1428 ...)
1429 {
1430 int rc;
1431 va_list ap;
1432
1433 if ((writer == NULL) || (format == NULL))
1434 return -1;
1435
1436 va_start(ap, format);
1437
1438 rc = xmlTextWriterWriteVFormatString(writer, format, ap);
1439
1440 va_end(ap);
1441 return rc;
1442 }
1443
1444 /**
1445 * xmlTextWriterWriteVFormatString:
1446 * @writer: the xmlTextWriterPtr
1447 * @format: format string (see printf)
1448 * @argptr: pointer to the first member of the variable argument list.
1449 *
1450 * Write a formatted xml text.
1451 *
1452 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1453 */
1454 int
1455 xmlTextWriterWriteVFormatString(xmlTextWriterPtr writer,
1456 const char *format, va_list argptr)
1457 {
1458 int rc;
1459 xmlChar *buf;
1460
1461 if ((writer == NULL) || (format == NULL))
1462 return -1;
1463
1464 buf = xmlTextWriterVSprintf(format, argptr);
1465 if (buf == NULL)
1466 return -1;
1467
1468 rc = xmlTextWriterWriteString(writer, buf);
1469
1470 xmlFree(buf);
1471 return rc;
1472 }
1473
1474 /**
1475 * xmlTextWriterWriteString:
1476 * @writer: the xmlTextWriterPtr
1477 * @content: text string
1478 *
1479 * Write an xml text.
1480 *
1481 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1482 */
1483 int
1484 xmlTextWriterWriteString(xmlTextWriterPtr writer, const xmlChar * content)
1485 {
1486 int count;
1487 int sum;
1488 xmlLinkPtr lk;
1489 xmlTextWriterStackEntry *p;
1490 xmlChar *buf;
1491
1492 if ((writer == NULL) || (content == NULL))
1493 return -1;
1494
1495 sum = 0;
1496 buf = (xmlChar *) content;
1497 lk = xmlListFront(writer->nodes);
1498 if (lk != 0) {
1499 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1500 if (p != 0) {
1501 switch (p->state) {
1502 case XML_TEXTWRITER_NAME:
1503 case XML_TEXTWRITER_TEXT:
1504 #if 0
1505 buf = NULL;
1506 xmlOutputBufferWriteEscape(writer->out, content, NULL);
1507 #endif
1508 buf = xmlEncodeSpecialChars(NULL, content);
1509 break;
1510 case XML_TEXTWRITER_ATTRIBUTE:
1511 buf = NULL;
1512 xmlBufAttrSerializeTxtContent(writer->out->buffer,
1513 writer->doc, NULL, content);
1514 break;
1515 default:
1516 break;
1517 }
1518 }
1519 }
1520
1521 if (buf != NULL) {
1522 count = xmlTextWriterWriteRaw(writer, buf);
1523
1524 if (buf != content) /* buf was allocated by us, so free it */
1525 xmlFree(buf);
1526
1527 if (count < 0)
1528 return -1;
1529 sum += count;
1530 }
1531
1532 return sum;
1533 }
1534
1535 /**
1536 * xmlOutputBufferWriteBase64:
1537 * @out: the xmlOutputBufferPtr
1538 * @data: binary data
1539 * @len: the number of bytes to encode
1540 *
1541 * Write base64 encoded data to an xmlOutputBuffer.
1542 * Adapted from John Walker's base64.c (http://www.fourmilab.ch/).
1543 *
1544 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1545 */
1546 static int
1547 xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len,
1548 const unsigned char *data)
1549 {
1550 static unsigned char dtable[64] =
1551 {'A','B','C','D','E','F','G','H','I','J','K','L','M',
1552 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
1553 'a','b','c','d','e','f','g','h','i','j','k','l','m',
1554 'n','o','p','q','r','s','t','u','v','w','x','y','z',
1555 '0','1','2','3','4','5','6','7','8','9','+','/'};
1556
1557 int i;
1558 int linelen;
1559 int count;
1560 int sum;
1561
1562 if ((out == NULL) || (len < 0) || (data == NULL))
1563 return(-1);
1564
1565 linelen = 0;
1566 sum = 0;
1567
1568 i = 0;
1569 while (1) {
1570 unsigned char igroup[3];
1571 unsigned char ogroup[4];
1572 int c;
1573 int n;
1574
1575 igroup[0] = igroup[1] = igroup[2] = 0;
1576 for (n = 0; n < 3 && i < len; n++, i++) {
1577 c = data[i];
1578 igroup[n] = (unsigned char) c;
1579 }
1580
1581 if (n > 0) {
1582 ogroup[0] = dtable[igroup[0] >> 2];
1583 ogroup[1] = dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)];
1584 ogroup[2] =
1585 dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)];
1586 ogroup[3] = dtable[igroup[2] & 0x3F];
1587
1588 if (n < 3) {
1589 ogroup[3] = '=';
1590 if (n < 2) {
1591 ogroup[2] = '=';
1592 }
1593 }
1594
1595 if (linelen >= B64LINELEN) {
1596 count = xmlOutputBufferWrite(out, 2, B64CRLF);
1597 if (count == -1)
1598 return -1;
1599 sum += count;
1600 linelen = 0;
1601 }
1602 count = xmlOutputBufferWrite(out, 4, (const char *) ogroup);
1603 if (count == -1)
1604 return -1;
1605 sum += count;
1606
1607 linelen += 4;
1608 }
1609
1610 if (i >= len)
1611 break;
1612 }
1613
1614 return sum;
1615 }
1616
1617 /**
1618 * xmlTextWriterWriteBase64:
1619 * @writer: the xmlTextWriterPtr
1620 * @data: binary data
1621 * @start: the position within the data of the first byte to encode
1622 * @len: the number of bytes to encode
1623 *
1624 * Write an base64 encoded xml text.
1625 *
1626 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1627 */
1628 int
1629 xmlTextWriterWriteBase64(xmlTextWriterPtr writer, const char *data,
1630 int start, int len)
1631 {
1632 int count;
1633 int sum;
1634 xmlLinkPtr lk;
1635 xmlTextWriterStackEntry *p;
1636
1637 if ((writer == NULL) || (data == NULL) || (start < 0) || (len < 0))
1638 return -1;
1639
1640 sum = 0;
1641 lk = xmlListFront(writer->nodes);
1642 if (lk != 0) {
1643 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1644 if (p != 0) {
1645 count = xmlTextWriterHandleStateDependencies(writer, p);
1646 if (count < 0)
1647 return -1;
1648 sum += count;
1649 }
1650 }
1651
1652 if (writer->indent)
1653 writer->doindent = 0;
1654
1655 count =
1656 xmlOutputBufferWriteBase64(writer->out, len,
1657 (unsigned char *) data + start);
1658 if (count < 0)
1659 return -1;
1660 sum += count;
1661
1662 return sum;
1663 }
1664
1665 /**
1666 * xmlOutputBufferWriteBinHex:
1667 * @out: the xmlOutputBufferPtr
1668 * @data: binary data
1669 * @len: the number of bytes to encode
1670 *
1671 * Write hqx encoded data to an xmlOutputBuffer.
1672 * ::todo
1673 *
1674 * Returns the bytes written (may be 0 because of buffering)
1675 * or -1 in case of error
1676 */
1677 static int
1678 xmlOutputBufferWriteBinHex(xmlOutputBufferPtr out,
1679 int len, const unsigned char *data)
1680 {
1681 int count;
1682 int sum;
1683 static char hex[16] =
1684 {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
1685 int i;
1686
1687 if ((out == NULL) || (data == NULL) || (len < 0)) {
1688 return -1;
1689 }
1690
1691 sum = 0;
1692 for (i = 0; i < len; i++) {
1693 count =
1694 xmlOutputBufferWrite(out, 1,
1695 (const char *) &hex[data[i] >> 4]);
1696 if (count == -1)
1697 return -1;
1698 sum += count;
1699 count =
1700 xmlOutputBufferWrite(out, 1,
1701 (const char *) &hex[data[i] & 0xF]);
1702 if (count == -1)
1703 return -1;
1704 sum += count;
1705 }
1706
1707 return sum;
1708 }
1709
1710 /**
1711 * xmlTextWriterWriteBinHex:
1712 * @writer: the xmlTextWriterPtr
1713 * @data: binary data
1714 * @start: the position within the data of the first byte to encode
1715 * @len: the number of bytes to encode
1716 *
1717 * Write a BinHex encoded xml text.
1718 *
1719 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1720 */
1721 int
1722 xmlTextWriterWriteBinHex(xmlTextWriterPtr writer, const char *data,
1723 int start, int len)
1724 {
1725 int count;
1726 int sum;
1727 xmlLinkPtr lk;
1728 xmlTextWriterStackEntry *p;
1729
1730 if ((writer == NULL) || (data == NULL) || (start < 0) || (len < 0))
1731 return -1;
1732
1733 sum = 0;
1734 lk = xmlListFront(writer->nodes);
1735 if (lk != 0) {
1736 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1737 if (p != 0) {
1738 count = xmlTextWriterHandleStateDependencies(writer, p);
1739 if (count < 0)
1740 return -1;
1741 sum += count;
1742 }
1743 }
1744
1745 if (writer->indent)
1746 writer->doindent = 0;
1747
1748 count =
1749 xmlOutputBufferWriteBinHex(writer->out, len,
1750 (unsigned char *) data + start);
1751 if (count < 0)
1752 return -1;
1753 sum += count;
1754
1755 return sum;
1756 }
1757
1758 /**
1759 * xmlTextWriterStartAttribute:
1760 * @writer: the xmlTextWriterPtr
1761 * @name: element name
1762 *
1763 * Start an xml attribute.
1764 *
1765 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1766 */
1767 int
1768 xmlTextWriterStartAttribute(xmlTextWriterPtr writer, const xmlChar * name)
1769 {
1770 int count;
1771 int sum;
1772 xmlLinkPtr lk;
1773 xmlTextWriterStackEntry *p;
1774
1775 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1776 return -1;
1777
1778 sum = 0;
1779 lk = xmlListFront(writer->nodes);
1780 if (lk == 0)
1781 return -1;
1782
1783 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1784 if (p == 0)
1785 return -1;
1786
1787 switch (p->state) {
1788 case XML_TEXTWRITER_ATTRIBUTE:
1789 count = xmlTextWriterEndAttribute(writer);
1790 if (count < 0)
1791 return -1;
1792 sum += count;
1793 /* fallthrough */
1794 case XML_TEXTWRITER_NAME:
1795 count = xmlOutputBufferWriteString(writer->out, " ");
1796 if (count < 0)
1797 return -1;
1798 sum += count;
1799 count =
1800 xmlOutputBufferWriteString(writer->out,
1801 (const char *) name);
1802 if (count < 0)
1803 return -1;
1804 sum += count;
1805 count = xmlOutputBufferWriteString(writer->out, "=");
1806 if (count < 0)
1807 return -1;
1808 sum += count;
1809 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
1810 if (count < 0)
1811 return -1;
1812 sum += count;
1813 p->state = XML_TEXTWRITER_ATTRIBUTE;
1814 break;
1815 default:
1816 return -1;
1817 }
1818
1819 return sum;
1820 }
1821
1822 /**
1823 * xmlTextWriterStartAttributeNS:
1824 * @writer: the xmlTextWriterPtr
1825 * @prefix: namespace prefix or NULL
1826 * @name: element local name
1827 * @namespaceURI: namespace URI or NULL
1828 *
1829 * Start an xml attribute with namespace support.
1830 *
1831 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1832 */
1833 int
1834 xmlTextWriterStartAttributeNS(xmlTextWriterPtr writer,
1835 const xmlChar * prefix, const xmlChar * name,
1836 const xmlChar * namespaceURI)
1837 {
1838 int count;
1839 int sum;
1840 xmlChar *buf;
1841 xmlTextWriterNsStackEntry *p;
1842
1843 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1844 return -1;
1845
1846 /* Handle namespace first in case of error */
1847 if (namespaceURI != 0) {
1848 xmlTextWriterNsStackEntry nsentry, *curns;
1849
1850 buf = xmlStrdup(BAD_CAST "xmlns");
1851 if (prefix != 0) {
1852 buf = xmlStrcat(buf, BAD_CAST ":");
1853 buf = xmlStrcat(buf, prefix);
1854 }
1855
1856 nsentry.prefix = buf;
1857 nsentry.uri = (xmlChar *)namespaceURI;
1858 nsentry.elem = xmlListFront(writer->nodes);
1859
1860 curns = (xmlTextWriterNsStackEntry *)xmlListSearch(writer->nsstack,
1861 (void *)&nsentry);
1862 if ((curns != NULL)) {
1863 xmlFree(buf);
1864 if (xmlStrcmp(curns->uri, namespaceURI) == 0) {
1865 /* Namespace already defined on element skip */
1866 buf = NULL;
1867 } else {
1868 /* Prefix mismatch so error out */
1869 return -1;
1870 }
1871 }
1872
1873 /* Do not add namespace decl to list - it is already there */
1874 if (buf != NULL) {
1875 p = (xmlTextWriterNsStackEntry *)
1876 xmlMalloc(sizeof(xmlTextWriterNsStackEntry));
1877 if (p == 0) {
1878 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
1879 "xmlTextWriterStartAttributeNS : out of memory!\n");
1880 return -1;
1881 }
1882
1883 p->prefix = buf;
1884 p->uri = xmlStrdup(namespaceURI);
1885 if (p->uri == 0) {
1886 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
1887 "xmlTextWriterStartAttributeNS : out of memory!\n");
1888 xmlFree(p);
1889 return -1;
1890 }
1891 p->elem = xmlListFront(writer->nodes);
1892
1893 xmlListPushFront(writer->nsstack, p);
1894 }
1895 }
1896
1897 buf = NULL;
1898 if (prefix != 0) {
1899 buf = xmlStrdup(prefix);
1900 buf = xmlStrcat(buf, BAD_CAST ":");
1901 }
1902 buf = xmlStrcat(buf, name);
1903
1904 sum = 0;
1905 count = xmlTextWriterStartAttribute(writer, buf);
1906 xmlFree(buf);
1907 if (count < 0)
1908 return -1;
1909 sum += count;
1910
1911 return sum;
1912 }
1913
1914 /**
1915 * xmlTextWriterEndAttribute:
1916 * @writer: the xmlTextWriterPtr
1917 *
1918 * End the current xml element.
1919 *
1920 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1921 */
1922 int
1923 xmlTextWriterEndAttribute(xmlTextWriterPtr writer)
1924 {
1925 int count;
1926 int sum;
1927 xmlLinkPtr lk;
1928 xmlTextWriterStackEntry *p;
1929
1930 if (writer == NULL)
1931 return -1;
1932
1933 lk = xmlListFront(writer->nodes);
1934 if (lk == 0) {
1935 return -1;
1936 }
1937
1938 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1939 if (p == 0) {
1940 return -1;
1941 }
1942
1943 sum = 0;
1944 switch (p->state) {
1945 case XML_TEXTWRITER_ATTRIBUTE:
1946 p->state = XML_TEXTWRITER_NAME;
1947
1948 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
1949 if (count < 0) {
1950 return -1;
1951 }
1952 sum += count;
1953 break;
1954 default:
1955 return -1;
1956 }
1957
1958 return sum;
1959 }
1960
1961 /**
1962 * xmlTextWriterWriteFormatAttribute:
1963 * @writer: the xmlTextWriterPtr
1964 * @name: attribute name
1965 * @format: format string (see printf)
1966 * @...: extra parameters for the format
1967 *
1968 * Write a formatted xml attribute.
1969 *
1970 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1971 */
1972 int XMLCDECL
1973 xmlTextWriterWriteFormatAttribute(xmlTextWriterPtr writer,
1974 const xmlChar * name, const char *format,
1975 ...)
1976 {
1977 int rc;
1978 va_list ap;
1979
1980 va_start(ap, format);
1981
1982 rc = xmlTextWriterWriteVFormatAttribute(writer, name, format, ap);
1983
1984 va_end(ap);
1985 return rc;
1986 }
1987
1988 /**
1989 * xmlTextWriterWriteVFormatAttribute:
1990 * @writer: the xmlTextWriterPtr
1991 * @name: attribute name
1992 * @format: format string (see printf)
1993 * @argptr: pointer to the first member of the variable argument list.
1994 *
1995 * Write a formatted xml attribute.
1996 *
1997 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1998 */
1999 int
2000 xmlTextWriterWriteVFormatAttribute(xmlTextWriterPtr writer,
2001 const xmlChar * name,
2002 const char *format, va_list argptr)
2003 {
2004 int rc;
2005 xmlChar *buf;
2006
2007 if (writer == NULL)
2008 return -1;
2009
2010 buf = xmlTextWriterVSprintf(format, argptr);
2011 if (buf == NULL)
2012 return -1;
2013
2014 rc = xmlTextWriterWriteAttribute(writer, name, buf);
2015
2016 xmlFree(buf);
2017 return rc;
2018 }
2019
2020 /**
2021 * xmlTextWriterWriteAttribute:
2022 * @writer: the xmlTextWriterPtr
2023 * @name: attribute name
2024 * @content: attribute content
2025 *
2026 * Write an xml attribute.
2027 *
2028 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2029 */
2030 int
2031 xmlTextWriterWriteAttribute(xmlTextWriterPtr writer, const xmlChar * name,
2032 const xmlChar * content)
2033 {
2034 int count;
2035 int sum;
2036
2037 sum = 0;
2038 count = xmlTextWriterStartAttribute(writer, name);
2039 if (count < 0)
2040 return -1;
2041 sum += count;
2042 count = xmlTextWriterWriteString(writer, content);
2043 if (count < 0)
2044 return -1;
2045 sum += count;
2046 count = xmlTextWriterEndAttribute(writer);
2047 if (count < 0)
2048 return -1;
2049 sum += count;
2050
2051 return sum;
2052 }
2053
2054 /**
2055 * xmlTextWriterWriteFormatAttributeNS:
2056 * @writer: the xmlTextWriterPtr
2057 * @prefix: namespace prefix
2058 * @name: attribute local name
2059 * @namespaceURI: namespace URI
2060 * @format: format string (see printf)
2061 * @...: extra parameters for the format
2062 *
2063 * Write a formatted xml attribute.with namespace support
2064 *
2065 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2066 */
2067 int XMLCDECL
2068 xmlTextWriterWriteFormatAttributeNS(xmlTextWriterPtr writer,
2069 const xmlChar * prefix,
2070 const xmlChar * name,
2071 const xmlChar * namespaceURI,
2072 const char *format, ...)
2073 {
2074 int rc;
2075 va_list ap;
2076
2077 va_start(ap, format);
2078
2079 rc = xmlTextWriterWriteVFormatAttributeNS(writer, prefix, name,
2080 namespaceURI, format, ap);
2081
2082 va_end(ap);
2083 return rc;
2084 }
2085
2086 /**
2087 * xmlTextWriterWriteVFormatAttributeNS:
2088 * @writer: the xmlTextWriterPtr
2089 * @prefix: namespace prefix
2090 * @name: attribute local name
2091 * @namespaceURI: namespace URI
2092 * @format: format string (see printf)
2093 * @argptr: pointer to the first member of the variable argument list.
2094 *
2095 * Write a formatted xml attribute.with namespace support
2096 *
2097 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2098 */
2099 int
2100 xmlTextWriterWriteVFormatAttributeNS(xmlTextWriterPtr writer,
2101 const xmlChar * prefix,
2102 const xmlChar * name,
2103 const xmlChar * namespaceURI,
2104 const char *format, va_list argptr)
2105 {
2106 int rc;
2107 xmlChar *buf;
2108
2109 if (writer == NULL)
2110 return -1;
2111
2112 buf = xmlTextWriterVSprintf(format, argptr);
2113 if (buf == NULL)
2114 return -1;
2115
2116 rc = xmlTextWriterWriteAttributeNS(writer, prefix, name, namespaceURI,
2117 buf);
2118
2119 xmlFree(buf);
2120 return rc;
2121 }
2122
2123 /**
2124 * xmlTextWriterWriteAttributeNS:
2125 * @writer: the xmlTextWriterPtr
2126 * @prefix: namespace prefix
2127 * @name: attribute local name
2128 * @namespaceURI: namespace URI
2129 * @content: attribute content
2130 *
2131 * Write an xml attribute.
2132 *
2133 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2134 */
2135 int
2136 xmlTextWriterWriteAttributeNS(xmlTextWriterPtr writer,
2137 const xmlChar * prefix, const xmlChar * name,
2138 const xmlChar * namespaceURI,
2139 const xmlChar * content)
2140 {
2141 int count;
2142 int sum;
2143
2144 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
2145 return -1;
2146
2147 sum = 0;
2148 count = xmlTextWriterStartAttributeNS(writer, prefix, name, namespaceURI);
2149 if (count < 0)
2150 return -1;
2151 sum += count;
2152 count = xmlTextWriterWriteString(writer, content);
2153 if (count < 0)
2154 return -1;
2155 sum += count;
2156 count = xmlTextWriterEndAttribute(writer);
2157 if (count < 0)
2158 return -1;
2159 sum += count;
2160
2161 return sum;
2162 }
2163
2164 /**
2165 * xmlTextWriterWriteFormatElement:
2166 * @writer: the xmlTextWriterPtr
2167 * @name: element name
2168 * @format: format string (see printf)
2169 * @...: extra parameters for the format
2170 *
2171 * Write a formatted xml element.
2172 *
2173 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2174 */
2175 int XMLCDECL
2176 xmlTextWriterWriteFormatElement(xmlTextWriterPtr writer,
2177 const xmlChar * name, const char *format,
2178 ...)
2179 {
2180 int rc;
2181 va_list ap;
2182
2183 va_start(ap, format);
2184
2185 rc = xmlTextWriterWriteVFormatElement(writer, name, format, ap);
2186
2187 va_end(ap);
2188 return rc;
2189 }
2190
2191 /**
2192 * xmlTextWriterWriteVFormatElement:
2193 * @writer: the xmlTextWriterPtr
2194 * @name: element name
2195 * @format: format string (see printf)
2196 * @argptr: pointer to the first member of the variable argument list.
2197 *
2198 * Write a formatted xml element.
2199 *
2200 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2201 */
2202 int
2203 xmlTextWriterWriteVFormatElement(xmlTextWriterPtr writer,
2204 const xmlChar * name, const char *format,
2205 va_list argptr)
2206 {
2207 int rc;
2208 xmlChar *buf;
2209
2210 if (writer == NULL)
2211 return -1;
2212
2213 buf = xmlTextWriterVSprintf(format, argptr);
2214 if (buf == NULL)
2215 return -1;
2216
2217 rc = xmlTextWriterWriteElement(writer, name, buf);
2218
2219 xmlFree(buf);
2220 return rc;
2221 }
2222
2223 /**
2224 * xmlTextWriterWriteElement:
2225 * @writer: the xmlTextWriterPtr
2226 * @name: element name
2227 * @content: element content
2228 *
2229 * Write an xml element.
2230 *
2231 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2232 */
2233 int
2234 xmlTextWriterWriteElement(xmlTextWriterPtr writer, const xmlChar * name,
2235 const xmlChar * content)
2236 {
2237 int count;
2238 int sum;
2239
2240 sum = 0;
2241 count = xmlTextWriterStartElement(writer, name);
2242 if (count == -1)
2243 return -1;
2244 sum += count;
2245 if (content != NULL) {
2246 count = xmlTextWriterWriteString(writer, content);
2247 if (count == -1)
2248 return -1;
2249 sum += count;
2250 }
2251 count = xmlTextWriterEndElement(writer);
2252 if (count == -1)
2253 return -1;
2254 sum += count;
2255
2256 return sum;
2257 }
2258
2259 /**
2260 * xmlTextWriterWriteFormatElementNS:
2261 * @writer: the xmlTextWriterPtr
2262 * @prefix: namespace prefix
2263 * @name: element local name
2264 * @namespaceURI: namespace URI
2265 * @format: format string (see printf)
2266 * @...: extra parameters for the format
2267 *
2268 * Write a formatted xml element with namespace support.
2269 *
2270 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2271 */
2272 int XMLCDECL
2273 xmlTextWriterWriteFormatElementNS(xmlTextWriterPtr writer,
2274 const xmlChar * prefix,
2275 const xmlChar * name,
2276 const xmlChar * namespaceURI,
2277 const char *format, ...)
2278 {
2279 int rc;
2280 va_list ap;
2281
2282 va_start(ap, format);
2283
2284 rc = xmlTextWriterWriteVFormatElementNS(writer, prefix, name,
2285 namespaceURI, format, ap);
2286
2287 va_end(ap);
2288 return rc;
2289 }
2290
2291 /**
2292 * xmlTextWriterWriteVFormatElementNS:
2293 * @writer: the xmlTextWriterPtr
2294 * @prefix: namespace prefix
2295 * @name: element local name
2296 * @namespaceURI: namespace URI
2297 * @format: format string (see printf)
2298 * @argptr: pointer to the first member of the variable argument list.
2299 *
2300 * Write a formatted xml element with namespace support.
2301 *
2302 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2303 */
2304 int
2305 xmlTextWriterWriteVFormatElementNS(xmlTextWriterPtr writer,
2306 const xmlChar * prefix,
2307 const xmlChar * name,
2308 const xmlChar * namespaceURI,
2309 const char *format, va_list argptr)
2310 {
2311 int rc;
2312 xmlChar *buf;
2313
2314 if (writer == NULL)
2315 return -1;
2316
2317 buf = xmlTextWriterVSprintf(format, argptr);
2318 if (buf == NULL)
2319 return -1;
2320
2321 rc = xmlTextWriterWriteElementNS(writer, prefix, name, namespaceURI,
2322 buf);
2323
2324 xmlFree(buf);
2325 return rc;
2326 }
2327
2328 /**
2329 * xmlTextWriterWriteElementNS:
2330 * @writer: the xmlTextWriterPtr
2331 * @prefix: namespace prefix
2332 * @name: element local name
2333 * @namespaceURI: namespace URI
2334 * @content: element content
2335 *
2336 * Write an xml element with namespace support.
2337 *
2338 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2339 */
2340 int
2341 xmlTextWriterWriteElementNS(xmlTextWriterPtr writer,
2342 const xmlChar * prefix, const xmlChar * name,
2343 const xmlChar * namespaceURI,
2344 const xmlChar * content)
2345 {
2346 int count;
2347 int sum;
2348
2349 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
2350 return -1;
2351
2352 sum = 0;
2353 count =
2354 xmlTextWriterStartElementNS(writer, prefix, name, namespaceURI);
2355 if (count < 0)
2356 return -1;
2357 sum += count;
2358 count = xmlTextWriterWriteString(writer, content);
2359 if (count == -1)
2360 return -1;
2361 sum += count;
2362 count = xmlTextWriterEndElement(writer);
2363 if (count == -1)
2364 return -1;
2365 sum += count;
2366
2367 return sum;
2368 }
2369
2370 /**
2371 * xmlTextWriterStartPI:
2372 * @writer: the xmlTextWriterPtr
2373 * @target: PI target
2374 *
2375 * Start an xml PI.
2376 *
2377 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2378 */
2379 int
2380 xmlTextWriterStartPI(xmlTextWriterPtr writer, const xmlChar * target)
2381 {
2382 int count;
2383 int sum;
2384 xmlLinkPtr lk;
2385 xmlTextWriterStackEntry *p;
2386
2387 if ((writer == NULL) || (target == NULL) || (*target == '\0'))
2388 return -1;
2389
2390 if (xmlStrcasecmp(target, (const xmlChar *) "xml") == 0) {
2391 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
2392 "xmlTextWriterStartPI : target name [Xx][Mm][Ll] is reserved for xml standardization!\n");
2393 return -1;
2394 }
2395
2396 sum = 0;
2397 lk = xmlListFront(writer->nodes);
2398 if (lk != 0) {
2399 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2400 if (p != 0) {
2401 switch (p->state) {
2402 case XML_TEXTWRITER_ATTRIBUTE:
2403 count = xmlTextWriterEndAttribute(writer);
2404 if (count < 0)
2405 return -1;
2406 sum += count;
2407 /* fallthrough */
2408 case XML_TEXTWRITER_NAME:
2409 /* Output namespace declarations */
2410 count = xmlTextWriterOutputNSDecl(writer);
2411 if (count < 0)
2412 return -1;
2413 sum += count;
2414 count = xmlOutputBufferWriteString(writer->out, ">");
2415 if (count < 0)
2416 return -1;
2417 sum += count;
2418 p->state = XML_TEXTWRITER_TEXT;
2419 break;
2420 case XML_TEXTWRITER_NONE:
2421 case XML_TEXTWRITER_TEXT:
2422 case XML_TEXTWRITER_DTD:
2423 break;
2424 case XML_TEXTWRITER_PI:
2425 case XML_TEXTWRITER_PI_TEXT:
2426 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
2427 "xmlTextWriterStartPI : nested PI!\n");
2428 return -1;
2429 default:
2430 return -1;
2431 }
2432 }
2433 }
2434
2435 p = (xmlTextWriterStackEntry *)
2436 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2437 if (p == 0) {
2438 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
2439 "xmlTextWriterStartPI : out of memory!\n");
2440 return -1;
2441 }
2442
2443 p->name = xmlStrdup(target);
2444 if (p->name == 0) {
2445 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
2446 "xmlTextWriterStartPI : out of memory!\n");
2447 xmlFree(p);
2448 return -1;
2449 }
2450 p->state = XML_TEXTWRITER_PI;
2451
2452 xmlListPushFront(writer->nodes, p);
2453
2454 count = xmlOutputBufferWriteString(writer->out, "<?");
2455 if (count < 0)
2456 return -1;
2457 sum += count;
2458 count =
2459 xmlOutputBufferWriteString(writer->out, (const char *) p->name);
2460 if (count < 0)
2461 return -1;
2462 sum += count;
2463
2464 return sum;
2465 }
2466
2467 /**
2468 * xmlTextWriterEndPI:
2469 * @writer: the xmlTextWriterPtr
2470 *
2471 * End the current xml PI.
2472 *
2473 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2474 */
2475 int
2476 xmlTextWriterEndPI(xmlTextWriterPtr writer)
2477 {
2478 int count;
2479 int sum;
2480 xmlLinkPtr lk;
2481 xmlTextWriterStackEntry *p;
2482
2483 if (writer == NULL)
2484 return -1;
2485
2486 lk = xmlListFront(writer->nodes);
2487 if (lk == 0)
2488 return 0;
2489
2490 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2491 if (p == 0)
2492 return 0;
2493
2494 sum = 0;
2495 switch (p->state) {
2496 case XML_TEXTWRITER_PI:
2497 case XML_TEXTWRITER_PI_TEXT:
2498 count = xmlOutputBufferWriteString(writer->out, "?>");
2499 if (count < 0)
2500 return -1;
2501 sum += count;
2502 break;
2503 default:
2504 return -1;
2505 }
2506
2507 if (writer->indent) {
2508 count = xmlOutputBufferWriteString(writer->out, "\n");
2509 if (count < 0)
2510 return -1;
2511 sum += count;
2512 }
2513
2514 xmlListPopFront(writer->nodes);
2515 return sum;
2516 }
2517
2518 /**
2519 * xmlTextWriterWriteFormatPI:
2520 * @writer: the xmlTextWriterPtr
2521 * @target: PI target
2522 * @format: format string (see printf)
2523 * @...: extra parameters for the format
2524 *
2525 * Write a formatted PI.
2526 *
2527 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2528 */
2529 int XMLCDECL
2530 xmlTextWriterWriteFormatPI(xmlTextWriterPtr writer, const xmlChar * target,
2531 const char *format, ...)
2532 {
2533 int rc;
2534 va_list ap;
2535
2536 va_start(ap, format);
2537
2538 rc = xmlTextWriterWriteVFormatPI(writer, target, format, ap);
2539
2540 va_end(ap);
2541 return rc;
2542 }
2543
2544 /**
2545 * xmlTextWriterWriteVFormatPI:
2546 * @writer: the xmlTextWriterPtr
2547 * @target: PI target
2548 * @format: format string (see printf)
2549 * @argptr: pointer to the first member of the variable argument list.
2550 *
2551 * Write a formatted xml PI.
2552 *
2553 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2554 */
2555 int
2556 xmlTextWriterWriteVFormatPI(xmlTextWriterPtr writer,
2557 const xmlChar * target, const char *format,
2558 va_list argptr)
2559 {
2560 int rc;
2561 xmlChar *buf;
2562
2563 if (writer == NULL)
2564 return -1;
2565
2566 buf = xmlTextWriterVSprintf(format, argptr);
2567 if (buf == NULL)
2568 return -1;
2569
2570 rc = xmlTextWriterWritePI(writer, target, buf);
2571
2572 xmlFree(buf);
2573 return rc;
2574 }
2575
2576 /**
2577 * xmlTextWriterWritePI:
2578 * @writer: the xmlTextWriterPtr
2579 * @target: PI target
2580 * @content: PI content
2581 *
2582 * Write an xml PI.
2583 *
2584 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2585 */
2586 int
2587 xmlTextWriterWritePI(xmlTextWriterPtr writer, const xmlChar * target,
2588 const xmlChar * content)
2589 {
2590 int count;
2591 int sum;
2592
2593 sum = 0;
2594 count = xmlTextWriterStartPI(writer, target);
2595 if (count == -1)
2596 return -1;
2597 sum += count;
2598 if (content != 0) {
2599 count = xmlTextWriterWriteString(writer, content);
2600 if (count == -1)
2601 return -1;
2602 sum += count;
2603 }
2604 count = xmlTextWriterEndPI(writer);
2605 if (count == -1)
2606 return -1;
2607 sum += count;
2608
2609 return sum;
2610 }
2611
2612 /**
2613 * xmlTextWriterStartCDATA:
2614 * @writer: the xmlTextWriterPtr
2615 *
2616 * Start an xml CDATA section.
2617 *
2618 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2619 */
2620 int
2621 xmlTextWriterStartCDATA(xmlTextWriterPtr writer)
2622 {
2623 int count;
2624 int sum;
2625 xmlLinkPtr lk;
2626 xmlTextWriterStackEntry *p;
2627
2628 if (writer == NULL)
2629 return -1;
2630
2631 sum = 0;
2632 lk = xmlListFront(writer->nodes);
2633 if (lk != 0) {
2634 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2635 if (p != 0) {
2636 switch (p->state) {
2637 case XML_TEXTWRITER_NONE:
2638 case XML_TEXTWRITER_TEXT:
2639 case XML_TEXTWRITER_PI:
2640 case XML_TEXTWRITER_PI_TEXT:
2641 break;
2642 case XML_TEXTWRITER_ATTRIBUTE:
2643 count = xmlTextWriterEndAttribute(writer);
2644 if (count < 0)
2645 return -1;
2646 sum += count;
2647 /* fallthrough */
2648 case XML_TEXTWRITER_NAME:
2649 /* Output namespace declarations */
2650 count = xmlTextWriterOutputNSDecl(writer);
2651 if (count < 0)
2652 return -1;
2653 sum += count;
2654 count = xmlOutputBufferWriteString(writer->out, ">");
2655 if (count < 0)
2656 return -1;
2657 sum += count;
2658 p->state = XML_TEXTWRITER_TEXT;
2659 break;
2660 case XML_TEXTWRITER_CDATA:
2661 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
2662 "xmlTextWriterStartCDATA : CDATA not allowed in this context!\n");
2663 return -1;
2664 default:
2665 return -1;
2666 }
2667 }
2668 }
2669
2670 p = (xmlTextWriterStackEntry *)
2671 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2672 if (p == 0) {
2673 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
2674 "xmlTextWriterStartCDATA : out of memory!\n");
2675 return -1;
2676 }
2677
2678 p->name = NULL;
2679 p->state = XML_TEXTWRITER_CDATA;
2680
2681 xmlListPushFront(writer->nodes, p);
2682
2683 count = xmlOutputBufferWriteString(writer->out, "<![CDATA[");
2684 if (count < 0)
2685 return -1;
2686 sum += count;
2687
2688 return sum;
2689 }
2690
2691 /**
2692 * xmlTextWriterEndCDATA:
2693 * @writer: the xmlTextWriterPtr
2694 *
2695 * End an xml CDATA section.
2696 *
2697 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2698 */
2699 int
2700 xmlTextWriterEndCDATA(xmlTextWriterPtr writer)
2701 {
2702 int count;
2703 int sum;
2704 xmlLinkPtr lk;
2705 xmlTextWriterStackEntry *p;
2706
2707 if (writer == NULL)
2708 return -1;
2709
2710 lk = xmlListFront(writer->nodes);
2711 if (lk == 0)
2712 return -1;
2713
2714 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2715 if (p == 0)
2716 return -1;
2717
2718 sum = 0;
2719 switch (p->state) {
2720 case XML_TEXTWRITER_CDATA:
2721 count = xmlOutputBufferWriteString(writer->out, "]]>");
2722 if (count < 0)
2723 return -1;
2724 sum += count;
2725 break;
2726 default:
2727 return -1;
2728 }
2729
2730 xmlListPopFront(writer->nodes);
2731 return sum;
2732 }
2733
2734 /**
2735 * xmlTextWriterWriteFormatCDATA:
2736 * @writer: the xmlTextWriterPtr
2737 * @format: format string (see printf)
2738 * @...: extra parameters for the format
2739 *
2740 * Write a formatted xml CDATA.
2741 *
2742 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2743 */
2744 int XMLCDECL
2745 xmlTextWriterWriteFormatCDATA(xmlTextWriterPtr writer, const char *format,
2746 ...)
2747 {
2748 int rc;
2749 va_list ap;
2750
2751 va_start(ap, format);
2752
2753 rc = xmlTextWriterWriteVFormatCDATA(writer, format, ap);
2754
2755 va_end(ap);
2756 return rc;
2757 }
2758
2759 /**
2760 * xmlTextWriterWriteVFormatCDATA:
2761 * @writer: the xmlTextWriterPtr
2762 * @format: format string (see printf)
2763 * @argptr: pointer to the first member of the variable argument list.
2764 *
2765 * Write a formatted xml CDATA.
2766 *
2767 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2768 */
2769 int
2770 xmlTextWriterWriteVFormatCDATA(xmlTextWriterPtr writer, const char *format,
2771 va_list argptr)
2772 {
2773 int rc;
2774 xmlChar *buf;
2775
2776 if (writer == NULL)
2777 return -1;
2778
2779 buf = xmlTextWriterVSprintf(format, argptr);
2780 if (buf == NULL)
2781 return -1;
2782
2783 rc = xmlTextWriterWriteCDATA(writer, buf);
2784
2785 xmlFree(buf);
2786 return rc;
2787 }
2788
2789 /**
2790 * xmlTextWriterWriteCDATA:
2791 * @writer: the xmlTextWriterPtr
2792 * @content: CDATA content
2793 *
2794 * Write an xml CDATA.
2795 *
2796 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2797 */
2798 int
2799 xmlTextWriterWriteCDATA(xmlTextWriterPtr writer, const xmlChar * content)
2800 {
2801 int count;
2802 int sum;
2803
2804 sum = 0;
2805 count = xmlTextWriterStartCDATA(writer);
2806 if (count == -1)
2807 return -1;
2808 sum += count;
2809 if (content != 0) {
2810 count = xmlTextWriterWriteString(writer, content);
2811 if (count == -1)
2812 return -1;
2813 sum += count;
2814 }
2815 count = xmlTextWriterEndCDATA(writer);
2816 if (count == -1)
2817 return -1;
2818 sum += count;
2819
2820 return sum;
2821 }
2822
2823 /**
2824 * xmlTextWriterStartDTD:
2825 * @writer: the xmlTextWriterPtr
2826 * @name: the name of the DTD
2827 * @pubid: the public identifier, which is an alternative to the system identifier
2828 * @sysid: the system identifier, which is the URI of the DTD
2829 *
2830 * Start an xml DTD.
2831 *
2832 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2833 */
2834 int
2835 xmlTextWriterStartDTD(xmlTextWriterPtr writer,
2836 const xmlChar * name,
2837 const xmlChar * pubid, const xmlChar * sysid)
2838 {
2839 int count;
2840 int sum;
2841 xmlLinkPtr lk;
2842 xmlTextWriterStackEntry *p;
2843
2844 if (writer == NULL || name == NULL || *name == '\0')
2845 return -1;
2846
2847 sum = 0;
2848 lk = xmlListFront(writer->nodes);
2849 if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) {
2850 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
2851 "xmlTextWriterStartDTD : DTD allowed only in prolog!\n");
2852 return -1;
2853 }
2854
2855 p = (xmlTextWriterStackEntry *)
2856 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2857 if (p == 0) {
2858 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
2859 "xmlTextWriterStartDTD : out of memory!\n");
2860 return -1;
2861 }
2862
2863 p->name = xmlStrdup(name);
2864 if (p->name == 0) {
2865 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
2866 "xmlTextWriterStartDTD : out of memory!\n");
2867 xmlFree(p);
2868 return -1;
2869 }
2870 p->state = XML_TEXTWRITER_DTD;
2871
2872 xmlListPushFront(writer->nodes, p);
2873
2874 count = xmlOutputBufferWriteString(writer->out, "<!DOCTYPE ");
2875 if (count < 0)
2876 return -1;
2877 sum += count;
2878 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
2879 if (count < 0)
2880 return -1;
2881 sum += count;
2882
2883 if (pubid != 0) {
2884 if (sysid == 0) {
2885 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
2886 "xmlTextWriterStartDTD : system identifier needed!\n");
2887 return -1;
2888 }
2889
2890 if (writer->indent)
2891 count = xmlOutputBufferWrite(writer->out, 1, "\n");
2892 else
2893 count = xmlOutputBufferWrite(writer->out, 1, " ");
2894 if (count < 0)
2895 return -1;
2896 sum += count;
2897
2898 count = xmlOutputBufferWriteString(writer->out, "PUBLIC ");
2899 if (count < 0)
2900 return -1;
2901 sum += count;
2902
2903 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
2904 if (count < 0)
2905 return -1;
2906 sum += count;
2907
2908 count =
2909 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
2910 if (count < 0)
2911 return -1;
2912 sum += count;
2913
2914 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
2915 if (count < 0)
2916 return -1;
2917 sum += count;
2918 }
2919
2920 if (sysid != 0) {
2921 if (pubid == 0) {
2922 if (writer->indent)
2923 count = xmlOutputBufferWrite(writer->out, 1, "\n");
2924 else
2925 count = xmlOutputBufferWrite(writer->out, 1, " ");
2926 if (count < 0)
2927 return -1;
2928 sum += count;
2929 count = xmlOutputBufferWriteString(writer->out, "SYSTEM ");
2930 if (count < 0)
2931 return -1;
2932 sum += count;
2933 } else {
2934 if (writer->indent)
2935 count = xmlOutputBufferWriteString(writer->out, "\n ");
2936 else
2937 count = xmlOutputBufferWrite(writer->out, 1, " ");
2938 if (count < 0)
2939 return -1;
2940 sum += count;
2941 }
2942
2943 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
2944 if (count < 0)
2945 return -1;
2946 sum += count;
2947
2948 count =
2949 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
2950 if (count < 0)
2951 return -1;
2952 sum += count;
2953
2954 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
2955 if (count < 0)
2956 return -1;
2957 sum += count;
2958 }
2959
2960 return sum;
2961 }
2962
2963 /**
2964 * xmlTextWriterEndDTD:
2965 * @writer: the xmlTextWriterPtr
2966 *
2967 * End an xml DTD.
2968 *
2969 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2970 */
2971 int
2972 xmlTextWriterEndDTD(xmlTextWriterPtr writer)
2973 {
2974 int loop;
2975 int count;
2976 int sum;
2977 xmlLinkPtr lk;
2978 xmlTextWriterStackEntry *p;
2979
2980 if (writer == NULL)
2981 return -1;
2982
2983 sum = 0;
2984 loop = 1;
2985 while (loop) {
2986 lk = xmlListFront(writer->nodes);
2987 if (lk == NULL)
2988 break;
2989 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2990 if (p == 0)
2991 break;
2992 switch (p->state) {
2993 case XML_TEXTWRITER_DTD_TEXT:
2994 count = xmlOutputBufferWriteString(writer->out, "]");
2995 if (count < 0)
2996 return -1;
2997 sum += count;
2998 /* fallthrough */
2999 case XML_TEXTWRITER_DTD:
3000 count = xmlOutputBufferWriteString(writer->out, ">");
3001
3002 if (writer->indent) {
3003 if (count < 0)
3004 return -1;
3005 sum += count;
3006 count = xmlOutputBufferWriteString(writer->out, "\n");
3007 }
3008
3009 xmlListPopFront(writer->nodes);
3010 break;
3011 case XML_TEXTWRITER_DTD_ELEM:
3012 case XML_TEXTWRITER_DTD_ELEM_TEXT:
3013 count = xmlTextWriterEndDTDElement(writer);
3014 break;
3015 case XML_TEXTWRITER_DTD_ATTL:
3016 case XML_TEXTWRITER_DTD_ATTL_TEXT:
3017 count = xmlTextWriterEndDTDAttlist(writer);
3018 break;
3019 case XML_TEXTWRITER_DTD_ENTY:
3020 case XML_TEXTWRITER_DTD_PENT:
3021 case XML_TEXTWRITER_DTD_ENTY_TEXT:
3022 count = xmlTextWriterEndDTDEntity(writer);
3023 break;
3024 case XML_TEXTWRITER_COMMENT:
3025 count = xmlTextWriterEndComment(writer);
3026 break;
3027 default:
3028 loop = 0;
3029 continue;
3030 }
3031
3032 if (count < 0)
3033 return -1;
3034 sum += count;
3035 }
3036
3037 return sum;
3038 }
3039
3040 /**
3041 * xmlTextWriterWriteFormatDTD:
3042 * @writer: the xmlTextWriterPtr
3043 * @name: the name of the DTD
3044 * @pubid: the public identifier, which is an alternative to the system identifier
3045 * @sysid: the system identifier, which is the URI of the DTD
3046 * @format: format string (see printf)
3047 * @...: extra parameters for the format
3048 *
3049 * Write a DTD with a formatted markup declarations part.
3050 *
3051 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3052 */
3053 int XMLCDECL
3054 xmlTextWriterWriteFormatDTD(xmlTextWriterPtr writer,
3055 const xmlChar * name,
3056 const xmlChar * pubid,
3057 const xmlChar * sysid, const char *format, ...)
3058 {
3059 int rc;
3060 va_list ap;
3061
3062 va_start(ap, format);
3063
3064 rc = xmlTextWriterWriteVFormatDTD(writer, name, pubid, sysid, format,
3065 ap);
3066
3067 va_end(ap);
3068 return rc;
3069 }
3070
3071 /**
3072 * xmlTextWriterWriteVFormatDTD:
3073 * @writer: the xmlTextWriterPtr
3074 * @name: the name of the DTD
3075 * @pubid: the public identifier, which is an alternative to the system identifier
3076 * @sysid: the system identifier, which is the URI of the DTD
3077 * @format: format string (see printf)
3078 * @argptr: pointer to the first member of the variable argument list.
3079 *
3080 * Write a DTD with a formatted markup declarations part.
3081 *
3082 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3083 */
3084 int
3085 xmlTextWriterWriteVFormatDTD(xmlTextWriterPtr writer,
3086 const xmlChar * name,
3087 const xmlChar * pubid,
3088 const xmlChar * sysid,
3089 const char *format, va_list argptr)
3090 {
3091 int rc;
3092 xmlChar *buf;
3093
3094 if (writer == NULL)
3095 return -1;
3096
3097 buf = xmlTextWriterVSprintf(format, argptr);
3098 if (buf == NULL)
3099 return -1;
3100
3101 rc = xmlTextWriterWriteDTD(writer, name, pubid, sysid, buf);
3102
3103 xmlFree(buf);
3104 return rc;
3105 }
3106
3107 /**
3108 * xmlTextWriterWriteDTD:
3109 * @writer: the xmlTextWriterPtr
3110 * @name: the name of the DTD
3111 * @pubid: the public identifier, which is an alternative to the system identifier
3112 * @sysid: the system identifier, which is the URI of the DTD
3113 * @subset: string content of the DTD
3114 *
3115 * Write a DTD.
3116 *
3117 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3118 */
3119 int
3120 xmlTextWriterWriteDTD(xmlTextWriterPtr writer,
3121 const xmlChar * name,
3122 const xmlChar * pubid,
3123 const xmlChar * sysid, const xmlChar * subset)
3124 {
3125 int count;
3126 int sum;
3127
3128 sum = 0;
3129 count = xmlTextWriterStartDTD(writer, name, pubid, sysid);
3130 if (count == -1)
3131 return -1;
3132 sum += count;
3133 if (subset != 0) {
3134 count = xmlTextWriterWriteString(writer, subset);
3135 if (count == -1)
3136 return -1;
3137 sum += count;
3138 }
3139 count = xmlTextWriterEndDTD(writer);
3140 if (count == -1)
3141 return -1;
3142 sum += count;
3143
3144 return sum;
3145 }
3146
3147 /**
3148 * xmlTextWriterStartDTDElement:
3149 * @writer: the xmlTextWriterPtr
3150 * @name: the name of the DTD element
3151 *
3152 * Start an xml DTD element.
3153 *
3154 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3155 */
3156 int
3157 xmlTextWriterStartDTDElement(xmlTextWriterPtr writer, const xmlChar * name)
3158 {
3159 int count;
3160 int sum;
3161 xmlLinkPtr lk;
3162 xmlTextWriterStackEntry *p;
3163
3164 if (writer == NULL || name == NULL || *name == '\0')
3165 return -1;
3166
3167 sum = 0;
3168 lk = xmlListFront(writer->nodes);
3169 if (lk == 0) {
3170 return -1;
3171 }
3172
3173 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3174 if (p != 0) {
3175 switch (p->state) {
3176 case XML_TEXTWRITER_DTD:
3177 count = xmlOutputBufferWriteString(writer->out, " [");
3178 if (count < 0)
3179 return -1;
3180 sum += count;
3181 if (writer->indent) {
3182 count = xmlOutputBufferWriteString(writer->out, "\n");
3183 if (count < 0)
3184 return -1;
3185 sum += count;
3186 }
3187 p->state = XML_TEXTWRITER_DTD_TEXT;
3188 /* fallthrough */
3189 case XML_TEXTWRITER_DTD_TEXT:
3190 case XML_TEXTWRITER_NONE:
3191 break;
3192 default:
3193 return -1;
3194 }
3195 }
3196
3197 p = (xmlTextWriterStackEntry *)
3198 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3199 if (p == 0) {
3200 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
3201 "xmlTextWriterStartDTDElement : out of memory!\n");
3202 return -1;
3203 }
3204
3205 p->name = xmlStrdup(name);
3206 if (p->name == 0) {
3207 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
3208 "xmlTextWriterStartDTDElement : out of memory!\n");
3209 xmlFree(p);
3210 return -1;
3211 }
3212 p->state = XML_TEXTWRITER_DTD_ELEM;
3213
3214 xmlListPushFront(writer->nodes, p);
3215
3216 if (writer->indent) {
3217 count = xmlTextWriterWriteIndent(writer);
3218 if (count < 0)
3219 return -1;
3220 sum += count;
3221 }
3222
3223 count = xmlOutputBufferWriteString(writer->out, "<!ELEMENT ");
3224 if (count < 0)
3225 return -1;
3226 sum += count;
3227 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
3228 if (count < 0)
3229 return -1;
3230 sum += count;
3231
3232 return sum;
3233 }
3234
3235 /**
3236 * xmlTextWriterEndDTDElement:
3237 * @writer: the xmlTextWriterPtr
3238 *
3239 * End an xml DTD element.
3240 *
3241 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3242 */
3243 int
3244 xmlTextWriterEndDTDElement(xmlTextWriterPtr writer)
3245 {
3246 int count;
3247 int sum;
3248 xmlLinkPtr lk;
3249 xmlTextWriterStackEntry *p;
3250
3251 if (writer == NULL)
3252 return -1;
3253
3254 sum = 0;
3255 lk = xmlListFront(writer->nodes);
3256 if (lk == 0)
3257 return -1;
3258
3259 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3260 if (p == 0)
3261 return -1;
3262
3263 switch (p->state) {
3264 case XML_TEXTWRITER_DTD_ELEM:
3265 case XML_TEXTWRITER_DTD_ELEM_TEXT:
3266 count = xmlOutputBufferWriteString(writer->out, ">");
3267 if (count < 0)
3268 return -1;
3269 sum += count;
3270 break;
3271 default:
3272 return -1;
3273 }
3274
3275 if (writer->indent) {
3276 count = xmlOutputBufferWriteString(writer->out, "\n");
3277 if (count < 0)
3278 return -1;
3279 sum += count;
3280 }
3281
3282 xmlListPopFront(writer->nodes);
3283 return sum;
3284 }
3285
3286 /**
3287 * xmlTextWriterWriteFormatDTDElement:
3288 * @writer: the xmlTextWriterPtr
3289 * @name: the name of the DTD element
3290 * @format: format string (see printf)
3291 * @...: extra parameters for the format
3292 *
3293 * Write a formatted DTD element.
3294 *
3295 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3296 */
3297 int XMLCDECL
3298 xmlTextWriterWriteFormatDTDElement(xmlTextWriterPtr writer,
3299 const xmlChar * name,
3300 const char *format, ...)
3301 {
3302 int rc;
3303 va_list ap;
3304
3305 va_start(ap, format);
3306
3307 rc = xmlTextWriterWriteVFormatDTDElement(writer, name, format, ap);
3308
3309 va_end(ap);
3310 return rc;
3311 }
3312
3313 /**
3314 * xmlTextWriterWriteVFormatDTDElement:
3315 * @writer: the xmlTextWriterPtr
3316 * @name: the name of the DTD element
3317 * @format: format string (see printf)
3318 * @argptr: pointer to the first member of the variable argument list.
3319 *
3320 * Write a formatted DTD element.
3321 *
3322 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3323 */
3324 int
3325 xmlTextWriterWriteVFormatDTDElement(xmlTextWriterPtr writer,
3326 const xmlChar * name,
3327 const char *format, va_list argptr)
3328 {
3329 int rc;
3330 xmlChar *buf;
3331
3332 if (writer == NULL)
3333 return -1;
3334
3335 buf = xmlTextWriterVSprintf(format, argptr);
3336 if (buf == NULL)
3337 return -1;
3338
3339 rc = xmlTextWriterWriteDTDElement(writer, name, buf);
3340
3341 xmlFree(buf);
3342 return rc;
3343 }
3344
3345 /**
3346 * xmlTextWriterWriteDTDElement:
3347 * @writer: the xmlTextWriterPtr
3348 * @name: the name of the DTD element
3349 * @content: content of the element
3350 *
3351 * Write a DTD element.
3352 *
3353 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3354 */
3355 int
3356 xmlTextWriterWriteDTDElement(xmlTextWriterPtr writer,
3357 const xmlChar * name, const xmlChar * content)
3358 {
3359 int count;
3360 int sum;
3361
3362 if (content == NULL)
3363 return -1;
3364
3365 sum = 0;
3366 count = xmlTextWriterStartDTDElement(writer, name);
3367 if (count == -1)
3368 return -1;
3369 sum += count;
3370
3371 count = xmlTextWriterWriteString(writer, content);
3372 if (count == -1)
3373 return -1;
3374 sum += count;
3375
3376 count = xmlTextWriterEndDTDElement(writer);
3377 if (count == -1)
3378 return -1;
3379 sum += count;
3380
3381 return sum;
3382 }
3383
3384 /**
3385 * xmlTextWriterStartDTDAttlist:
3386 * @writer: the xmlTextWriterPtr
3387 * @name: the name of the DTD ATTLIST
3388 *
3389 * Start an xml DTD ATTLIST.
3390 *
3391 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3392 */
3393 int
3394 xmlTextWriterStartDTDAttlist(xmlTextWriterPtr writer, const xmlChar * name)
3395 {
3396 int count;
3397 int sum;
3398 xmlLinkPtr lk;
3399 xmlTextWriterStackEntry *p;
3400
3401 if (writer == NULL || name == NULL || *name == '\0')
3402 return -1;
3403
3404 sum = 0;
3405 lk = xmlListFront(writer->nodes);
3406 if (lk == 0) {
3407 return -1;
3408 }
3409
3410 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3411 if (p != 0) {
3412 switch (p->state) {
3413 case XML_TEXTWRITER_DTD:
3414 count = xmlOutputBufferWriteString(writer->out, " [");
3415 if (count < 0)
3416 return -1;
3417 sum += count;
3418 if (writer->indent) {
3419 count = xmlOutputBufferWriteString(writer->out, "\n");
3420 if (count < 0)
3421 return -1;
3422 sum += count;
3423 }
3424 p->state = XML_TEXTWRITER_DTD_TEXT;
3425 /* fallthrough */
3426 case XML_TEXTWRITER_DTD_TEXT:
3427 case XML_TEXTWRITER_NONE:
3428 break;
3429 default:
3430 return -1;
3431 }
3432 }
3433
3434 p = (xmlTextWriterStackEntry *)
3435 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3436 if (p == 0) {
3437 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
3438 "xmlTextWriterStartDTDAttlist : out of memory!\n");
3439 return -1;
3440 }
3441
3442 p->name = xmlStrdup(name);
3443 if (p->name == 0) {
3444 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
3445 "xmlTextWriterStartDTDAttlist : out of memory!\n");
3446 xmlFree(p);
3447 return -1;
3448 }
3449 p->state = XML_TEXTWRITER_DTD_ATTL;
3450
3451 xmlListPushFront(writer->nodes, p);
3452
3453 if (writer->indent) {
3454 count = xmlTextWriterWriteIndent(writer);
3455 if (count < 0)
3456 return -1;
3457 sum += count;
3458 }
3459
3460 count = xmlOutputBufferWriteString(writer->out, "<!ATTLIST ");
3461 if (count < 0)
3462 return -1;
3463 sum += count;
3464 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
3465 if (count < 0)
3466 return -1;
3467 sum += count;
3468
3469 return sum;
3470 }
3471
3472 /**
3473 * xmlTextWriterEndDTDAttlist:
3474 * @writer: the xmlTextWriterPtr
3475 *
3476 * End an xml DTD attribute list.
3477 *
3478 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3479 */
3480 int
3481 xmlTextWriterEndDTDAttlist(xmlTextWriterPtr writer)
3482 {
3483 int count;
3484 int sum;
3485 xmlLinkPtr lk;
3486 xmlTextWriterStackEntry *p;
3487
3488 if (writer == NULL)
3489 return -1;
3490
3491 sum = 0;
3492 lk = xmlListFront(writer->nodes);
3493 if (lk == 0)
3494 return -1;
3495
3496 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3497 if (p == 0)
3498 return -1;
3499
3500 switch (p->state) {
3501 case XML_TEXTWRITER_DTD_ATTL:
3502 case XML_TEXTWRITER_DTD_ATTL_TEXT:
3503 count = xmlOutputBufferWriteString(writer->out, ">");
3504 if (count < 0)
3505 return -1;
3506 sum += count;
3507 break;
3508 default:
3509 return -1;
3510 }
3511
3512 if (writer->indent) {
3513 count = xmlOutputBufferWriteString(writer->out, "\n");
3514 if (count < 0)
3515 return -1;
3516 sum += count;
3517 }
3518
3519 xmlListPopFront(writer->nodes);
3520 return sum;
3521 }
3522
3523 /**
3524 * xmlTextWriterWriteFormatDTDAttlist:
3525 * @writer: the xmlTextWriterPtr
3526 * @name: the name of the DTD ATTLIST
3527 * @format: format string (see printf)
3528 * @...: extra parameters for the format
3529 *
3530 * Write a formatted DTD ATTLIST.
3531 *
3532 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3533 */
3534 int XMLCDECL
3535 xmlTextWriterWriteFormatDTDAttlist(xmlTextWriterPtr writer,
3536 const xmlChar * name,
3537 const char *format, ...)
3538 {
3539 int rc;
3540 va_list ap;
3541
3542 va_start(ap, format);
3543
3544 rc = xmlTextWriterWriteVFormatDTDAttlist(writer, name, format, ap);
3545
3546 va_end(ap);
3547 return rc;
3548 }
3549
3550 /**
3551 * xmlTextWriterWriteVFormatDTDAttlist:
3552 * @writer: the xmlTextWriterPtr
3553 * @name: the name of the DTD ATTLIST
3554 * @format: format string (see printf)
3555 * @argptr: pointer to the first member of the variable argument list.
3556 *
3557 * Write a formatted DTD ATTLIST.
3558 *
3559 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3560 */
3561 int
3562 xmlTextWriterWriteVFormatDTDAttlist(xmlTextWriterPtr writer,
3563 const xmlChar * name,
3564 const char *format, va_list argptr)
3565 {
3566 int rc;
3567 xmlChar *buf;
3568
3569 if (writer == NULL)
3570 return -1;
3571
3572 buf = xmlTextWriterVSprintf(format, argptr);
3573 if (buf == NULL)
3574 return -1;
3575
3576 rc = xmlTextWriterWriteDTDAttlist(writer, name, buf);
3577
3578 xmlFree(buf);
3579 return rc;
3580 }
3581
3582 /**
3583 * xmlTextWriterWriteDTDAttlist:
3584 * @writer: the xmlTextWriterPtr
3585 * @name: the name of the DTD ATTLIST
3586 * @content: content of the ATTLIST
3587 *
3588 * Write a DTD ATTLIST.
3589 *
3590 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3591 */
3592 int
3593 xmlTextWriterWriteDTDAttlist(xmlTextWriterPtr writer,
3594 const xmlChar * name, const xmlChar * content)
3595 {
3596 int count;
3597 int sum;
3598
3599 if (content == NULL)
3600 return -1;
3601
3602 sum = 0;
3603 count = xmlTextWriterStartDTDAttlist(writer, name);
3604 if (count == -1)
3605 return -1;
3606 sum += count;
3607
3608 count = xmlTextWriterWriteString(writer, content);
3609 if (count == -1)
3610 return -1;
3611 sum += count;
3612
3613 count = xmlTextWriterEndDTDAttlist(writer);
3614 if (count == -1)
3615 return -1;
3616 sum += count;
3617
3618 return sum;
3619 }
3620
3621 /**
3622 * xmlTextWriterStartDTDEntity:
3623 * @writer: the xmlTextWriterPtr
3624 * @pe: TRUE if this is a parameter entity, FALSE if not
3625 * @name: the name of the DTD ATTLIST
3626 *
3627 * Start an xml DTD ATTLIST.
3628 *
3629 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3630 */
3631 int
3632 xmlTextWriterStartDTDEntity(xmlTextWriterPtr writer,
3633 int pe, const xmlChar * name)
3634 {
3635 int count;
3636 int sum;
3637 xmlLinkPtr lk;
3638 xmlTextWriterStackEntry *p;
3639
3640 if (writer == NULL || name == NULL || *name == '\0')
3641 return -1;
3642
3643 sum = 0;
3644 lk = xmlListFront(writer->nodes);
3645 if (lk != 0) {
3646
3647 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3648 if (p != 0) {
3649 switch (p->state) {
3650 case XML_TEXTWRITER_DTD:
3651 count = xmlOutputBufferWriteString(writer->out, " [");
3652 if (count < 0)
3653 return -1;
3654 sum += count;
3655 if (writer->indent) {
3656 count =
3657 xmlOutputBufferWriteString(writer->out, "\n");
3658 if (count < 0)
3659 return -1;
3660 sum += count;
3661 }
3662 p->state = XML_TEXTWRITER_DTD_TEXT;
3663 /* fallthrough */
3664 case XML_TEXTWRITER_DTD_TEXT:
3665 case XML_TEXTWRITER_NONE:
3666 break;
3667 default:
3668 return -1;
3669 }
3670 }
3671 }
3672
3673 p = (xmlTextWriterStackEntry *)
3674 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3675 if (p == 0) {
3676 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
3677 "xmlTextWriterStartDTDElement : out of memory!\n");
3678 return -1;
3679 }
3680
3681 p->name = xmlStrdup(name);
3682 if (p->name == 0) {
3683 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
3684 "xmlTextWriterStartDTDElement : out of memory!\n");
3685 xmlFree(p);
3686 return -1;
3687 }
3688
3689 if (pe != 0)
3690 p->state = XML_TEXTWRITER_DTD_PENT;
3691 else
3692 p->state = XML_TEXTWRITER_DTD_ENTY;
3693
3694 xmlListPushFront(writer->nodes, p);
3695
3696 if (writer->indent) {
3697 count = xmlTextWriterWriteIndent(writer);
3698 if (count < 0)
3699 return -1;
3700 sum += count;
3701 }
3702
3703 count = xmlOutputBufferWriteString(writer->out, "<!ENTITY ");
3704 if (count < 0)
3705 return -1;
3706 sum += count;
3707
3708 if (pe != 0) {
3709 count = xmlOutputBufferWriteString(writer->out, "% ");
3710 if (count < 0)
3711 return -1;
3712 sum += count;
3713 }
3714
3715 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
3716 if (count < 0)
3717 return -1;
3718 sum += count;
3719
3720 return sum;
3721 }
3722
3723 /**
3724 * xmlTextWriterEndDTDEntity:
3725 * @writer: the xmlTextWriterPtr
3726 *
3727 * End an xml DTD entity.
3728 *
3729 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3730 */
3731 int
3732 xmlTextWriterEndDTDEntity(xmlTextWriterPtr writer)
3733 {
3734 int count;
3735 int sum;
3736 xmlLinkPtr lk;
3737 xmlTextWriterStackEntry *p;
3738
3739 if (writer == NULL)
3740 return -1;
3741
3742 sum = 0;
3743 lk = xmlListFront(writer->nodes);
3744 if (lk == 0)
3745 return -1;
3746
3747 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3748 if (p == 0)
3749 return -1;
3750
3751 switch (p->state) {
3752 case XML_TEXTWRITER_DTD_ENTY_TEXT:
3753 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3754 if (count < 0)
3755 return -1;
3756 sum += count;
3757 /* Falls through. */
3758 case XML_TEXTWRITER_DTD_ENTY:
3759 case XML_TEXTWRITER_DTD_PENT:
3760 count = xmlOutputBufferWriteString(writer->out, ">");
3761 if (count < 0)
3762 return -1;
3763 sum += count;
3764 break;
3765 default:
3766 return -1;
3767 }
3768
3769 if (writer->indent) {
3770 count = xmlOutputBufferWriteString(writer->out, "\n");
3771 if (count < 0)
3772 return -1;
3773 sum += count;
3774 }
3775
3776 xmlListPopFront(writer->nodes);
3777 return sum;
3778 }
3779
3780 /**
3781 * xmlTextWriterWriteFormatDTDInternalEntity:
3782 * @writer: the xmlTextWriterPtr
3783 * @pe: TRUE if this is a parameter entity, FALSE if not
3784 * @name: the name of the DTD entity
3785 * @format: format string (see printf)
3786 * @...: extra parameters for the format
3787 *
3788 * Write a formatted DTD internal entity.
3789 *
3790 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3791 */
3792 int XMLCDECL
3793 xmlTextWriterWriteFormatDTDInternalEntity(xmlTextWriterPtr writer,
3794 int pe,
3795 const xmlChar * name,
3796 const char *format, ...)
3797 {
3798 int rc;
3799 va_list ap;
3800
3801 va_start(ap, format);
3802
3803 rc = xmlTextWriterWriteVFormatDTDInternalEntity(writer, pe, name,
3804 format, ap);
3805
3806 va_end(ap);
3807 return rc;
3808 }
3809
3810 /**
3811 * xmlTextWriterWriteVFormatDTDInternalEntity:
3812 * @writer: the xmlTextWriterPtr
3813 * @pe: TRUE if this is a parameter entity, FALSE if not
3814 * @name: the name of the DTD entity
3815 * @format: format string (see printf)
3816 * @argptr: pointer to the first member of the variable argument list.
3817 *
3818 * Write a formatted DTD internal entity.
3819 *
3820 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3821 */
3822 int
3823 xmlTextWriterWriteVFormatDTDInternalEntity(xmlTextWriterPtr writer,
3824 int pe,
3825 const xmlChar * name,
3826 const char *format,
3827 va_list argptr)
3828 {
3829 int rc;
3830 xmlChar *buf;
3831
3832 if (writer == NULL)
3833 return -1;
3834
3835 buf = xmlTextWriterVSprintf(format, argptr);
3836 if (buf == NULL)
3837 return -1;
3838
3839 rc = xmlTextWriterWriteDTDInternalEntity(writer, pe, name, buf);
3840
3841 xmlFree(buf);
3842 return rc;
3843 }
3844
3845 /**
3846 * xmlTextWriterWriteDTDEntity:
3847 * @writer: the xmlTextWriterPtr
3848 * @pe: TRUE if this is a parameter entity, FALSE if not
3849 * @name: the name of the DTD entity
3850 * @pubid: the public identifier, which is an alternative to the system identifier
3851 * @sysid: the system identifier, which is the URI of the DTD
3852 * @ndataid: the xml notation name.
3853 * @content: content of the entity
3854 *
3855 * Write a DTD entity.
3856 *
3857 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3858 */
3859 int
3860 xmlTextWriterWriteDTDEntity(xmlTextWriterPtr writer,
3861 int pe,
3862 const xmlChar * name,
3863 const xmlChar * pubid,
3864 const xmlChar * sysid,
3865 const xmlChar * ndataid,
3866 const xmlChar * content)
3867 {
3868 if ((content == NULL) && (pubid == NULL) && (sysid == NULL))
3869 return -1;
3870 if ((pe != 0) && (ndataid != NULL))
3871 return -1;
3872
3873 if ((pubid == NULL) && (sysid == NULL))
3874 return xmlTextWriterWriteDTDInternalEntity(writer, pe, name,
3875 content);
3876
3877 return xmlTextWriterWriteDTDExternalEntity(writer, pe, name, pubid,
3878 sysid, ndataid);
3879 }
3880
3881 /**
3882 * xmlTextWriterWriteDTDInternalEntity:
3883 * @writer: the xmlTextWriterPtr
3884 * @pe: TRUE if this is a parameter entity, FALSE if not
3885 * @name: the name of the DTD entity
3886 * @content: content of the entity
3887 *
3888 * Write a DTD internal entity.
3889 *
3890 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3891 */
3892 int
3893 xmlTextWriterWriteDTDInternalEntity(xmlTextWriterPtr writer,
3894 int pe,
3895 const xmlChar * name,
3896 const xmlChar * content)
3897 {
3898 int count;
3899 int sum;
3900
3901 if ((name == NULL) || (*name == '\0') || (content == NULL))
3902 return -1;
3903
3904 sum = 0;
3905 count = xmlTextWriterStartDTDEntity(writer, pe, name);
3906 if (count == -1)
3907 return -1;
3908 sum += count;
3909
3910 count = xmlTextWriterWriteString(writer, content);
3911 if (count == -1)
3912 return -1;
3913 sum += count;
3914
3915 count = xmlTextWriterEndDTDEntity(writer);
3916 if (count == -1)
3917 return -1;
3918 sum += count;
3919
3920 return sum;
3921 }
3922
3923 /**
3924 * xmlTextWriterWriteDTDExternalEntity:
3925 * @writer: the xmlTextWriterPtr
3926 * @pe: TRUE if this is a parameter entity, FALSE if not
3927 * @name: the name of the DTD entity
3928 * @pubid: the public identifier, which is an alternative to the system identifier
3929 * @sysid: the system identifier, which is the URI of the DTD
3930 * @ndataid: the xml notation name.
3931 *
3932 * Write a DTD external entity. The entity must have been started with xmlTextWriterStartDTDEntity
3933 *
3934 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3935 */
3936 int
3937 xmlTextWriterWriteDTDExternalEntity(xmlTextWriterPtr writer,
3938 int pe,
3939 const xmlChar * name,
3940 const xmlChar * pubid,
3941 const xmlChar * sysid,
3942 const xmlChar * ndataid)
3943 {
3944 int count;
3945 int sum;
3946
3947 if (((pubid == NULL) && (sysid == NULL)))
3948 return -1;
3949 if ((pe != 0) && (ndataid != NULL))
3950 return -1;
3951
3952 sum = 0;
3953 count = xmlTextWriterStartDTDEntity(writer, pe, name);
3954 if (count == -1)
3955 return -1;
3956 sum += count;
3957
3958 count =
3959 xmlTextWriterWriteDTDExternalEntityContents(writer, pubid, sysid,
3960 ndataid);
3961 if (count < 0)
3962 return -1;
3963 sum += count;
3964
3965 count = xmlTextWriterEndDTDEntity(writer);
3966 if (count == -1)
3967 return -1;
3968 sum += count;
3969
3970 return sum;
3971 }
3972
3973 /**
3974 * xmlTextWriterWriteDTDExternalEntityContents:
3975 * @writer: the xmlTextWriterPtr
3976 * @pubid: the public identifier, which is an alternative to the system identifier
3977 * @sysid: the system identifier, which is the URI of the DTD
3978 * @ndataid: the xml notation name.
3979 *
3980 * Write the contents of a DTD external entity.
3981 *
3982 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3983 */
3984 int
3985 xmlTextWriterWriteDTDExternalEntityContents(xmlTextWriterPtr writer,
3986 const xmlChar * pubid,
3987 const xmlChar * sysid,
3988 const xmlChar * ndataid)
3989 {
3990 int count;
3991 int sum;
3992 xmlLinkPtr lk;
3993 xmlTextWriterStackEntry *p;
3994
3995 if (writer == NULL) {
3996 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
3997 "xmlTextWriterWriteDTDExternalEntityContents: xmlTextWriterPtr invalid!\n");
3998 return -1;
3999 }
4000
4001 sum = 0;
4002 lk = xmlListFront(writer->nodes);
4003 if (lk == 0) {
4004 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
4005 "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n");
4006 return -1;
4007 }
4008
4009 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
4010 if (p == 0)
4011 return -1;
4012
4013 switch (p->state) {
4014 case XML_TEXTWRITER_DTD_ENTY:
4015 break;
4016 case XML_TEXTWRITER_DTD_PENT:
4017 if (ndataid != NULL) {
4018 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
4019 "xmlTextWriterWriteDTDExternalEntityContents: notation not allowed with parameter entities!\n");
4020 return -1;
4021 }
4022 break;
4023 default:
4024 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
4025 "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n");
4026 return -1;
4027 }
4028
4029 if (pubid != 0) {
4030 if (sysid == 0) {
4031 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
4032 "xmlTextWriterWriteDTDExternalEntityContents: system identifier needed!\n");
4033 return -1;
4034 }
4035
4036 count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
4037 if (count < 0)
4038 return -1;
4039 sum += count;
4040
4041 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4042 if (count < 0)
4043 return -1;
4044 sum += count;
4045
4046 count =
4047 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
4048 if (count < 0)
4049 return -1;
4050 sum += count;
4051
4052 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4053 if (count < 0)
4054 return -1;
4055 sum += count;
4056 }
4057
4058 if (sysid != 0) {
4059 if (pubid == 0) {
4060 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
4061 if (count < 0)
4062 return -1;
4063 sum += count;
4064 }
4065
4066 count = xmlOutputBufferWriteString(writer->out, " ");
4067 if (count < 0)
4068 return -1;
4069 sum += count;
4070
4071 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4072 if (count < 0)
4073 return -1;
4074 sum += count;
4075
4076 count =
4077 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
4078 if (count < 0)
4079 return -1;
4080 sum += count;
4081
4082 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4083 if (count < 0)
4084 return -1;
4085 sum += count;
4086 }
4087
4088 if (ndataid != NULL) {
4089 count = xmlOutputBufferWriteString(writer->out, " NDATA ");
4090 if (count < 0)
4091 return -1;
4092 sum += count;
4093
4094 count =
4095 xmlOutputBufferWriteString(writer->out,
4096 (const char *) ndataid);
4097 if (count < 0)
4098 return -1;
4099 sum += count;
4100 }
4101
4102 return sum;
4103 }
4104
4105 /**
4106 * xmlTextWriterWriteDTDNotation:
4107 * @writer: the xmlTextWriterPtr
4108 * @name: the name of the xml notation
4109 * @pubid: the public identifier, which is an alternative to the system identifier
4110 * @sysid: the system identifier, which is the URI of the DTD
4111 *
4112 * Write a DTD entity.
4113 *
4114 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
4115 */
4116 int
4117 xmlTextWriterWriteDTDNotation(xmlTextWriterPtr writer,
4118 const xmlChar * name,
4119 const xmlChar * pubid, const xmlChar * sysid)
4120 {
4121 int count;
4122 int sum;
4123 xmlLinkPtr lk;
4124 xmlTextWriterStackEntry *p;
4125
4126 if (writer == NULL || name == NULL || *name == '\0')
4127 return -1;
4128
4129 sum = 0;
4130 lk = xmlListFront(writer->nodes);
4131 if (lk == 0) {
4132 return -1;
4133 }
4134
4135 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
4136 if (p != 0) {
4137 switch (p->state) {
4138 case XML_TEXTWRITER_DTD:
4139 count = xmlOutputBufferWriteString(writer->out, " [");
4140 if (count < 0)
4141 return -1;
4142 sum += count;
4143 if (writer->indent) {
4144 count = xmlOutputBufferWriteString(writer->out, "\n");
4145 if (count < 0)
4146 return -1;
4147 sum += count;
4148 }
4149 p->state = XML_TEXTWRITER_DTD_TEXT;
4150 /* fallthrough */
4151 case XML_TEXTWRITER_DTD_TEXT:
4152 break;
4153 default:
4154 return -1;
4155 }
4156 }
4157
4158 if (writer->indent) {
4159 count = xmlTextWriterWriteIndent(writer);
4160 if (count < 0)
4161 return -1;
4162 sum += count;
4163 }
4164
4165 count = xmlOutputBufferWriteString(writer->out, "<!NOTATION ");
4166 if (count < 0)
4167 return -1;
4168 sum += count;
4169 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
4170 if (count < 0)
4171 return -1;
4172 sum += count;
4173
4174 if (pubid != 0) {
4175 count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
4176 if (count < 0)
4177 return -1;
4178 sum += count;
4179 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4180 if (count < 0)
4181 return -1;
4182 sum += count;
4183 count =
4184 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
4185 if (count < 0)
4186 return -1;
4187 sum += count;
4188 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4189 if (count < 0)
4190 return -1;
4191 sum += count;
4192 }
4193
4194 if (sysid != 0) {
4195 if (pubid == 0) {
4196 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
4197 if (count < 0)
4198 return -1;
4199 sum += count;
4200 }
4201 count = xmlOutputBufferWriteString(writer->out, " ");
4202 if (count < 0)
4203 return -1;
4204 sum += count;
4205 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4206 if (count < 0)
4207 return -1;
4208 sum += count;
4209 count =
4210 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
4211 if (count < 0)
4212 return -1;
4213 sum += count;
4214 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4215 if (count < 0)
4216 return -1;
4217 sum += count;
4218 }
4219
4220 count = xmlOutputBufferWriteString(writer->out, ">");
4221 if (count < 0)
4222 return -1;
4223 sum += count;
4224
4225 return sum;
4226 }
4227
4228 /**
4229 * xmlTextWriterFlush:
4230 * @writer: the xmlTextWriterPtr
4231 *
4232 * Flush the output buffer.
4233 *
4234 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
4235 */
4236 int
4237 xmlTextWriterFlush(xmlTextWriterPtr writer)
4238 {
4239 int count;
4240
4241 if (writer == NULL)
4242 return -1;
4243
4244 if (writer->out == NULL)
4245 count = 0;
4246 else
4247 count = xmlOutputBufferFlush(writer->out);
4248
4249 return count;
4250 }
4251
4252 /**
4253 * misc
4254 */
4255
4256 /**
4257 * xmlFreeTextWriterStackEntry:
4258 * @lk: the xmlLinkPtr
4259 *
4260 * Free callback for the xmlList.
4261 */
4262 static void
4263 xmlFreeTextWriterStackEntry(xmlLinkPtr lk)
4264 {
4265 xmlTextWriterStackEntry *p;
4266
4267 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
4268 if (p == 0)
4269 return;
4270
4271 if (p->name != 0)
4272 xmlFree(p->name);
4273 xmlFree(p);
4274 }
4275
4276 /**
4277 * xmlCmpTextWriterStackEntry:
4278 * @data0: the first data
4279 * @data1: the second data
4280 *
4281 * Compare callback for the xmlList.
4282 *
4283 * Returns -1, 0, 1
4284 */
4285 static int
4286 xmlCmpTextWriterStackEntry(const void *data0, const void *data1)
4287 {
4288 xmlTextWriterStackEntry *p0;
4289 xmlTextWriterStackEntry *p1;
4290
4291 if (data0 == data1)
4292 return 0;
4293
4294 if (data0 == 0)
4295 return -1;
4296
4297 if (data1 == 0)
4298 return 1;
4299
4300 p0 = (xmlTextWriterStackEntry *) data0;
4301 p1 = (xmlTextWriterStackEntry *) data1;
4302
4303 return xmlStrcmp(p0->name, p1->name);
4304 }
4305
4306 /**
4307 * misc
4308 */
4309
4310 /**
4311 * xmlTextWriterOutputNSDecl:
4312 * @writer: the xmlTextWriterPtr
4313 *
4314 * Output the current namespace declarations.
4315 */
4316 static int
4317 xmlTextWriterOutputNSDecl(xmlTextWriterPtr writer)
4318 {
4319 xmlLinkPtr lk;
4320 xmlTextWriterNsStackEntry *np;
4321 int count;
4322 int sum;
4323
4324 sum = 0;
4325 while (!xmlListEmpty(writer->nsstack)) {
4326 xmlChar *namespaceURI = NULL;
4327 xmlChar *prefix = NULL;
4328
4329 lk = xmlListFront(writer->nsstack);
4330 np = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
4331
4332 if (np != 0) {
4333 namespaceURI = xmlStrdup(np->uri);
4334 prefix = xmlStrdup(np->prefix);
4335 }
4336
4337 xmlListPopFront(writer->nsstack);
4338
4339 if (np != 0) {
4340 count = xmlTextWriterWriteAttribute(writer, prefix, namespaceURI);
4341 xmlFree(namespaceURI);
4342 xmlFree(prefix);
4343
4344 if (count < 0) {
4345 xmlListDelete(writer->nsstack);
4346 writer->nsstack = NULL;
4347 return -1;
4348 }
4349 sum += count;
4350 }
4351 }
4352 return sum;
4353 }
4354
4355 /**
4356 * xmlFreeTextWriterNsStackEntry:
4357 * @lk: the xmlLinkPtr
4358 *
4359 * Free callback for the xmlList.
4360 */
4361 static void
4362 xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk)
4363 {
4364 xmlTextWriterNsStackEntry *p;
4365
4366 p = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
4367 if (p == 0)
4368 return;
4369
4370 if (p->prefix != 0)
4371 xmlFree(p->prefix);
4372 if (p->uri != 0)
4373 xmlFree(p->uri);
4374
4375 xmlFree(p);
4376 }
4377
4378 /**
4379 * xmlCmpTextWriterNsStackEntry:
4380 * @data0: the first data
4381 * @data1: the second data
4382 *
4383 * Compare callback for the xmlList.
4384 *
4385 * Returns -1, 0, 1
4386 */
4387 static int
4388 xmlCmpTextWriterNsStackEntry(const void *data0, const void *data1)
4389 {
4390 xmlTextWriterNsStackEntry *p0;
4391 xmlTextWriterNsStackEntry *p1;
4392 int rc;
4393
4394 if (data0 == data1)
4395 return 0;
4396
4397 if (data0 == 0)
4398 return -1;
4399
4400 if (data1 == 0)
4401 return 1;
4402
4403 p0 = (xmlTextWriterNsStackEntry *) data0;
4404 p1 = (xmlTextWriterNsStackEntry *) data1;
4405
4406 rc = xmlStrcmp(p0->prefix, p1->prefix);
4407
4408 if ((rc != 0) || (p0->elem != p1->elem))
4409 rc = -1;
4410
4411 return rc;
4412 }
4413
4414 /**
4415 * xmlTextWriterWriteDocCallback:
4416 * @context: the xmlBufferPtr
4417 * @str: the data to write
4418 * @len: the length of the data
4419 *
4420 * Write callback for the xmlOutputBuffer with target xmlBuffer
4421 *
4422 * Returns -1, 0, 1
4423 */
4424 static int
4425 xmlTextWriterWriteDocCallback(void *context, const xmlChar * str, int len)
4426 {
4427 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context;
4428 int rc;
4429
4430 if ((rc = xmlParseChunk(ctxt, (const char *) str, len, 0)) != 0) {
4431 xmlWriterErrMsgInt(NULL, XML_ERR_INTERNAL_ERROR,
4432 "xmlTextWriterWriteDocCallback : XML error %d !\n",
4433 rc);
4434 return -1;
4435 }
4436
4437 return len;
4438 }
4439
4440 /**
4441 * xmlTextWriterCloseDocCallback:
4442 * @context: the xmlBufferPtr
4443 *
4444 * Close callback for the xmlOutputBuffer with target xmlBuffer
4445 *
4446 * Returns -1, 0, 1
4447 */
4448 static int
4449 xmlTextWriterCloseDocCallback(void *context)
4450 {
4451 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context;
4452 int rc;
4453
4454 if ((rc = xmlParseChunk(ctxt, NULL, 0, 1)) != 0) {
4455 xmlWriterErrMsgInt(NULL, XML_ERR_INTERNAL_ERROR,
4456 "xmlTextWriterWriteDocCallback : XML error %d !\n",
4457 rc);
4458 return -1;
4459 }
4460
4461 return 0;
4462 }
4463
4464 /**
4465 * xmlTextWriterVSprintf:
4466 * @format: see printf
4467 * @argptr: pointer to the first member of the variable argument list.
4468 *
4469 * Utility function for formatted output
4470 *
4471 * Returns a new xmlChar buffer with the data or NULL on error. This buffer must be freed.
4472 */
4473 static xmlChar *
4474 xmlTextWriterVSprintf(const char *format, va_list argptr)
4475 {
4476 int size;
4477 int count;
4478 xmlChar *buf;
4479 va_list locarg;
4480
4481 size = BUFSIZ;
4482 buf = (xmlChar *) xmlMalloc(size);
4483 if (buf == NULL) {
4484 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
4485 "xmlTextWriterVSprintf : out of memory!\n");
4486 return NULL;
4487 }
4488
4489 VA_COPY(locarg, argptr);
4490 while (((count = vsnprintf((char *) buf, size, format, locarg)) < 0)
4491 || (count == size - 1) || (count == size) || (count > size)) {
4492 va_end(locarg);
4493 xmlFree(buf);
4494 size += BUFSIZ;
4495 buf = (xmlChar *) xmlMalloc(size);
4496 if (buf == NULL) {
4497 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
4498 "xmlTextWriterVSprintf : out of memory!\n");
4499 return NULL;
4500 }
4501 VA_COPY(locarg, argptr);
4502 }
4503 va_end(locarg);
4504
4505 return buf;
4506 }
4507
4508 /**
4509 * xmlTextWriterStartDocumentCallback:
4510 * @ctx: the user data (XML parser context)
4511 *
4512 * called at the start of document processing.
4513 */
4514 static void
4515 xmlTextWriterStartDocumentCallback(void *ctx)
4516 {
4517 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
4518 xmlDocPtr doc;
4519
4520 if (ctxt->html) {
4521 #ifdef LIBXML_HTML_ENABLED
4522 if (ctxt->myDoc == NULL)
4523 ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
4524 if (ctxt->myDoc == NULL) {
4525 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
4526 ctxt->sax->error(ctxt->userData,
4527 "SAX.startDocument(): out of memory\n");
4528 ctxt->errNo = XML_ERR_NO_MEMORY;
4529 ctxt->instate = XML_PARSER_EOF;
4530 ctxt->disableSAX = 1;
4531 return;
4532 }
4533 #else
4534 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
4535 "libxml2 built without HTML support\n");
4536 ctxt->errNo = XML_ERR_INTERNAL_ERROR;
4537 ctxt->instate = XML_PARSER_EOF;
4538 ctxt->disableSAX = 1;
4539 return;
4540 #endif
4541 } else {
4542 doc = ctxt->myDoc;
4543 if (doc == NULL)
4544 doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
4545 if (doc != NULL) {
4546 if (doc->children == NULL) {
4547 if (ctxt->encoding != NULL)
4548 doc->encoding = xmlStrdup(ctxt->encoding);
4549 else
4550 doc->encoding = NULL;
4551 doc->standalone = ctxt->standalone;
4552 }
4553 } else {
4554 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
4555 ctxt->sax->error(ctxt->userData,
4556 "SAX.startDocument(): out of memory\n");
4557 ctxt->errNo = XML_ERR_NO_MEMORY;
4558 ctxt->instate = XML_PARSER_EOF;
4559 ctxt->disableSAX = 1;
4560 return;
4561 }
4562 }
4563 if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) &&
4564 (ctxt->input != NULL) && (ctxt->input->filename != NULL)) {
4565 ctxt->myDoc->URL =
4566 xmlCanonicPath((const xmlChar *) ctxt->input->filename);
4567 if (ctxt->myDoc->URL == NULL)
4568 ctxt->myDoc->URL =
4569 xmlStrdup((const xmlChar *) ctxt->input->filename);
4570 }
4571 }
4572
4573 /**
4574 * xmlTextWriterSetIndent:
4575 * @writer: the xmlTextWriterPtr
4576 * @indent: do indentation?
4577 *
4578 * Set indentation output. indent = 0 do not indentation. indent > 0 do indentation.
4579 *
4580 * Returns -1 on error or 0 otherwise.
4581 */
4582 int
4583 xmlTextWriterSetIndent(xmlTextWriterPtr writer, int indent)
4584 {
4585 if ((writer == NULL) || (indent < 0))
4586 return -1;
4587
4588 writer->indent = indent;
4589 writer->doindent = 1;
4590
4591 return 0;
4592 }
4593
4594 /**
4595 * xmlTextWriterSetIndentString:
4596 * @writer: the xmlTextWriterPtr
4597 * @str: the xmlChar string
4598 *
4599 * Set string indentation.
4600 *
4601 * Returns -1 on error or 0 otherwise.
4602 */
4603 int
4604 xmlTextWriterSetIndentString(xmlTextWriterPtr writer, const xmlChar * str)
4605 {
4606 if ((writer == NULL) || (!str))
4607 return -1;
4608
4609 if (writer->ichar != NULL)
4610 xmlFree(writer->ichar);
4611 writer->ichar = xmlStrdup(str);
4612
4613 if (!writer->ichar)
4614 return -1;
4615 else
4616 return 0;
4617 }
4618
4619 /**
4620 * xmlTextWriterSetQuoteChar:
4621 * @writer: the xmlTextWriterPtr
4622 * @quotechar: the quote character
4623 *
4624 * Set the character used for quoting attributes.
4625 *
4626 * Returns -1 on error or 0 otherwise.
4627 */
4628 int
4629 xmlTextWriterSetQuoteChar(xmlTextWriterPtr writer, xmlChar quotechar)
4630 {
4631 if ((writer == NULL) || ((quotechar != '\'') && (quotechar != '"')))
4632 return -1;
4633
4634 writer->qchar = quotechar;
4635
4636 return 0;
4637 }
4638
4639 /**
4640 * xmlTextWriterWriteIndent:
4641 * @writer: the xmlTextWriterPtr
4642 *
4643 * Write indent string.
4644 *
4645 * Returns -1 on error or the number of strings written.
4646 */
4647 static int
4648 xmlTextWriterWriteIndent(xmlTextWriterPtr writer)
4649 {
4650 int lksize;
4651 int i;
4652 int ret;
4653
4654 lksize = xmlListSize(writer->nodes);
4655 if (lksize < 1)
4656 return (-1); /* list is empty */
4657 for (i = 0; i < (lksize - 1); i++) {
4658 ret = xmlOutputBufferWriteString(writer->out,
4659 (const char *) writer->ichar);
4660 if (ret == -1)
4661 return (-1);
4662 }
4663
4664 return (lksize - 1);
4665 }
4666
4667 /**
4668 * xmlTextWriterHandleStateDependencies:
4669 * @writer: the xmlTextWriterPtr
4670 * @p: the xmlTextWriterStackEntry
4671 *
4672 * Write state dependent strings.
4673 *
4674 * Returns -1 on error or the number of characters written.
4675 */
4676 static int
4677 xmlTextWriterHandleStateDependencies(xmlTextWriterPtr writer,
4678 xmlTextWriterStackEntry * p)
4679 {
4680 int count;
4681 int sum;
4682 char extra[3];
4683
4684 if (writer == NULL)
4685 return -1;
4686
4687 if (p == NULL)
4688 return 0;
4689
4690 sum = 0;
4691 extra[0] = extra[1] = extra[2] = '\0';
4692 if (p != 0) {
4693 sum = 0;
4694 switch (p->state) {
4695 case XML_TEXTWRITER_NAME:
4696 /* Output namespace declarations */
4697 count = xmlTextWriterOutputNSDecl(writer);
4698 if (count < 0)
4699 return -1;
4700 sum += count;
4701 extra[0] = '>';
4702 p->state = XML_TEXTWRITER_TEXT;
4703 break;
4704 case XML_TEXTWRITER_PI:
4705 extra[0] = ' ';
4706 p->state = XML_TEXTWRITER_PI_TEXT;
4707 break;
4708 case XML_TEXTWRITER_DTD:
4709 extra[0] = ' ';
4710 extra[1] = '[';
4711 p->state = XML_TEXTWRITER_DTD_TEXT;
4712 break;
4713 case XML_TEXTWRITER_DTD_ELEM:
4714 extra[0] = ' ';
4715 p->state = XML_TEXTWRITER_DTD_ELEM_TEXT;
4716 break;
4717 case XML_TEXTWRITER_DTD_ATTL:
4718 extra[0] = ' ';
4719 p->state = XML_TEXTWRITER_DTD_ATTL_TEXT;
4720 break;
4721 case XML_TEXTWRITER_DTD_ENTY:
4722 case XML_TEXTWRITER_DTD_PENT:
4723 extra[0] = ' ';
4724 extra[1] = writer->qchar;
4725 p->state = XML_TEXTWRITER_DTD_ENTY_TEXT;
4726 break;
4727 default:
4728 break;
4729 }
4730 }
4731
4732 if (*extra != '\0') {
4733 count = xmlOutputBufferWriteString(writer->out, extra);
4734 if (count < 0)
4735 return -1;
4736 sum += count;
4737 }
4738
4739 return sum;
4740 }
4741
4742 #define bottom_xmlwriter
4743 #include "elfgcchack.h"
4744 #endif