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