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