VirtualBox

source: vbox/trunk/src/libs/libxml2-2.13.2/xmlwriter.c@ 105681

最後變更 在這個檔案從105681是 105420,由 vboxsync 提交於 4 月 前

libxml2-2.12.6: Applied and adjusted our libxml2 changes to 2.12.6. bugref:10730

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

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