VirtualBox

source: vbox/trunk/src/libs/libxml2-2.6.30/xmlwriter.c@ 34034

Last change on this file since 34034 was 6076, checked in by vboxsync, 17 years ago

Merged dmik/s2 branch (r25959:26751) to the trunk.

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette