Bug Summary

File:xmlwriter.c
Location:line 992, column 25
Description:Value stored to 'count' is never read

Annotated Source Code

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