blob: c6df6f29feb079c9e8bc67b1dfcd6e0eda98894c [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:
871 count = xmlOutputBufferWriteString(writer->out, "/>");
872 if (count < 0)
873 return -1;
874 sum += count;
875 break;
876 case XML_TEXTWRITER_TEXT:
Daniel Veillard2cca4462004-01-02 20:04:23 +0000877 if ((writer->indent) && (writer->doindent)) {
878 count = xmlTextWriterWriteIndent (writer);
879 sum += count;
880 writer->doindent = 1;
881 } else writer->doindent = 1;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000882 count = xmlOutputBufferWriteString(writer->out, "</");
883 if (count < 0)
884 return -1;
885 sum += count;
886 count = xmlOutputBufferWriteString(writer->out,
887 (const char *)p->name);
888 if (count < 0)
889 return -1;
890 sum += count;
891 count = xmlOutputBufferWriteString(writer->out, ">");
892 if (count < 0)
893 return -1;
894 sum += count;
895 break;
896 default:
897 return -1;
898 }
899
Daniel Veillard2cca4462004-01-02 20:04:23 +0000900 if (writer->indent) {
901 count = xmlOutputBufferWriteString (writer->out, "\n");
902 sum += count;
903 }
904
Daniel Veillard1d211e22003-10-20 22:32:39 +0000905 xmlListPopFront(writer->nodes);
906 return sum;
907}
908
909/**
910 * xmlTextWriterFullEndElement:
911 * @writer: the xmlTextWriterPtr
912 *
913 * End the current xml element. Writes an end tag even if the element is empty
914 *
915 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
916 */
917int
918xmlTextWriterFullEndElement(xmlTextWriterPtr writer)
919{
920 int count;
921 int sum;
922 xmlLinkPtr lk;
923 xmlTextWriterStackEntry *p;
924
925 if (writer == NULL)
926 return -1;
927
928 lk = xmlListFront(writer->nodes);
929 if (lk == 0)
930 return -1;
931
932 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
933 if (p == 0)
934 return -1;
935
936 sum = 0;
937 switch (p->state) {
938 case XML_TEXTWRITER_ATTRIBUTE:
939 count = xmlTextWriterEndAttribute(writer);
940 if (count < 0)
941 return -1;
942 sum += count;
943 /* fallthrough */
944 case XML_TEXTWRITER_NAME:
945 count = xmlOutputBufferWriteString(writer->out, ">");
946 if (count < 0)
947 return -1;
948 sum += count;
949 /* fallthrough */
950 case XML_TEXTWRITER_TEXT:
951 count = xmlOutputBufferWriteString(writer->out, "</");
952 if (count < 0)
953 return -1;
954 sum += count;
955 count = xmlOutputBufferWriteString(writer->out,
956 (const char *) p->name);
957 if (count < 0)
958 return -1;
959 sum += count;
960 count = xmlOutputBufferWriteString(writer->out, ">");
961 if (count < 0)
962 return -1;
963 sum += count;
964 break;
965 default:
966 return -1;
967 }
968
969 xmlListPopFront(writer->nodes);
970 return sum;
971}
972
973/**
974 * xmlTextWriterWriteFormatRaw:
975 * @writer: the xmlTextWriterPtr
976 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +0000977 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +0000978 *
979 * Write a formatted raw xml text.
980 *
981 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
982 */
983int
984xmlTextWriterWriteFormatRaw(xmlTextWriterPtr writer, const char *format,
985 ...)
986{
987 int rc;
988 va_list ap;
989
990 va_start(ap, format);
991
992 rc = xmlTextWriterWriteVFormatRaw(writer, format, ap);
993
994 va_end(ap);
995 return rc;
996}
997
998/**
999 * xmlTextWriterWriteVFormatRaw:
1000 * @writer: the xmlTextWriterPtr
1001 * @format: format string (see printf)
1002 * @argptr: pointer to the first member of the variable argument list.
1003 *
1004 * Write a formatted raw xml text.
1005 *
1006 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1007 */
1008int
1009xmlTextWriterWriteVFormatRaw(xmlTextWriterPtr writer, const char *format,
1010 va_list argptr)
1011{
1012 int rc;
1013 xmlChar *buf;
1014
1015 if (writer == NULL)
1016 return -1;
1017
1018 buf = xmlTextWriterVSprintf(format, argptr);
1019 if (buf == 0)
1020 return 0;
1021
1022 rc = xmlTextWriterWriteRaw(writer, buf);
1023
1024 xmlFree(buf);
1025 return rc;
1026}
1027
1028/**
Daniel Veillard1e906612003-12-05 14:57:46 +00001029 * xmlTextWriterWriteRawLen:
Daniel Veillard1d211e22003-10-20 22:32:39 +00001030 * @writer: the xmlTextWriterPtr
1031 * @content: text string
1032 * @len: length of the text string
1033 *
1034 * Write an xml text.
1035 * TODO: what about entities and special chars??
1036 *
1037 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1038 */
1039int
1040xmlTextWriterWriteRawLen(xmlTextWriterPtr writer, const xmlChar * content,
1041 int len)
1042{
1043 int count;
1044 int sum;
1045 xmlLinkPtr lk;
1046 xmlTextWriterStackEntry *p;
1047
1048 if (writer == NULL)
1049 return -1;
1050
1051 lk = xmlListFront(writer->nodes);
1052 if (lk == 0)
1053 return 0;
1054
1055 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1056 if (p == 0)
1057 return 0;
1058
1059 sum = 0;
1060 switch (p->state) {
1061 case XML_TEXTWRITER_NONE:
1062 return -1;
1063 case XML_TEXTWRITER_NAME:
1064 count = xmlOutputBufferWriteString(writer->out, ">");
1065 if (count < 0)
1066 return -1;
1067 sum += count;
1068 p->state = XML_TEXTWRITER_TEXT;
1069 break;
1070 case XML_TEXTWRITER_PI:
1071 count = xmlOutputBufferWriteString(writer->out, " ");
1072 if (count < 0)
1073 return -1;
1074 sum += count;
1075 p->state = XML_TEXTWRITER_PI_TEXT;
1076 break;
1077 case XML_TEXTWRITER_DTD:
1078 count = xmlOutputBufferWriteString(writer->out, " [");
1079 if (count < 0)
1080 return -1;
1081 sum += count;
1082 p->state = XML_TEXTWRITER_DTD_TEXT;
1083 break;
1084 default:
1085 break;
1086 }
1087
1088 count = xmlOutputBufferWrite(writer->out, len, (const char *) content);
1089 if (count < 0)
1090 return -1;
1091 sum += count;
1092
1093 return sum;
1094}
1095
1096/**
1097 * xmlTextWriterWriteRaw:
1098 * @writer: the xmlTextWriterPtr
1099 * @content: text string
1100 *
1101 * Write a raw xml text.
1102 *
1103 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1104 */
1105int
1106xmlTextWriterWriteRaw(xmlTextWriterPtr writer, const xmlChar * content)
1107{
1108 return xmlTextWriterWriteRawLen(writer, content, xmlStrlen(content));
1109}
1110
1111/**
1112 * xmlTextWriterWriteFormatString:
1113 * @writer: the xmlTextWriterPtr
1114 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001115 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001116 *
1117 * Write a formatted xml text.
1118 *
1119 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1120 */
1121int
1122xmlTextWriterWriteFormatString(xmlTextWriterPtr writer, const char *format,
1123 ...)
1124{
1125 int rc;
1126 va_list ap;
1127
1128 va_start(ap, format);
1129
1130 rc = xmlTextWriterWriteVFormatString(writer, format, ap);
1131
1132 va_end(ap);
1133 return rc;
1134}
1135
1136/**
1137 * xmlTextWriterWriteVFormatString:
1138 * @writer: the xmlTextWriterPtr
1139 * @format: format string (see printf)
1140 * @argptr: pointer to the first member of the variable argument list.
1141 *
1142 * Write a formatted xml text.
1143 *
1144 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1145 */
1146int
1147xmlTextWriterWriteVFormatString(xmlTextWriterPtr writer,
1148 const char *format, va_list argptr)
1149{
1150 int rc;
1151 xmlChar *buf;
1152
1153 if (writer == NULL)
1154 return -1;
1155
1156 buf = xmlTextWriterVSprintf(format, argptr);
1157 if (buf == 0)
1158 return 0;
1159
1160 rc = xmlTextWriterWriteString(writer, buf);
1161
1162 xmlFree(buf);
1163 return rc;
1164}
1165
1166/**
1167 * xmlTextWriterWriteString:
1168 * @writer: the xmlTextWriterPtr
1169 * @content: text string
1170 *
1171 * Write an xml text.
1172 *
1173 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1174 */
1175int
1176xmlTextWriterWriteString(xmlTextWriterPtr writer, const xmlChar * content)
1177{
William M. Bracka9c612c2004-02-01 10:04:05 +00001178 int count=0;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001179 int sum;
1180 xmlLinkPtr lk;
1181 xmlTextWriterStackEntry *p;
William M. Bracka9c612c2004-02-01 10:04:05 +00001182 xmlChar *buf=NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001183
1184 if (writer == NULL)
1185 return -1;
1186
1187 lk = xmlListFront(writer->nodes);
1188 if (lk == 0)
1189 return -1;
1190
1191 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1192 if (p == 0)
1193 return -1;
1194
1195 sum = 0;
1196 switch (p->state) {
1197 case XML_TEXTWRITER_NONE:
1198 return -1;
1199 case XML_TEXTWRITER_NAME:
1200 count = xmlOutputBufferWriteString(writer->out, ">");
1201 if (count < 0)
1202 return -1;
1203 sum += count;
1204 p->state = XML_TEXTWRITER_TEXT;
1205 goto encode;
1206 case XML_TEXTWRITER_PI:
1207 count = xmlOutputBufferWriteString(writer->out, " ");
1208 if (count < 0)
1209 return -1;
1210 sum += count;
1211 p->state = XML_TEXTWRITER_PI_TEXT;
1212 /* fallthrough */
1213 case XML_TEXTWRITER_PI_TEXT:
1214 case XML_TEXTWRITER_TEXT:
Daniel Veillard1d211e22003-10-20 22:32:39 +00001215 encode:
Daniel Veillard5841f0e2003-11-20 11:59:09 +00001216 buf = xmlEncodeSpecialChars(NULL, content);
William M. Bracka9c612c2004-02-01 10:04:05 +00001217 if (buf == NULL)
1218 count = -1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001219 break;
William M. Bracka9c612c2004-02-01 10:04:05 +00001220 case XML_TEXTWRITER_ATTRIBUTE:
1221 xmlAttrSerializeTxtContent(writer->out->buffer, NULL,
1222 NULL, content);
1223 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001224 case XML_TEXTWRITER_DTD:
1225 count = xmlOutputBufferWriteString(writer->out, " [");
1226 if (count < 0)
1227 return -1;
1228 sum += count;
1229 p->state = XML_TEXTWRITER_DTD_TEXT;
1230 /* fallthrough */
1231 case XML_TEXTWRITER_DTD_TEXT:
1232 case XML_TEXTWRITER_DTD_ELEM:
1233 case XML_TEXTWRITER_CDATA:
1234 buf = xmlStrdup(content);
William M. Bracka9c612c2004-02-01 10:04:05 +00001235 if (buf == NULL)
1236 count = -1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001237 break;
1238 default:
1239 break;
1240 }
1241
Daniel Veillard751c9ec2004-01-05 13:05:58 +00001242 if (writer->indent)
1243 writer->doindent = 0;
1244
Daniel Veillard1d211e22003-10-20 22:32:39 +00001245 if (buf != 0) {
Daniel Veillard5841f0e2003-11-20 11:59:09 +00001246 count =
1247 xmlOutputBufferWriteString(writer->out, (const char *) buf);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001248 xmlFree(buf);
William M. Bracka9c612c2004-02-01 10:04:05 +00001249 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001250 if (count < 0)
1251 return -1;
1252 sum += count;
1253
1254 return sum;
1255}
1256
1257/**
1258 * xmlOutputBufferWriteBase64:
1259 * @out: the xmlOutputBufferPtr
1260 * @data: binary data
1261 * @len: the number of bytes to encode
1262 *
1263 * Write base64 encoded data to an xmlOutputBuffer.
1264 * Adapted from John Walker's base64.c (http://www.fourmilab.ch/).
1265 *
1266 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1267 */
1268static int
1269xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len,
1270 const unsigned char *data)
1271{
1272 static unsigned char dtable[64] =
1273 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1274 int i;
1275 int linelen;
1276 int count;
1277 int sum;
1278
1279 linelen = 0;
1280 sum = 0;
1281
1282 i = 0;
1283 while (1) {
1284 unsigned char igroup[3];
1285 unsigned char ogroup[4];
1286 int c;
1287 int n;
1288
1289 igroup[0] = igroup[1] = igroup[2] = 0;
1290 for (n = 0; n < 3 && i < len; n++, i++) {
1291 c = data[i];
1292 igroup[n] = (unsigned char) c;
1293 }
1294
1295 if (n > 0) {
1296 ogroup[0] = dtable[igroup[0] >> 2];
1297 ogroup[1] = dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)];
1298 ogroup[2] =
1299 dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)];
1300 ogroup[3] = dtable[igroup[2] & 0x3F];
1301
1302 if (n < 3) {
1303 ogroup[3] = '=';
1304 if (n < 2) {
1305 ogroup[2] = '=';
1306 }
1307 }
1308
1309 if (linelen >= B64LINELEN) {
1310 count = xmlOutputBufferWrite(out, 2, B64CRLF);
1311 if (count == -1)
1312 return -1;
1313 sum += count;
1314 linelen = 0;
1315 }
1316 count = xmlOutputBufferWrite(out, 4, (const char *) ogroup);
1317 if (count == -1)
1318 return -1;
1319 sum += count;
1320
1321 linelen += 4;
1322 }
Daniel Veillard929714b2003-10-22 12:34:36 +00001323
1324 if (i >= len)
1325 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001326 }
1327
1328 count = xmlOutputBufferWrite(out, 2, B64CRLF);
1329 if (count == -1)
1330 return -1;
1331 sum += count;
1332
1333 return sum;
1334}
1335
1336/**
1337 * xmlTextWriterWriteBase64:
1338 * @writer: the xmlTextWriterPtr
1339 * @data: binary data
1340 * @start: the position within the data of the first byte to encode
1341 * @len: the number of bytes to encode
1342 *
1343 * Write an base64 encoded xml text.
1344 *
1345 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1346 */
1347int
1348xmlTextWriterWriteBase64(xmlTextWriterPtr writer, const char * data,
1349 int start, int len)
1350{
1351 int count;
1352 int sum;
1353 xmlLinkPtr lk;
1354 xmlTextWriterStackEntry *p;
1355
1356 if (writer == NULL)
1357 return -1;
1358
1359 lk = xmlListFront(writer->nodes);
1360 if (lk == 0)
1361 return 0;
1362
1363 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1364 if (p == 0)
1365 return 0;
1366
1367 sum = 0;
1368 switch (p->state) {
1369 case XML_TEXTWRITER_NONE:
1370 return -1;
1371 case XML_TEXTWRITER_NAME:
1372 count = xmlOutputBufferWriteString(writer->out, ">");
1373 if (count < 0)
1374 return -1;
1375 sum += count;
1376 p->state = XML_TEXTWRITER_TEXT;
1377 break;
1378 case XML_TEXTWRITER_PI:
1379 count = xmlOutputBufferWriteString(writer->out, " ");
1380 if (count < 0)
1381 return -1;
1382 sum += count;
1383 p->state = XML_TEXTWRITER_PI_TEXT;
1384 break;
1385 case XML_TEXTWRITER_DTD:
1386 count = xmlOutputBufferWriteString(writer->out, " [");
1387 if (count < 0)
1388 return -1;
1389 sum += count;
1390 p->state = XML_TEXTWRITER_DTD_TEXT;
1391 break;
1392 default:
1393 break;
1394 }
1395
1396 count =
1397 xmlOutputBufferWriteBase64(writer->out, len,
1398 (unsigned char *) data + start);
1399 if (count < 0)
1400 return -1;
1401 sum += count;
1402
1403 return sum;
1404}
1405
1406/**
1407 * xmlOutputBufferWriteBinHex:
1408 * @out: the xmlOutputBufferPtr
1409 * @data: binary data
1410 * @len: the number of bytes to encode
1411 *
1412 * Write hqx encoded data to an xmlOutputBuffer.
1413 * ::todo
1414 *
1415 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1416 */
1417static int
1418xmlOutputBufferWriteBinHex(xmlOutputBufferPtr out ATTRIBUTE_UNUSED,
1419 int len ATTRIBUTE_UNUSED,
1420 const unsigned char *data ATTRIBUTE_UNUSED)
1421{
1422 return -1;
1423}
1424
1425/**
1426 * xmlTextWriterWriteBinHex:
1427 * @writer: the xmlTextWriterPtr
1428 * @data: binary data
1429 * @start: the position within the data of the first byte to encode
1430 * @len: the number of bytes to encode
1431 *
1432 * Write a BinHex encoded xml text.
1433 *
1434 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1435 */
1436int
1437xmlTextWriterWriteBinHex(xmlTextWriterPtr writer, const char * data,
1438 int start, int len)
1439{
1440 int count;
1441 int sum;
1442 xmlLinkPtr lk;
1443 xmlTextWriterStackEntry *p;
1444
1445 if (writer == NULL)
1446 return -1;
1447
1448 lk = xmlListFront(writer->nodes);
1449 if (lk == 0)
1450 return 0;
1451
1452 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1453 if (p == 0)
1454 return 0;
1455
1456 sum = 0;
1457 switch (p->state) {
1458 case XML_TEXTWRITER_NONE:
1459 return -1;
1460 case XML_TEXTWRITER_NAME:
1461 count = xmlOutputBufferWriteString(writer->out, ">");
1462 if (count < 0)
1463 return -1;
1464 sum += count;
1465 p->state = XML_TEXTWRITER_TEXT;
1466 break;
1467 case XML_TEXTWRITER_PI:
1468 count = xmlOutputBufferWriteString(writer->out, " ");
1469 if (count < 0)
1470 return -1;
1471 sum += count;
1472 p->state = XML_TEXTWRITER_PI_TEXT;
1473 break;
1474 case XML_TEXTWRITER_DTD:
1475 count = xmlOutputBufferWriteString(writer->out, " [");
1476 if (count < 0)
1477 return -1;
1478 sum += count;
1479 p->state = XML_TEXTWRITER_DTD_TEXT;
1480 break;
1481 default:
1482 break;
1483 }
1484
1485 count =
1486 xmlOutputBufferWriteBinHex(writer->out, len,
1487 (unsigned char *) data + start);
1488 if (count < 0)
1489 return -1;
1490 sum += count;
1491
1492 return sum;
1493}
1494
1495/**
1496 * xmlTextWriterStartAttribute:
1497 * @writer: the xmlTextWriterPtr
1498 * @name: element name
1499 *
1500 * Start an xml attribute.
1501 *
1502 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1503 */
1504int
1505xmlTextWriterStartAttribute(xmlTextWriterPtr writer, const xmlChar * name)
1506{
1507 int count;
1508 int sum;
1509 xmlLinkPtr lk;
1510 xmlTextWriterStackEntry *p;
1511
1512 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1513 return -1;
1514
1515 sum = 0;
1516 lk = xmlListFront(writer->nodes);
1517 if (lk == 0)
1518 return -1;
1519
1520 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1521 if (p == 0)
1522 return -1;
1523
1524 switch (p->state) {
1525 case XML_TEXTWRITER_ATTRIBUTE:
1526 count = xmlTextWriterEndAttribute(writer);
1527 if (count < 0)
1528 return -1;
1529 sum += count;
1530 /* fallthrough */
1531 case XML_TEXTWRITER_NAME:
1532 count = xmlOutputBufferWriteString(writer->out, " ");
1533 if (count < 0)
1534 return -1;
1535 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00001536 count =
1537 xmlOutputBufferWriteString(writer->out,
1538 (const char *) name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001539 if (count < 0)
1540 return -1;
1541 sum += count;
1542 count = xmlOutputBufferWriteString(writer->out, "=");
1543 if (count < 0)
1544 return -1;
1545 sum += count;
1546 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
1547 if (count < 0)
1548 return -1;
1549 sum += count;
1550 p->state = XML_TEXTWRITER_ATTRIBUTE;
1551 break;
1552 default:
1553 return -1;
1554 }
1555
1556 return sum;
1557}
1558
1559/**
1560 * xmlTextWriterStartAttributeNS:
1561 * @writer: the xmlTextWriterPtr
1562 * @prefix: namespace prefix or NULL
1563 * @name: element local name
1564 * @namespaceURI: namespace URI or NULL
1565 *
1566 * Start an xml attribute with namespace support.
1567 *
1568 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1569 */
1570int
1571xmlTextWriterStartAttributeNS(xmlTextWriterPtr writer,
1572 const xmlChar * prefix, const xmlChar * name,
1573 const xmlChar * namespaceURI)
1574{
1575 int count;
1576 int sum;
1577 xmlChar *buf;
1578 xmlTextWriterNsStackEntry *p;
1579
1580 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1581 return -1;
1582
1583 buf = 0;
1584 if (prefix != 0) {
1585 buf = xmlStrdup(prefix);
1586 buf = xmlStrcat(buf, BAD_CAST ":");
1587 }
1588 buf = xmlStrcat(buf, name);
1589
1590 sum = 0;
1591 count = xmlTextWriterStartAttribute(writer, buf);
1592 xmlFree(buf);
1593 if (count < 0)
1594 return -1;
1595 sum += count;
1596
1597 if (namespaceURI != 0) {
1598 buf = xmlStrdup(BAD_CAST "xmlns");
1599 if (prefix != 0) {
1600 buf = xmlStrcat(buf, BAD_CAST ":");
1601 buf = xmlStrcat(buf, prefix);
1602 }
1603
1604 p = (xmlTextWriterNsStackEntry *)
1605 xmlMalloc(sizeof(xmlTextWriterNsStackEntry));
1606 if (p == 0) {
1607 xmlGenericError(xmlGenericErrorContext,
1608 "xmlTextWriterStartAttributeNS : out of memory!\n");
1609 return -1;
1610 }
1611
1612 p->prefix = buf;
1613 p->uri = xmlStrdup(namespaceURI);
1614 if (p->uri == 0) {
1615 xmlGenericError(xmlGenericErrorContext,
1616 "xmlTextWriterStartAttributeNS : out of memory!\n");
1617 xmlFree(p);
1618 return -1;
1619 }
1620 p->elem = xmlListFront(writer->nodes);
1621
1622 xmlListPushFront(writer->nsstack, p);
1623 }
1624
1625 return sum;
1626}
1627
1628/**
1629 * xmlTextWriterEndAttribute:
1630 * @writer: the xmlTextWriterPtr
1631 *
1632 * End the current xml element.
1633 *
1634 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1635 */
1636int
1637xmlTextWriterEndAttribute(xmlTextWriterPtr writer)
1638{
1639 int count;
1640 int sum;
1641 xmlLinkPtr lk;
1642 xmlTextWriterStackEntry *p;
1643 xmlTextWriterNsStackEntry *np;
1644
1645 if (writer == NULL)
1646 return -1;
1647
1648 lk = xmlListFront(writer->nodes);
1649 if (lk == 0) {
1650 xmlListDelete(writer->nsstack);
1651 return -1;
1652 }
1653
1654 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1655 if (p == 0) {
1656 xmlListDelete(writer->nsstack);
1657 return -1;
1658 }
1659
1660 sum = 0;
1661 switch (p->state) {
1662 case XML_TEXTWRITER_ATTRIBUTE:
1663 p->state = XML_TEXTWRITER_NAME;
1664
1665 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
1666 if (count < 0) {
1667 xmlListDelete(writer->nsstack);
1668 return -1;
1669 }
1670 sum += count;
1671
1672 while (!xmlListEmpty(writer->nsstack)) {
1673 lk = xmlListFront(writer->nsstack);
1674 np = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
1675 if (np != 0) {
1676 count =
1677 xmlTextWriterWriteAttribute(writer, np->prefix,
1678 np->uri);
1679 if (count < 0) {
1680 xmlListDelete(writer->nsstack);
1681 return -1;
1682 }
1683 sum += count;
1684 }
1685
1686 xmlListPopFront(writer->nsstack);
1687 }
1688 break;
1689
1690 default:
1691 xmlListClear(writer->nsstack);
1692 return -1;
1693 }
1694
1695 return sum;
1696}
1697
1698/**
1699 * xmlTextWriterWriteFormatAttribute:
1700 * @writer: the xmlTextWriterPtr
1701 * @name: attribute name
1702 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001703 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001704 *
1705 * Write a formatted xml attribute.
1706 *
1707 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1708 */
1709int
1710xmlTextWriterWriteFormatAttribute(xmlTextWriterPtr writer,
1711 const xmlChar * name, const char *format,
1712 ...)
1713{
1714 int rc;
1715 va_list ap;
1716
1717 va_start(ap, format);
1718
1719 rc = xmlTextWriterWriteVFormatAttribute(writer, name, format, ap);
1720
1721 va_end(ap);
1722 return rc;
1723}
1724
1725/**
1726 * xmlTextWriterWriteVFormatAttribute:
1727 * @writer: the xmlTextWriterPtr
1728 * @name: attribute name
1729 * @format: format string (see printf)
1730 * @argptr: pointer to the first member of the variable argument list.
1731 *
1732 * Write a formatted xml attribute.
1733 *
1734 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1735 */
1736int
1737xmlTextWriterWriteVFormatAttribute(xmlTextWriterPtr writer,
1738 const xmlChar * name,
1739 const char *format, va_list argptr)
1740{
1741 int rc;
1742 xmlChar *buf;
1743
1744 if (writer == NULL)
1745 return -1;
1746
1747 buf = xmlTextWriterVSprintf(format, argptr);
1748 if (buf == 0)
1749 return 0;
1750
1751 rc = xmlTextWriterWriteAttribute(writer, name, buf);
1752
1753 xmlFree(buf);
1754 return rc;
1755}
1756
1757/**
1758 * xmlTextWriterWriteAttribute:
1759 * @writer: the xmlTextWriterPtr
1760 * @name: attribute name
1761 * @content: attribute content
1762 *
1763 * Write an xml attribute.
1764 *
1765 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1766 */
1767int
1768xmlTextWriterWriteAttribute(xmlTextWriterPtr writer, const xmlChar * name,
1769 const xmlChar * content)
1770{
1771 int count;
1772 int sum;
1773
1774 sum = 0;
1775 count = xmlTextWriterStartAttribute(writer, name);
1776 if (count < 0)
1777 return -1;
1778 sum += count;
1779 count = xmlTextWriterWriteString(writer, content);
1780 if (count < 0)
1781 return -1;
1782 sum += count;
1783 count = xmlTextWriterEndAttribute(writer);
1784 if (count < 0)
1785 return -1;
1786 sum += count;
1787
1788 return sum;
1789}
1790
1791/**
1792 * xmlTextWriterWriteFormatAttributeNS:
1793 * @writer: the xmlTextWriterPtr
1794 * @prefix: namespace prefix
1795 * @name: attribute local name
1796 * @namespaceURI: namespace URI
1797 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001798 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001799 *
1800 * Write a formatted xml attribute.with namespace support
1801 *
1802 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1803 */
1804int
1805xmlTextWriterWriteFormatAttributeNS(xmlTextWriterPtr writer,
1806 const xmlChar * prefix,
1807 const xmlChar * name,
1808 const xmlChar * namespaceURI,
1809 const char *format, ...)
1810{
1811 int rc;
1812 va_list ap;
1813
1814 va_start(ap, format);
1815
1816 rc = xmlTextWriterWriteVFormatAttributeNS(writer, prefix, name,
1817 namespaceURI, format, ap);
1818
1819 va_end(ap);
1820 return rc;
1821}
1822
1823/**
1824 * xmlTextWriterWriteVFormatAttributeNS:
1825 * @writer: the xmlTextWriterPtr
1826 * @prefix: namespace prefix
1827 * @name: attribute local name
1828 * @namespaceURI: namespace URI
1829 * @format: format string (see printf)
1830 * @argptr: pointer to the first member of the variable argument list.
1831 *
1832 * Write a formatted xml attribute.with namespace support
1833 *
1834 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1835 */
1836int
1837xmlTextWriterWriteVFormatAttributeNS(xmlTextWriterPtr writer,
1838 const xmlChar * prefix,
1839 const xmlChar * name,
1840 const xmlChar * namespaceURI,
1841 const char *format, va_list argptr)
1842{
1843 int rc;
1844 xmlChar *buf;
1845
1846 if (writer == NULL)
1847 return -1;
1848
1849 buf = xmlTextWriterVSprintf(format, argptr);
1850 if (buf == 0)
1851 return 0;
1852
1853 rc = xmlTextWriterWriteAttributeNS(writer, prefix, name, namespaceURI,
1854 buf);
1855
1856 xmlFree(buf);
1857 return rc;
1858}
1859
1860/**
1861 * xmlTextWriterWriteAttributeNS:
1862 * @writer: the xmlTextWriterPtr
1863 * @prefix: namespace prefix
1864 * @name: attribute local name
1865 * @namespaceURI: namespace URI
1866 * @content: attribute content
1867 *
1868 * Write an xml attribute.
1869 *
1870 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1871 */
1872int
1873xmlTextWriterWriteAttributeNS(xmlTextWriterPtr writer,
1874 const xmlChar * prefix, const xmlChar * name,
1875 const xmlChar * namespaceURI,
1876 const xmlChar * content)
1877{
1878 int count;
1879 int sum;
1880 xmlChar *buf;
1881
1882 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1883 return -1;
1884
1885 buf = 0;
1886 if (prefix != NULL) {
1887 buf = xmlStrdup(prefix);
1888 buf = xmlStrcat(buf, BAD_CAST ":");
1889 }
1890 buf = xmlStrcat(buf, name);
1891
1892 sum = 0;
1893 count = xmlTextWriterWriteAttribute(writer, buf, content);
1894 xmlFree(buf);
1895 if (count < 0)
1896 return -1;
1897 sum += count;
1898
1899 if (namespaceURI != NULL) {
1900 buf = 0;
1901 buf = xmlStrdup(BAD_CAST "xmlns");
1902 if (prefix != NULL) {
1903 buf = xmlStrcat(buf, BAD_CAST ":");
1904 buf = xmlStrcat(buf, prefix);
1905 }
1906 count = xmlTextWriterWriteAttribute(writer, buf, namespaceURI);
1907 xmlFree(buf);
1908 if (count < 0)
1909 return -1;
1910 sum += count;
1911 }
1912 return sum;
1913}
1914
1915/**
1916 * xmlTextWriterWriteFormatElement:
1917 * @writer: the xmlTextWriterPtr
1918 * @name: element name
1919 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001920 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001921 *
1922 * Write a formatted xml element.
1923 *
1924 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1925 */
1926int
1927xmlTextWriterWriteFormatElement(xmlTextWriterPtr writer,
1928 const xmlChar * name, const char *format,
1929 ...)
1930{
1931 int rc;
1932 va_list ap;
1933
1934 va_start(ap, format);
1935
1936 rc = xmlTextWriterWriteVFormatElement(writer, name, format, ap);
1937
1938 va_end(ap);
1939 return rc;
1940}
1941
1942/**
1943 * xmlTextWriterWriteVFormatElement:
1944 * @writer: the xmlTextWriterPtr
1945 * @name: element name
1946 * @format: format string (see printf)
1947 * @argptr: pointer to the first member of the variable argument list.
1948 *
1949 * Write a formatted xml element.
1950 *
1951 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1952 */
1953int
1954xmlTextWriterWriteVFormatElement(xmlTextWriterPtr writer,
1955 const xmlChar * name, const char *format,
1956 va_list argptr)
1957{
1958 int rc;
1959 xmlChar *buf;
1960
1961 if (writer == NULL)
1962 return -1;
1963
1964 buf = xmlTextWriterVSprintf(format, argptr);
1965 if (buf == 0)
1966 return 0;
1967
1968 rc = xmlTextWriterWriteElement(writer, name, buf);
1969
1970 xmlFree(buf);
1971 return rc;
1972}
1973
1974/**
1975 * xmlTextWriterWriteElement:
1976 * @writer: the xmlTextWriterPtr
1977 * @name: element name
1978 * @content: element content
1979 *
1980 * Write an xml element.
1981 *
1982 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1983 */
1984int
1985xmlTextWriterWriteElement(xmlTextWriterPtr writer, const xmlChar * name,
1986 const xmlChar * content)
1987{
1988 int count;
1989 int sum;
1990
1991 sum = 0;
1992 count = xmlTextWriterStartElement(writer, name);
1993 if (count == -1)
1994 return -1;
1995 sum += count;
1996 count = xmlTextWriterWriteString(writer, content);
1997 if (count == -1)
1998 return -1;
1999 sum += count;
2000 count = xmlTextWriterEndElement(writer);
2001 if (count == -1)
2002 return -1;
2003 sum += count;
2004
2005 return sum;
2006}
2007
2008/**
2009 * xmlTextWriterWriteFormatElementNS:
2010 * @writer: the xmlTextWriterPtr
2011 * @prefix: namespace prefix
2012 * @name: element local name
2013 * @namespaceURI: namespace URI
2014 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002015 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002016 *
2017 * Write a formatted xml element with namespace support.
2018 *
2019 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2020 */
2021int
2022xmlTextWriterWriteFormatElementNS(xmlTextWriterPtr writer,
2023 const xmlChar * prefix,
2024 const xmlChar * name,
2025 const xmlChar * namespaceURI,
2026 const char *format, ...)
2027{
2028 int rc;
2029 va_list ap;
2030
2031 va_start(ap, format);
2032
2033 rc = xmlTextWriterWriteVFormatElementNS(writer, prefix, name,
2034 namespaceURI, format, ap);
2035
2036 va_end(ap);
2037 return rc;
2038}
2039
2040/**
2041 * xmlTextWriterWriteVFormatElementNS:
2042 * @writer: the xmlTextWriterPtr
2043 * @prefix: namespace prefix
2044 * @name: element local name
2045 * @namespaceURI: namespace URI
2046 * @format: format string (see printf)
2047 * @argptr: pointer to the first member of the variable argument list.
2048 *
2049 * Write a formatted xml element with namespace support.
2050 *
2051 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2052 */
2053int
2054xmlTextWriterWriteVFormatElementNS(xmlTextWriterPtr writer,
2055 const xmlChar * prefix,
2056 const xmlChar * name,
2057 const xmlChar * namespaceURI,
2058 const char *format, va_list argptr)
2059{
2060 int rc;
2061 xmlChar *buf;
2062
2063 if (writer == NULL)
2064 return -1;
2065
2066 buf = xmlTextWriterVSprintf(format, argptr);
2067 if (buf == 0)
2068 return 0;
2069
2070 rc = xmlTextWriterWriteElementNS(writer, prefix, name, namespaceURI,
2071 buf);
2072
2073 xmlFree(buf);
2074 return rc;
2075}
2076
2077/**
2078 * xmlTextWriterWriteElementNS:
2079 * @writer: the xmlTextWriterPtr
2080 * @prefix: namespace prefix
2081 * @name: element local name
2082 * @namespaceURI: namespace URI
2083 * @content: element content
2084 *
2085 * Write an xml element with namespace support.
2086 *
2087 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2088 */
2089int
2090xmlTextWriterWriteElementNS(xmlTextWriterPtr writer,
2091 const xmlChar * prefix, const xmlChar * name,
2092 const xmlChar * namespaceURI,
2093 const xmlChar * content)
2094{
2095 int count;
2096 int sum;
2097
2098 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
2099 return -1;
2100
2101 sum = 0;
2102 count =
2103 xmlTextWriterStartElementNS(writer, prefix, name, namespaceURI);
2104 if (count < 0)
2105 return -1;
2106 sum += count;
2107 count = xmlTextWriterWriteString(writer, content);
2108 if (count == -1)
2109 return -1;
2110 sum += count;
2111 count = xmlTextWriterEndElement(writer);
2112 if (count == -1)
2113 return -1;
2114 sum += count;
2115
2116 return sum;
2117}
2118
2119/**
2120 * xmlTextWriterStartPI:
2121 * @writer: the xmlTextWriterPtr
2122 * @target: PI target
2123 *
2124 * Start an xml PI.
2125 *
2126 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2127 */
2128int
2129xmlTextWriterStartPI(xmlTextWriterPtr writer, const xmlChar * target)
2130{
2131 int count;
2132 int sum;
2133 xmlLinkPtr lk;
2134 xmlTextWriterStackEntry *p;
2135
2136 if ((writer == NULL) || (target == NULL) || (*target == '\0'))
2137 return -1;
2138
2139 if (xmlStrcasecmp(target, (const xmlChar *) "xml") == 0) {
2140 xmlGenericError(xmlGenericErrorContext,
2141 "xmlTextWriterStartPI : target name [Xx][Mm][Ll] is reserved for xml standardization!\n");
2142 return -1;
2143 }
2144
2145 sum = 0;
2146 lk = xmlListFront(writer->nodes);
2147 if (lk != 0) {
2148 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2149 if (p != 0) {
2150 switch (p->state) {
2151 case XML_TEXTWRITER_ATTRIBUTE:
2152 count = xmlTextWriterEndAttribute(writer);
2153 if (count < 0)
2154 return -1;
2155 sum += count;
2156 /* fallthrough */
2157 case XML_TEXTWRITER_NAME:
2158 count = xmlOutputBufferWriteString(writer->out, ">");
2159 if (count < 0)
2160 return -1;
2161 sum += count;
2162 p->state = XML_TEXTWRITER_TEXT;
2163 break;
Daniel Veillard10c08c72003-12-09 15:14:26 +00002164 case XML_TEXTWRITER_NONE:
2165 case XML_TEXTWRITER_TEXT:
2166 case XML_TEXTWRITER_DTD:
2167 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002168 case XML_TEXTWRITER_PI:
2169 case XML_TEXTWRITER_PI_TEXT:
2170 xmlGenericError(xmlGenericErrorContext,
2171 "xmlTextWriterStartPI : nested PI!\n");
2172 return -1;
2173 default:
2174 return -1;
2175 }
2176 }
2177 }
2178
2179 p = (xmlTextWriterStackEntry *)
2180 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2181 if (p == 0) {
2182 xmlGenericError(xmlGenericErrorContext,
2183 "xmlTextWriterStartPI : out of memory!\n");
2184 return -1;
2185 }
2186
2187 p->name = xmlStrdup(target);
2188 if (p->name == 0) {
2189 xmlGenericError(xmlGenericErrorContext,
2190 "xmlTextWriterStartPI : out of memory!\n");
2191 xmlFree(p);
2192 return -1;
2193 }
2194 p->state = XML_TEXTWRITER_PI;
2195
2196 xmlListPushFront(writer->nodes, p);
2197
2198 count = xmlOutputBufferWriteString(writer->out, "<?");
2199 if (count < 0)
2200 return -1;
2201 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002202 count =
2203 xmlOutputBufferWriteString(writer->out, (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002204 if (count < 0)
2205 return -1;
2206 sum += count;
2207
2208 return sum;
2209}
2210
2211/**
2212 * xmlTextWriterEndPI:
2213 * @writer: the xmlTextWriterPtr
2214 *
2215 * End the current xml PI.
2216 *
2217 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2218 */
2219int
2220xmlTextWriterEndPI(xmlTextWriterPtr writer)
2221{
2222 int count;
2223 int sum;
2224 xmlLinkPtr lk;
2225 xmlTextWriterStackEntry *p;
2226
2227 if (writer == NULL)
2228 return -1;
2229
2230 lk = xmlListFront(writer->nodes);
2231 if (lk == 0)
2232 return 0;
2233
2234 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2235 if (p == 0)
2236 return 0;
2237
2238 sum = 0;
2239 switch (p->state) {
2240 case XML_TEXTWRITER_PI:
2241 case XML_TEXTWRITER_PI_TEXT:
2242 count = xmlOutputBufferWriteString(writer->out, "?>");
2243 if (count < 0)
2244 return -1;
2245 sum += count;
2246 break;
2247 default:
2248 return -1;
2249 }
2250
2251 xmlListPopFront(writer->nodes);
2252 return sum;
2253}
2254
2255/**
2256 * xmlTextWriterWriteFormatPI:
2257 * @writer: the xmlTextWriterPtr
2258 * @target: PI target
2259 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002260 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002261 *
2262 * Write a formatted PI.
2263 *
2264 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2265 */
2266int
2267xmlTextWriterWriteFormatPI(xmlTextWriterPtr writer, const xmlChar * target,
2268 const char *format, ...)
2269{
2270 int rc;
2271 va_list ap;
2272
2273 va_start(ap, format);
2274
2275 rc = xmlTextWriterWriteVFormatPI(writer, target, format, ap);
2276
2277 va_end(ap);
2278 return rc;
2279}
2280
2281/**
2282 * xmlTextWriterWriteVFormatPI:
2283 * @writer: the xmlTextWriterPtr
2284 * @target: PI target
2285 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002286 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00002287 *
2288 * Write a formatted xml PI.
2289 *
2290 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2291 */
2292int
2293xmlTextWriterWriteVFormatPI(xmlTextWriterPtr writer,
2294 const xmlChar * target, const char *format,
2295 va_list argptr)
2296{
2297 int rc;
2298 xmlChar *buf;
2299
2300 if (writer == NULL)
2301 return -1;
2302
2303 buf = xmlTextWriterVSprintf(format, argptr);
2304 if (buf == 0)
2305 return 0;
2306
2307 rc = xmlTextWriterWritePI(writer, target, buf);
2308
2309 xmlFree(buf);
2310 return rc;
2311}
2312
2313/**
2314 * xmlTextWriterWritePI:
2315 * @writer: the xmlTextWriterPtr
2316 * @target: PI target
2317 * @content: PI content
2318 *
2319 * Write an xml PI.
2320 *
2321 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2322 */
2323int
2324xmlTextWriterWritePI(xmlTextWriterPtr writer, const xmlChar * target,
2325 const xmlChar * content)
2326{
2327 int count;
2328 int sum;
2329
2330 sum = 0;
2331 count = xmlTextWriterStartPI(writer, target);
2332 if (count == -1)
2333 return -1;
2334 sum += count;
2335 if (content != 0) {
2336 count = xmlTextWriterWriteString(writer, content);
2337 if (count == -1)
2338 return -1;
2339 sum += count;
2340 }
2341 count = xmlTextWriterEndPI(writer);
2342 if (count == -1)
2343 return -1;
2344 sum += count;
2345
2346 return sum;
2347}
2348
2349/**
2350 * xmlTextWriterStartCDATA:
2351 * @writer: the xmlTextWriterPtr
2352 *
2353 * Start an xml CDATA section.
2354 *
2355 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2356 */
2357int
2358xmlTextWriterStartCDATA(xmlTextWriterPtr writer)
2359{
2360 int count;
2361 int sum;
2362 xmlLinkPtr lk;
2363 xmlTextWriterStackEntry *p;
2364
2365 if (writer == NULL)
2366 return -1;
2367
2368 sum = 0;
2369 lk = xmlListFront(writer->nodes);
2370 if (lk != 0) {
2371 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2372 if (p != 0) {
2373 switch (p->state) {
2374 case XML_TEXTWRITER_NONE:
2375 case XML_TEXTWRITER_PI:
2376 case XML_TEXTWRITER_PI_TEXT:
2377 break;
2378 case XML_TEXTWRITER_ATTRIBUTE:
2379 count = xmlTextWriterEndAttribute(writer);
2380 if (count < 0)
2381 return -1;
2382 sum += count;
2383 /* fallthrough */
2384 case XML_TEXTWRITER_NAME:
2385 count = xmlOutputBufferWriteString(writer->out, ">");
2386 if (count < 0)
2387 return -1;
2388 sum += count;
2389 p->state = XML_TEXTWRITER_TEXT;
2390 break;
2391 case XML_TEXTWRITER_CDATA:
2392 xmlGenericError(xmlGenericErrorContext,
2393 "xmlTextWriterStartCDATA : CDATA not allowed in this context!\n");
2394 return -1;
2395 default:
2396 return -1;
2397 }
2398 }
2399 }
2400
2401 p = (xmlTextWriterStackEntry *)
2402 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2403 if (p == 0) {
2404 xmlGenericError(xmlGenericErrorContext,
2405 "xmlTextWriterStartCDATA : out of memory!\n");
2406 return -1;
2407 }
2408
2409 p->name = 0;
2410 p->state = XML_TEXTWRITER_CDATA;
2411
2412 xmlListPushFront(writer->nodes, p);
2413
2414 count = xmlOutputBufferWriteString(writer->out, "<![CDATA[");
2415 if (count < 0)
2416 return -1;
2417 sum += count;
2418
2419 return sum;
2420}
2421
2422/**
2423 * xmlTextWriterEndCDATA:
2424 * @writer: the xmlTextWriterPtr
2425 *
2426 * End an xml CDATA section.
2427 *
2428 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2429 */
2430int
2431xmlTextWriterEndCDATA(xmlTextWriterPtr writer)
2432{
2433 int count;
2434 int sum;
2435 xmlLinkPtr lk;
2436 xmlTextWriterStackEntry *p;
2437
2438 if (writer == NULL)
2439 return -1;
2440
2441 lk = xmlListFront(writer->nodes);
2442 if (lk == 0)
2443 return -1;
2444
2445 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2446 if (p == 0)
2447 return -1;
2448
2449 sum = 0;
2450 switch (p->state) {
2451 case XML_TEXTWRITER_CDATA:
2452 count = xmlOutputBufferWriteString(writer->out, "]]>");
2453 if (count < 0)
2454 return -1;
2455 sum += count;
2456 break;
2457 default:
2458 return -1;
2459 }
2460
2461 xmlListPopFront(writer->nodes);
2462 return sum;
2463}
2464
2465/**
2466 * xmlTextWriterWriteFormatCDATA:
2467 * @writer: the xmlTextWriterPtr
2468 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002469 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002470 *
2471 * Write a formatted xml CDATA.
2472 *
2473 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2474 */
2475int
2476xmlTextWriterWriteFormatCDATA(xmlTextWriterPtr writer, const char *format,
2477 ...)
2478{
2479 int rc;
2480 va_list ap;
2481
2482 va_start(ap, format);
2483
2484 rc = xmlTextWriterWriteVFormatCDATA(writer, format, ap);
2485
2486 va_end(ap);
2487 return rc;
2488}
2489
2490/**
2491 * xmlTextWriterWriteVFormatCDATA:
2492 * @writer: the xmlTextWriterPtr
2493 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002494 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00002495 *
2496 * Write a formatted xml CDATA.
2497 *
2498 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2499 */
2500int
2501xmlTextWriterWriteVFormatCDATA(xmlTextWriterPtr writer, const char *format,
2502 va_list argptr)
2503{
2504 int rc;
2505 xmlChar *buf;
2506
2507 if (writer == NULL)
2508 return -1;
2509
2510 buf = xmlTextWriterVSprintf(format, argptr);
2511 if (buf == 0)
2512 return 0;
2513
2514 rc = xmlTextWriterWriteCDATA(writer, buf);
2515
2516 xmlFree(buf);
2517 return rc;
2518}
2519
2520/**
2521 * xmlTextWriterWriteCDATA:
2522 * @writer: the xmlTextWriterPtr
2523 * @content: CDATA content
2524 *
2525 * Write an xml CDATA.
2526 *
2527 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2528 */
2529int
2530xmlTextWriterWriteCDATA(xmlTextWriterPtr writer, const xmlChar * content)
2531{
2532 int count;
2533 int sum;
2534
2535 sum = 0;
2536 count = xmlTextWriterStartCDATA(writer);
2537 if (count == -1)
2538 return -1;
2539 sum += count;
2540 if (content != 0) {
2541 count = xmlTextWriterWriteString(writer, content);
2542 if (count == -1)
2543 return -1;
2544 sum += count;
2545 }
2546 count = xmlTextWriterEndCDATA(writer);
2547 if (count == -1)
2548 return -1;
2549 sum += count;
2550
2551 return sum;
2552}
2553
2554/**
2555 * xmlTextWriterStartDTD:
2556 * @writer: the xmlTextWriterPtr
2557 * @name: the name of the DTD
2558 * @pubid: the public identifier, which is an alternative to the system identifier
2559 * @sysid: the system identifier, which is the URI of the DTD
2560 *
2561 * Start an xml DTD.
2562 *
2563 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2564 */
2565int
2566xmlTextWriterStartDTD(xmlTextWriterPtr writer,
2567 const xmlChar * name,
2568 const xmlChar * pubid, const xmlChar * sysid)
2569{
2570 int count;
2571 int sum;
2572 xmlLinkPtr lk;
2573 xmlTextWriterStackEntry *p;
2574
2575 if (writer == NULL || name == NULL || *name == '\0')
2576 return -1;
2577
2578 sum = 0;
2579 lk = xmlListFront(writer->nodes);
2580 if (lk != 0) {
2581 xmlGenericError(xmlGenericErrorContext,
2582 "xmlTextWriterStartDTD : DTD allowed only in prolog!\n");
2583 return -1;
2584 }
2585
2586 p = (xmlTextWriterStackEntry *)
2587 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2588 if (p == 0) {
2589 xmlGenericError(xmlGenericErrorContext,
2590 "xmlTextWriterStartDTD : out of memory!\n");
2591 return -1;
2592 }
2593
2594 p->name = xmlStrdup(name);
2595 if (p->name == 0) {
2596 xmlGenericError(xmlGenericErrorContext,
2597 "xmlTextWriterStartDTD : out of memory!\n");
2598 xmlFree(p);
2599 return -1;
2600 }
2601 p->state = XML_TEXTWRITER_DTD;
2602
2603 xmlListPushFront(writer->nodes, p);
2604
2605 count = xmlOutputBufferWriteString(writer->out, "<!DOCTYPE ");
2606 if (count < 0)
2607 return -1;
2608 sum += count;
2609 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
2610 if (count < 0)
2611 return -1;
2612 sum += count;
2613
2614 if (pubid != 0) {
2615 if (sysid == 0) {
2616 xmlGenericError(xmlGenericErrorContext,
2617 "xmlTextWriterStartDTD : system identifier needed!\n");
2618 return -1;
2619 }
2620
2621 count = xmlOutputBufferWriteString(writer->out, " PUBLIC \"");
2622 if (count < 0)
2623 return -1;
2624 sum += count;
2625
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002626 count =
2627 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002628 if (count < 0)
2629 return -1;
2630 sum += count;
2631
2632 count = xmlOutputBufferWriteString(writer->out, "\"");
2633 if (count < 0)
2634 return -1;
2635 sum += count;
2636 }
2637
2638 if (sysid != 0) {
2639 if (pubid == 0) {
2640 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
2641 if (count < 0)
2642 return -1;
2643 sum += count;
2644 }
2645
2646 count = xmlOutputBufferWriteString(writer->out, " \"");
2647 if (count < 0)
2648 return -1;
2649 sum += count;
2650
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002651 count =
2652 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002653 if (count < 0)
2654 return -1;
2655 sum += count;
2656
2657 count = xmlOutputBufferWriteString(writer->out, "\"");
2658 if (count < 0)
2659 return -1;
2660 sum += count;
2661 }
2662
2663 return sum;
2664}
2665
2666/**
2667 * xmlTextWriterEndDTD:
2668 * @writer: the xmlTextWriterPtr
2669 *
2670 * End an xml DTD.
2671 *
2672 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2673 */
2674int
2675xmlTextWriterEndDTD(xmlTextWriterPtr writer)
2676{
2677 int count;
2678 int sum;
2679 xmlLinkPtr lk;
2680 xmlTextWriterStackEntry *p;
2681
2682 if (writer == NULL)
2683 return -1;
2684
2685 sum = 0;
2686 lk = xmlListFront(writer->nodes);
2687 if (lk == 0)
2688 return -1;
2689
2690 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2691 if (p == 0)
2692 return -1;
2693
2694 switch (p->state) {
2695 case XML_TEXTWRITER_DTD_TEXT:
2696 count = xmlOutputBufferWriteString(writer->out, "]");
2697 if (count < 0)
2698 return -1;
2699 sum += count;
2700 /* fallthrough */
2701 case XML_TEXTWRITER_DTD:
2702 case XML_TEXTWRITER_DTD_ELEM:
2703 case XML_TEXTWRITER_DTD_ATTL:
2704 count = xmlOutputBufferWriteString(writer->out, ">");
2705 if (count < 0)
2706 return -1;
2707 sum += count;
2708 break;
2709 default:
2710 return -1;
2711 }
2712
2713 xmlListPopFront(writer->nodes);
2714 return sum;
2715}
2716
2717/**
2718 * xmlTextWriterWriteFormatDTD:
2719 * @writer: the xmlTextWriterPtr
2720 * @name: the name of the DTD
2721 * @pubid: the public identifier, which is an alternative to the system identifier
2722 * @sysid: the system identifier, which is the URI of the DTD
2723 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002724 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002725 *
2726 * Write a DTD with a formatted markup declarations part.
2727 *
2728 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2729 */
2730int
2731xmlTextWriterWriteFormatDTD(xmlTextWriterPtr writer,
2732 const xmlChar * name,
2733 const xmlChar * pubid,
2734 const xmlChar * sysid, const char *format, ...)
2735{
2736 int rc;
2737 va_list ap;
2738
2739 va_start(ap, format);
2740
2741 rc = xmlTextWriterWriteVFormatDTD(writer, name, pubid, sysid, format,
2742 ap);
2743
2744 va_end(ap);
2745 return rc;
2746}
2747
2748/**
2749 * xmlTextWriterWriteVFormatDTD:
2750 * @writer: the xmlTextWriterPtr
2751 * @name: the name of the DTD
2752 * @pubid: the public identifier, which is an alternative to the system identifier
2753 * @sysid: the system identifier, which is the URI of the DTD
2754 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002755 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00002756 *
2757 * Write a DTD with a formatted markup declarations part.
2758 *
2759 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2760 */
2761int
2762xmlTextWriterWriteVFormatDTD(xmlTextWriterPtr writer,
2763 const xmlChar * name,
2764 const xmlChar * pubid,
2765 const xmlChar * sysid,
2766 const char *format, va_list argptr)
2767{
2768 int rc;
2769 xmlChar *buf;
2770
2771 if (writer == NULL)
2772 return -1;
2773
2774 buf = xmlTextWriterVSprintf(format, argptr);
2775 if (buf == 0)
2776 return 0;
2777
2778 rc = xmlTextWriterWriteDTD(writer, name, pubid, sysid, buf);
2779
2780 xmlFree(buf);
2781 return rc;
2782}
2783
2784/**
2785 * xmlTextWriterWriteDTD:
2786 * @writer: the xmlTextWriterPtr
2787 * @name: the name of the DTD
2788 * @pubid: the public identifier, which is an alternative to the system identifier
2789 * @sysid: the system identifier, which is the URI of the DTD
William M. Brackb1d53162003-11-18 06:54:40 +00002790 * @subset: string content of the DTD
Daniel Veillard1d211e22003-10-20 22:32:39 +00002791 *
2792 * Write a DTD.
2793 *
2794 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2795 */
2796int
2797xmlTextWriterWriteDTD(xmlTextWriterPtr writer,
2798 const xmlChar * name,
2799 const xmlChar * pubid,
2800 const xmlChar * sysid, const xmlChar * subset)
2801{
2802 int count;
2803 int sum;
2804
2805 sum = 0;
2806 count = xmlTextWriterStartDTD(writer, name, pubid, sysid);
2807 if (count == -1)
2808 return -1;
2809 sum += count;
2810 if (subset != 0) {
2811 count = xmlTextWriterWriteString(writer, subset);
2812 if (count == -1)
2813 return -1;
2814 sum += count;
2815 }
2816 count = xmlTextWriterEndDTD(writer);
2817 if (count == -1)
2818 return -1;
2819 sum += count;
2820
2821 return sum;
2822}
2823
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002824/**
2825 * xmlTextWriterStartDTDElement:
2826 * @writer: the xmlTextWriterPtr
2827 * @name: the name of the DTD element
2828 *
2829 * Start an xml DTD element.
2830 *
2831 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2832 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00002833int
2834xmlTextWriterStartDTDElement(xmlTextWriterPtr writer, const xmlChar * name)
2835{
2836 int count;
2837 int sum;
2838 xmlLinkPtr lk;
2839 xmlTextWriterStackEntry *p;
2840
2841 if (writer == NULL || name == NULL || *name == '\0')
2842 return -1;
2843
2844 sum = 0;
2845 lk = xmlListFront(writer->nodes);
2846 if (lk == 0) {
2847 return -1;
2848 }
2849
2850 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2851 if (p == 0)
2852 return -1;
2853
2854 switch (p->state) {
2855 case XML_TEXTWRITER_DTD:
2856 count = xmlOutputBufferWriteString(writer->out, " [");
2857 if (count < 0)
2858 return -1;
2859 sum += count;
2860 p->state = XML_TEXTWRITER_DTD_TEXT;
2861 /* fallthrough */
2862 case XML_TEXTWRITER_DTD_TEXT:
2863 break;
2864 case XML_TEXTWRITER_DTD_ELEM:
2865 count = xmlTextWriterEndDTDElement(writer);
2866 if (count < 0)
2867 return -1;
2868 sum += count;
2869 break;
2870 default:
2871 return -1;
2872 }
2873
2874 p = (xmlTextWriterStackEntry *)
2875 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2876 if (p == 0) {
2877 xmlGenericError(xmlGenericErrorContext,
2878 "xmlTextWriterStartDTDElement : out of memory!\n");
2879 return -1;
2880 }
2881
2882 p->name = xmlStrdup(name);
2883 if (p->name == 0) {
2884 xmlGenericError(xmlGenericErrorContext,
2885 "xmlTextWriterStartDTDElement : out of memory!\n");
2886 xmlFree(p);
2887 return -1;
2888 }
2889 p->state = XML_TEXTWRITER_DTD_ELEM;
2890
2891 xmlListPushFront(writer->nodes, p);
2892
2893 count = xmlOutputBufferWriteString(writer->out, "<!ELEMENT ");
2894 if (count < 0)
2895 return -1;
2896 sum += count;
2897 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
2898 if (count < 0)
2899 return -1;
2900 sum += count;
2901
2902 return sum;
2903}
2904
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002905/**
2906 * xmlTextWriterWriteFormatDTDElement:
2907 * @writer: the xmlTextWriterPtr
2908 * @name: the name of the DTD element
2909 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002910 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002911 *
2912 * Write a formatted DTD element.
2913 *
2914 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2915 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00002916int
2917xmlTextWriterWriteFormatDTDElement(xmlTextWriterPtr writer,
2918 const xmlChar * name,
2919 const char *format, ...)
2920{
2921 int rc;
2922 va_list ap;
2923
2924 va_start(ap, format);
2925
2926 rc = xmlTextWriterWriteVFormatDTDElement(writer, name, format, ap);
2927
2928 va_end(ap);
2929 return rc;
2930}
2931
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002932/**
2933 * xmlTextWriterWriteVFormatDTDElement:
2934 * @writer: the xmlTextWriterPtr
2935 * @name: the name of the DTD element
2936 * @format: format string (see printf)
2937 * @argptr: pointer to the first member of the variable argument list.
2938 *
2939 * Write a formatted DTD element.
2940 *
2941 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2942 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00002943int
2944xmlTextWriterWriteVFormatDTDElement(xmlTextWriterPtr writer,
2945 const xmlChar * name,
2946 const char *format, va_list argptr)
2947{
2948 int rc;
2949 xmlChar *buf;
2950
2951 if (writer == NULL)
2952 return -1;
2953
2954 buf = xmlTextWriterVSprintf(format, argptr);
2955 if (buf == 0)
2956 return 0;
2957
2958 rc = xmlTextWriterWriteDTDElement(writer, name, buf);
2959
2960 xmlFree(buf);
2961 return rc;
2962}
2963
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002964/**
2965 * xmlTextWriterWriteDTDElement:
2966 * @writer: the xmlTextWriterPtr
2967 * @name: the name of the DTD element
2968 * @content: content of the element
2969 *
2970 * Write a DTD element.
2971 *
2972 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2973 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00002974int
2975xmlTextWriterWriteDTDElement(xmlTextWriterPtr writer,
2976 const xmlChar * name, const xmlChar * content)
2977{
2978 int count;
2979 int sum;
2980
2981 if (content == NULL)
2982 return -1;
2983
2984 sum = 0;
2985 count = xmlTextWriterStartDTDElement(writer, name);
2986 if (count == -1)
2987 return -1;
2988 sum += count;
2989
2990 count = xmlTextWriterWriteString(writer, BAD_CAST " ");
2991 if (count == -1)
2992 return -1;
2993 sum += count;
2994 count = xmlTextWriterWriteString(writer, content);
2995 if (count == -1)
2996 return -1;
2997 sum += count;
2998
2999 count = xmlTextWriterEndDTDElement(writer);
3000 if (count == -1)
3001 return -1;
3002 sum += count;
3003
3004 return sum;
3005}
3006
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003007/**
3008 * xmlTextWriterStartDTDAttlist:
3009 * @writer: the xmlTextWriterPtr
3010 * @name: the name of the DTD ATTLIST
3011 *
3012 * Start an xml DTD ATTLIST.
3013 *
3014 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3015 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003016int
3017xmlTextWriterStartDTDAttlist(xmlTextWriterPtr writer, const xmlChar * name)
3018{
3019 int count;
3020 int sum;
3021 xmlLinkPtr lk;
3022 xmlTextWriterStackEntry *p;
3023
3024 if (writer == NULL || name == NULL || *name == '\0')
3025 return -1;
3026
3027 sum = 0;
3028 lk = xmlListFront(writer->nodes);
3029 if (lk == 0) {
3030 return -1;
3031 }
3032
3033 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3034 if (p == 0)
3035 return -1;
3036
3037 switch (p->state) {
3038 case XML_TEXTWRITER_DTD:
3039 count = xmlOutputBufferWriteString(writer->out, " [");
3040 if (count < 0)
3041 return -1;
3042 sum += count;
3043 p->state = XML_TEXTWRITER_DTD_TEXT;
3044 /* fallthrough */
3045 case XML_TEXTWRITER_DTD_TEXT:
3046 break;
3047 case XML_TEXTWRITER_DTD_ELEM:
3048 case XML_TEXTWRITER_DTD_ATTL:
3049 case XML_TEXTWRITER_DTD_ENTY:
3050 count = xmlTextWriterEndDTD(writer);
3051 if (count < 0)
3052 return -1;
3053 sum += count;
3054 break;
3055 default:
3056 return -1;
3057 }
3058
3059 p = (xmlTextWriterStackEntry *)
3060 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3061 if (p == 0) {
3062 xmlGenericError(xmlGenericErrorContext,
3063 "xmlTextWriterStartDTDAttlist : out of memory!\n");
3064 return -1;
3065 }
3066
3067 p->name = xmlStrdup(name);
3068 if (p->name == 0) {
3069 xmlGenericError(xmlGenericErrorContext,
3070 "xmlTextWriterStartDTDAttlist : out of memory!\n");
3071 xmlFree(p);
3072 return -1;
3073 }
3074 p->state = XML_TEXTWRITER_DTD_ATTL;
3075
3076 xmlListPushFront(writer->nodes, p);
3077
3078 count = xmlOutputBufferWriteString(writer->out, "<!ATTLIST ");
3079 if (count < 0)
3080 return -1;
3081 sum += count;
3082 count = xmlOutputBufferWriteString(writer->out, (const char *)name);
3083 if (count < 0)
3084 return -1;
3085 sum += count;
3086
3087 return sum;
3088}
3089
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003090/**
3091 * xmlTextWriterWriteFormatDTDAttlist:
3092 * @writer: the xmlTextWriterPtr
3093 * @name: the name of the DTD ATTLIST
3094 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003095 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003096 *
3097 * Write a formatted DTD ATTLIST.
3098 *
3099 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3100 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003101int
3102xmlTextWriterWriteFormatDTDAttlist(xmlTextWriterPtr writer,
3103 const xmlChar * name,
3104 const char *format, ...)
3105{
3106 int rc;
3107 va_list ap;
3108
3109 va_start(ap, format);
3110
3111 rc = xmlTextWriterWriteVFormatDTDAttlist(writer, name, format, ap);
3112
3113 va_end(ap);
3114 return rc;
3115}
3116
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003117/**
3118 * xmlTextWriterWriteVFormatDTDAttlist:
3119 * @writer: the xmlTextWriterPtr
3120 * @name: the name of the DTD ATTLIST
3121 * @format: format string (see printf)
3122 * @argptr: pointer to the first member of the variable argument list.
3123 *
3124 * Write a formatted DTD ATTLIST.
3125 *
3126 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3127 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003128int
3129xmlTextWriterWriteVFormatDTDAttlist(xmlTextWriterPtr writer,
3130 const xmlChar * name,
3131 const char *format, va_list argptr)
3132{
3133 int rc;
3134 xmlChar *buf;
3135
3136 if (writer == NULL)
3137 return -1;
3138
3139 buf = xmlTextWriterVSprintf(format, argptr);
3140 if (buf == 0)
3141 return 0;
3142
3143 rc = xmlTextWriterWriteDTDAttlist(writer, name, buf);
3144
3145 xmlFree(buf);
3146 return rc;
3147}
3148
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003149/**
3150 * xmlTextWriterWriteDTDAttlist:
3151 * @writer: the xmlTextWriterPtr
3152 * @name: the name of the DTD ATTLIST
3153 * @content: content of the ATTLIST
3154 *
3155 * Write a DTD ATTLIST.
3156 *
3157 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3158 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003159int
3160xmlTextWriterWriteDTDAttlist(xmlTextWriterPtr writer,
3161 const xmlChar * name, const xmlChar * content)
3162{
3163 int count;
3164 int sum;
3165
3166 if (content == NULL)
3167 return -1;
3168
3169 sum = 0;
3170 count = xmlTextWriterStartDTDAttlist(writer, name);
3171 if (count == -1)
3172 return -1;
3173 sum += count;
3174
3175 count = xmlTextWriterWriteString(writer, BAD_CAST " ");
3176 if (count == -1)
3177 return -1;
3178 sum += count;
3179 count = xmlTextWriterWriteString(writer, content);
3180 if (count == -1)
3181 return -1;
3182 sum += count;
3183
3184 count = xmlTextWriterEndDTDAttlist(writer);
3185 if (count == -1)
3186 return -1;
3187 sum += count;
3188
3189 return sum;
3190}
3191
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003192/**
3193 * xmlTextWriterStartDTDEntity:
3194 * @writer: the xmlTextWriterPtr
3195 * @pe: TRUE if this is a parameter entity, FALSE if not
3196 * @name: the name of the DTD ATTLIST
3197 *
3198 * Start an xml DTD ATTLIST.
3199 *
3200 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3201 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003202int
3203xmlTextWriterStartDTDEntity(xmlTextWriterPtr writer,
3204 int pe, const xmlChar * name)
3205{
3206 int count;
3207 int sum;
3208 xmlLinkPtr lk;
3209 xmlTextWriterStackEntry *p;
3210
3211 if (writer == NULL || name == NULL || *name == '\0')
3212 return -1;
3213
3214 sum = 0;
3215 lk = xmlListFront(writer->nodes);
3216 if (lk == 0) {
3217 return -1;
3218 }
3219
3220 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3221 if (p == 0)
3222 return -1;
3223
3224 switch (p->state) {
3225 case XML_TEXTWRITER_DTD:
3226 count = xmlOutputBufferWriteString(writer->out, " [");
3227 if (count < 0)
3228 return -1;
3229 sum += count;
3230 p->state = XML_TEXTWRITER_DTD_TEXT;
3231 /* fallthrough */
3232 case XML_TEXTWRITER_DTD_TEXT:
3233 break;
3234 case XML_TEXTWRITER_DTD_ELEM:
3235 case XML_TEXTWRITER_DTD_ATTL:
3236 case XML_TEXTWRITER_DTD_ENTY:
3237 count = xmlTextWriterEndDTD(writer);
3238 if (count < 0)
3239 return -1;
3240 sum += count;
3241 break;
3242 default:
3243 return -1;
3244 }
3245
3246 p = (xmlTextWriterStackEntry *)
3247 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3248 if (p == 0) {
3249 xmlGenericError(xmlGenericErrorContext,
3250 "xmlTextWriterStartDTDElement : out of memory!\n");
3251 return -1;
3252 }
3253
3254 p->name = xmlStrdup(name);
3255 if (p->name == 0) {
3256 xmlGenericError(xmlGenericErrorContext,
3257 "xmlTextWriterStartDTDElement : out of memory!\n");
3258 xmlFree(p);
3259 return -1;
3260 }
3261 p->state = XML_TEXTWRITER_DTD_ENTY;
3262
3263 xmlListPushFront(writer->nodes, p);
3264
3265 count = xmlOutputBufferWriteString(writer->out, "<!ENTITY ");
3266 if (count < 0)
3267 return -1;
3268 sum += count;
3269
3270 if (pe != 0) {
3271 count = xmlOutputBufferWriteString(writer->out, " % ");
3272 if (count < 0)
3273 return -1;
3274 sum += count;
3275 }
3276
3277 count = xmlOutputBufferWriteString(writer->out, (const char *)name);
3278 if (count < 0)
3279 return -1;
3280 sum += count;
3281
3282 return sum;
3283}
3284
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003285/**
3286 * xmlTextWriterWriteFormatDTDInternalEntity:
3287 * @writer: the xmlTextWriterPtr
3288 * @pe: TRUE if this is a parameter entity, FALSE if not
3289 * @name: the name of the DTD entity
3290 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003291 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003292 *
3293 * Write a formatted DTD internal entity.
3294 *
3295 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3296 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003297int
3298xmlTextWriterWriteFormatDTDInternalEntity(xmlTextWriterPtr writer,
3299 int pe,
3300 const xmlChar * name,
3301 const char *format, ...)
3302{
3303 int rc;
3304 va_list ap;
3305
3306 va_start(ap, format);
3307
3308 rc = xmlTextWriterWriteVFormatDTDInternalEntity(writer, pe, name,
3309 format, ap);
3310
3311 va_end(ap);
3312 return rc;
3313}
3314
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003315/**
3316 * xmlTextWriterWriteVFormatDTDInternalEntity:
3317 * @writer: the xmlTextWriterPtr
3318 * @pe: TRUE if this is a parameter entity, FALSE if not
3319 * @name: the name of the DTD entity
3320 * @format: format string (see printf)
3321 * @argptr: pointer to the first member of the variable argument list.
3322 *
3323 * Write a formatted DTD internal entity.
3324 *
3325 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3326 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003327int
3328xmlTextWriterWriteVFormatDTDInternalEntity(xmlTextWriterPtr writer,
3329 int pe,
3330 const xmlChar * name,
3331 const char *format,
3332 va_list argptr)
3333{
3334 int rc;
3335 xmlChar *buf;
3336
3337 if (writer == NULL)
3338 return -1;
3339
3340 buf = xmlTextWriterVSprintf(format, argptr);
3341 if (buf == 0)
3342 return 0;
3343
3344 rc = xmlTextWriterWriteDTDInternalEntity(writer, pe, name, buf);
3345
3346 xmlFree(buf);
3347 return rc;
3348}
3349
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003350/**
3351 * xmlTextWriterWriteDTDEntity:
3352 * @writer: the xmlTextWriterPtr
3353 * @pe: TRUE if this is a parameter entity, FALSE if not
3354 * @name: the name of the DTD entity
3355 * @pubid: the public identifier, which is an alternative to the system identifier
3356 * @sysid: the system identifier, which is the URI of the DTD
3357 * @ndataid: the xml notation name.
3358 * @content: content of the entity
3359 *
3360 * Write a DTD entity.
3361 *
3362 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3363 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003364int
3365xmlTextWriterWriteDTDEntity(xmlTextWriterPtr writer,
3366 int pe,
3367 const xmlChar * name,
3368 const xmlChar * pubid,
3369 const xmlChar * sysid,
3370 const xmlChar * ndataid,
3371 const xmlChar * content)
3372{
3373 if (((content == NULL) && (pubid == NULL) && (sysid == NULL))
3374 || ((content != NULL) && ((pubid != NULL) || (sysid != NULL))))
3375 return -1;
3376 if ((pe != 0) && (ndataid != NULL))
3377 return -1;
3378
3379 if (content != 0)
3380 return xmlTextWriterWriteDTDInternalEntity(writer, pe, name,
3381 content);
3382
3383 return xmlTextWriterWriteDTDExternalEntity(writer, pe, name, pubid,
3384 sysid, ndataid);
3385}
3386
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003387/**
3388 * xmlTextWriterWriteDTDInternalEntity:
3389 * @writer: the xmlTextWriterPtr
3390 * @pe: TRUE if this is a parameter entity, FALSE if not
3391 * @name: the name of the DTD entity
3392 * @content: content of the entity
3393 *
3394 * Write a DTD internal entity.
3395 *
3396 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3397 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003398int
3399xmlTextWriterWriteDTDInternalEntity(xmlTextWriterPtr writer,
3400 int pe,
3401 const xmlChar * name,
3402 const xmlChar * content)
3403{
3404 int count;
3405 int sum;
3406
3407 if ((name == NULL) || (*name == '\0') || (content == NULL))
3408 return -1;
3409
3410 sum = 0;
3411 count = xmlTextWriterStartDTDEntity(writer, pe, name);
3412 if (count == -1)
3413 return -1;
3414 sum += count;
3415
3416 count = xmlTextWriterWriteString(writer, BAD_CAST " ");
3417 if (count == -1)
3418 return -1;
3419 sum += count;
3420 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3421 if (count < 0)
3422 return -1;
3423 sum += count;
3424 count = xmlTextWriterWriteString(writer, content);
3425 if (count == -1)
3426 return -1;
3427 sum += count;
3428 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3429 if (count < 0)
3430 return -1;
3431 sum += count;
3432
3433 count = xmlTextWriterEndDTDEntity(writer);
3434 if (count == -1)
3435 return -1;
3436 sum += count;
3437
3438 return sum;
3439}
3440
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003441/**
3442 * xmlTextWriterWriteDTDExternalEntity:
3443 * @writer: the xmlTextWriterPtr
3444 * @pe: TRUE if this is a parameter entity, FALSE if not
3445 * @name: the name of the DTD entity
3446 * @pubid: the public identifier, which is an alternative to the system identifier
3447 * @sysid: the system identifier, which is the URI of the DTD
3448 * @ndataid: the xml notation name.
3449 *
3450 * Write a DTD internal entity.
3451 *
3452 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3453 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003454int
3455xmlTextWriterWriteDTDExternalEntity(xmlTextWriterPtr writer,
3456 int pe,
3457 const xmlChar * name,
3458 const xmlChar * pubid,
3459 const xmlChar * sysid,
3460 const xmlChar * ndataid)
3461{
3462 int count;
3463 int sum;
3464
3465 if ((name == NULL) || (*name == '\0')
3466 || ((pubid == NULL) && (sysid == NULL)))
3467 return -1;
3468 if ((pe != 0) && (ndataid != NULL))
3469 return -1;
3470
3471 sum = 0;
3472 count = xmlTextWriterStartDTDEntity(writer, pe, name);
3473 if (count == -1)
3474 return -1;
3475 sum += count;
3476
3477 if (pubid != 0) {
3478 if (sysid == 0) {
3479 xmlGenericError(xmlGenericErrorContext,
3480 "xmlTextWriterWriteDTDEntity : system identifier needed!\n");
3481 return -1;
3482 }
3483
3484 count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
3485 if (count < 0)
3486 return -1;
3487 sum += count;
3488
3489 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3490 if (count < 0)
3491 return -1;
3492 sum += count;
3493
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003494 count =
3495 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003496 if (count < 0)
3497 return -1;
3498 sum += count;
3499
3500 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3501 if (count < 0)
3502 return -1;
3503 sum += count;
3504 }
3505
3506 if (sysid != 0) {
3507 if (pubid == 0) {
3508 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
3509 if (count < 0)
3510 return -1;
3511 sum += count;
3512 }
3513
3514 count = xmlOutputBufferWriteString(writer->out, " ");
3515 if (count < 0)
3516 return -1;
3517 sum += count;
3518
3519 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3520 if (count < 0)
3521 return -1;
3522 sum += count;
3523
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003524 count =
3525 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003526 if (count < 0)
3527 return -1;
3528 sum += count;
3529
3530 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3531 if (count < 0)
3532 return -1;
3533 sum += count;
3534 }
3535
3536 if (ndataid != NULL) {
3537 count = xmlOutputBufferWriteString(writer->out, " NDATA ");
3538 if (count < 0)
3539 return -1;
3540 sum += count;
3541
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003542 count =
3543 xmlOutputBufferWriteString(writer->out,
3544 (const char *) ndataid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003545 if (count < 0)
3546 return -1;
3547 sum += count;
3548 }
3549
3550 count = xmlTextWriterEndDTDEntity(writer);
3551 if (count == -1)
3552 return -1;
3553 sum += count;
3554
3555 return sum;
3556}
3557
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003558/**
3559 * xmlTextWriterWriteDTDNotation:
3560 * @writer: the xmlTextWriterPtr
3561 * @name: the name of the xml notation
3562 * @pubid: the public identifier, which is an alternative to the system identifier
3563 * @sysid: the system identifier, which is the URI of the DTD
3564 *
3565 * Write a DTD entity.
3566 *
3567 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3568 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003569int
3570xmlTextWriterWriteDTDNotation(xmlTextWriterPtr writer,
3571 const xmlChar * name,
3572 const xmlChar * pubid, const xmlChar * sysid)
3573{
3574 int count;
3575 int sum;
3576 xmlLinkPtr lk;
3577 xmlTextWriterStackEntry *p;
3578
3579 if (writer == NULL || name == NULL || *name == '\0')
3580 return -1;
3581
3582 sum = 0;
3583 lk = xmlListFront(writer->nodes);
3584 if (lk == 0) {
3585 return -1;
3586 }
3587
3588 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3589 if (p == 0)
3590 return -1;
3591
3592 switch (p->state) {
3593 case XML_TEXTWRITER_DTD:
3594 count = xmlOutputBufferWriteString(writer->out, " [");
3595 if (count < 0)
3596 return -1;
3597 sum += count;
3598 p->state = XML_TEXTWRITER_DTD_TEXT;
3599 /* fallthrough */
3600 case XML_TEXTWRITER_DTD_TEXT:
3601 break;
3602 case XML_TEXTWRITER_DTD_ELEM:
3603 case XML_TEXTWRITER_DTD_ATTL:
3604 case XML_TEXTWRITER_DTD_ENTY:
3605 count = xmlTextWriterEndDTD(writer);
3606 if (count < 0)
3607 return -1;
3608 sum += count;
3609 break;
3610 default:
3611 return -1;
3612 }
3613
3614 count = xmlOutputBufferWriteString(writer->out, "<!NOTATION ");
3615 if (count < 0)
3616 return -1;
3617 sum += count;
3618 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
3619 if (count < 0)
3620 return -1;
3621 sum += count;
3622
3623 if (pubid != 0) {
3624 count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
3625 if (count < 0)
3626 return -1;
3627 sum += count;
3628 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3629 if (count < 0)
3630 return -1;
3631 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003632 count =
3633 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003634 if (count < 0)
3635 return -1;
3636 sum += count;
3637 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3638 if (count < 0)
3639 return -1;
3640 sum += count;
3641 }
3642
3643 if (sysid != 0) {
3644 if (pubid == 0) {
3645 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
3646 if (count < 0)
3647 return -1;
3648 sum += count;
3649 }
3650 count = xmlOutputBufferWriteString(writer->out, " ");
3651 if (count < 0)
3652 return -1;
3653 sum += count;
3654 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3655 if (count < 0)
3656 return -1;
3657 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003658 count =
3659 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003660 if (count < 0)
3661 return -1;
3662 sum += count;
3663 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3664 if (count < 0)
3665 return -1;
3666 sum += count;
3667 }
3668
3669 count = xmlOutputBufferWriteString(writer->out, ">");
3670 if (count < 0)
3671 return -1;
3672 sum += count;
3673
3674 return sum;
3675}
3676
3677/**
3678 * xmlTextWriterFlush:
3679 * @writer: the xmlTextWriterPtr
3680 *
3681 * Flush the output buffer.
3682 *
3683 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3684 */
3685int
3686xmlTextWriterFlush(xmlTextWriterPtr writer)
3687{
3688 int count;
3689
3690 if (writer == NULL)
3691 return -1;
3692
3693 if (writer->out == NULL)
3694 count = 0;
3695 else
3696 count = xmlOutputBufferFlush(writer->out);
3697
3698 return count;
3699}
3700
3701/**
3702 * misc
3703 */
3704
3705/**
3706 * xmlFreeTextWriterStackEntry:
3707 * @lk: the xmlLinkPtr
3708 *
3709 * Free callback for the xmlList.
3710 */
3711static void
3712xmlFreeTextWriterStackEntry(xmlLinkPtr lk)
3713{
3714 xmlTextWriterStackEntry *p;
3715
3716 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3717 if (p == 0)
3718 return;
3719
3720 if (p->name != 0)
3721 xmlFree(p->name);
3722 xmlFree(p);
3723}
3724
3725/**
3726 * xmlCmpTextWriterStackEntry:
3727 * @data0: the first data
3728 * @data1: the second data
3729 *
3730 * Compare callback for the xmlList.
3731 *
3732 * Returns -1, 0, 1
3733 */
3734static int
3735xmlCmpTextWriterStackEntry(const void *data0, const void *data1)
3736{
3737 xmlTextWriterStackEntry *p0;
3738 xmlTextWriterStackEntry *p1;
3739
3740 if (data0 == data1)
3741 return 0;
3742
3743 if (data0 == 0)
3744 return -1;
3745
3746 if (data1 == 0)
3747 return 1;
3748
3749 p0 = (xmlTextWriterStackEntry *) data0;
3750 p1 = (xmlTextWriterStackEntry *) data1;
3751
3752 return xmlStrcmp(p0->name, p1->name);
3753}
3754
3755/**
3756 * misc
3757 */
3758
3759/**
3760 * xmlFreeTextWriterNsStackEntry:
3761 * @lk: the xmlLinkPtr
3762 *
3763 * Free callback for the xmlList.
3764 */
3765static void
3766xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk)
3767{
3768 xmlTextWriterNsStackEntry *p;
3769
3770 p = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
3771 if (p == 0)
3772 return;
3773
3774 if (p->prefix != 0)
3775 xmlFree(p->prefix);
3776 if (p->uri != 0)
3777 xmlFree(p->uri);
3778
3779 xmlFree(p);
3780}
3781
3782/**
3783 * xmlCmpTextWriterNsStackEntry:
3784 * @data0: the first data
3785 * @data1: the second data
3786 *
3787 * Compare callback for the xmlList.
3788 *
3789 * Returns -1, 0, 1
3790 */
3791static int
3792xmlCmpTextWriterNsStackEntry(const void *data0, const void *data1)
3793{
3794 xmlTextWriterNsStackEntry *p0;
3795 xmlTextWriterNsStackEntry *p1;
3796 int rc;
3797
3798 if (data0 == data1)
3799 return 0;
3800
3801 if (data0 == 0)
3802 return -1;
3803
3804 if (data1 == 0)
3805 return 1;
3806
3807 p0 = (xmlTextWriterNsStackEntry *) data0;
3808 p1 = (xmlTextWriterNsStackEntry *) data1;
3809
3810 rc = xmlStrcmp(p0->prefix, p1->prefix);
3811
3812 if (rc == 0)
3813 rc = p0->elem == p1->elem;
3814
3815 return rc;
3816}
3817
3818/**
3819 * xmlTextWriterWriteMemCallback:
3820 * @context: the xmlBufferPtr
3821 * @str: the data to write
3822 * @len: the length of the data
3823 *
3824 * Write callback for the xmlOutputBuffer with target xmlBuffer
3825 *
3826 * Returns -1, 0, 1
3827 */
3828static int
3829xmlTextWriterWriteMemCallback(void *context, const xmlChar * str, int len)
3830{
3831 xmlBufferPtr buf = (xmlBufferPtr) context;
3832
3833 xmlBufferAdd(buf, str, len);
3834
3835 return len;
3836}
3837
3838/**
3839 * xmlTextWriterCloseMemCallback:
3840 * @context: the xmlBufferPtr
3841 *
3842 * Close callback for the xmlOutputBuffer with target xmlBuffer
3843 *
3844 * Returns -1, 0, 1
3845 */
3846static int
3847xmlTextWriterCloseMemCallback(void *context ATTRIBUTE_UNUSED)
3848{
3849 return 0;
3850}
3851
3852/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003853 * xmlTextWriterWriteDocCallback:
3854 * @context: the xmlBufferPtr
3855 * @str: the data to write
3856 * @len: the length of the data
3857 *
3858 * Write callback for the xmlOutputBuffer with target xmlBuffer
3859 *
3860 * Returns -1, 0, 1
3861 */
3862static int
3863xmlTextWriterWriteDocCallback(void *context, const xmlChar * str, int len)
3864{
3865 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context;
3866 int rc;
3867
Daniel Veillard1d913862003-11-21 00:28:39 +00003868 if ((rc = xmlParseChunk(ctxt, (const char *) str, len, 0)) != 0) {
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003869 xmlGenericError(xmlGenericErrorContext,
3870 "xmlTextWriterWriteDocCallback : XML error %d !\n",
3871 rc);
3872 return -1;
3873 }
3874
3875 return len;
3876}
3877
3878/**
3879 * xmlTextWriterCloseDocCallback:
3880 * @context: the xmlBufferPtr
3881 *
3882 * Close callback for the xmlOutputBuffer with target xmlBuffer
3883 *
3884 * Returns -1, 0, 1
3885 */
3886static int
3887xmlTextWriterCloseDocCallback(void *context)
3888{
3889 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context;
3890 int rc;
3891
3892 if ((rc = xmlParseChunk(ctxt, NULL, 0, 1)) != 0) {
3893 xmlGenericError(xmlGenericErrorContext,
3894 "xmlTextWriterWriteDocCallback : XML error %d !\n",
3895 rc);
3896 return -1;
3897 }
3898
3899 return 0;
3900}
3901
3902/**
Daniel Veillard1d211e22003-10-20 22:32:39 +00003903 * xmlTextWriterVSprintf:
3904 * @format: see printf
3905 * @argptr: pointer to the first member of the variable argument list.
3906 *
3907 * Utility function for formatted output
3908 *
3909 * Returns a new xmlChar buffer with the data or NULL on error. This buffer must be freed.
3910 */
3911static xmlChar *
3912xmlTextWriterVSprintf(const char *format, va_list argptr)
3913{
3914 int size;
3915 int count;
3916 xmlChar *buf;
3917
3918 size = BUFSIZ;
3919 buf = (xmlChar *) xmlMalloc(size);
3920 if (buf == NULL) {
3921 xmlGenericError(xmlGenericErrorContext,
3922 "xmlTextWriterVSprintf : out of memory!\n");
3923 return NULL;
3924 }
3925
3926 while (((count = vsnprintf((char *) buf, size, format, argptr)) < 0)
3927 || (count == size - 1) || (count == size) || (count > size)) {
3928 xmlFree(buf);
3929 size += BUFSIZ;
3930 buf = (xmlChar *) xmlMalloc(size);
3931 if (buf == NULL) {
3932 xmlGenericError(xmlGenericErrorContext,
3933 "xmlTextWriterVSprintf : out of memory!\n");
3934 return NULL;
3935 }
3936 }
3937
3938 return buf;
3939}
3940
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003941/**
3942 * xmlTextWriterStartDocumentCallback:
3943 * @ctx: the user data (XML parser context)
3944 *
3945 * called at the start of document processing.
3946 */
3947static void
3948xmlTextWriterStartDocumentCallback(void *ctx)
3949{
3950 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
3951 xmlDocPtr doc;
3952
3953#ifdef DEBUG_SAX
3954 xmlGenericError(xmlGenericErrorContext, "SAX.startDocument()\n");
3955#endif
3956 if (ctxt->html) {
3957#ifdef LIBXML_HTML_ENABLED
3958 if (ctxt->myDoc == NULL)
3959 ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
3960 if (ctxt->myDoc == NULL) {
3961 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
3962 ctxt->sax->error(ctxt->userData,
3963 "SAX.startDocument(): out of memory\n");
3964 ctxt->errNo = XML_ERR_NO_MEMORY;
3965 ctxt->instate = XML_PARSER_EOF;
3966 ctxt->disableSAX = 1;
3967 return;
3968 }
3969#else
3970 xmlGenericError(xmlGenericErrorContext,
3971 "libxml2 built without HTML support\n");
3972 ctxt->errNo = XML_ERR_INTERNAL_ERROR;
3973 ctxt->instate = XML_PARSER_EOF;
3974 ctxt->disableSAX = 1;
3975 return;
3976#endif
3977 } else {
3978 doc = ctxt->myDoc;
3979 if (doc == NULL)
3980 doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
3981 if (doc != NULL) {
3982 if (doc->children == NULL) {
3983 if (ctxt->encoding != NULL)
3984 doc->encoding = xmlStrdup(ctxt->encoding);
3985 else
3986 doc->encoding = NULL;
3987 doc->standalone = ctxt->standalone;
3988 }
3989 } else {
3990 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
3991 ctxt->sax->error(ctxt->userData,
3992 "SAX.startDocument(): out of memory\n");
3993 ctxt->errNo = XML_ERR_NO_MEMORY;
3994 ctxt->instate = XML_PARSER_EOF;
3995 ctxt->disableSAX = 1;
3996 return;
3997 }
3998 }
3999 if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) &&
4000 (ctxt->input != NULL) && (ctxt->input->filename != NULL)) {
4001 ctxt->myDoc->URL =
4002 xmlCanonicPath((const xmlChar *) ctxt->input->filename);
4003 if (ctxt->myDoc->URL == NULL)
4004 ctxt->myDoc->URL =
4005 xmlStrdup((const xmlChar *) ctxt->input->filename);
4006 }
4007}
4008
Daniel Veillard2cca4462004-01-02 20:04:23 +00004009/**
4010 * xmlTextWriterSetIndent:
4011 * @writer: the xmlTextWriterPtr
4012 * @indent: do indentation?
4013 *
4014 * Set indentation output. indent = 0 do not indentation. indent > 0 do indentation.
4015 *
4016 * Returns -1 on error or 0 otherwise.
4017 */
4018int
4019xmlTextWriterSetIndent (xmlTextWriterPtr writer, int indent)
4020{
4021 if (indent < 0)
4022 return -1;
4023
4024 writer->indent = indent;
4025 writer->doindent = 1;
4026
4027 return 0;
4028}
4029
4030/**
4031 * xmlTextWriterSetIndentString:
4032 * @writer: the xmlTextWriterPtr
4033 * @str: the xmlChar string
4034 *
4035 * Set string indentation.
4036 *
4037 * Returns -1 on error or 0 otherwise.
4038 */
4039int
4040xmlTextWriterSetIndentString (xmlTextWriterPtr writer, xmlChar *str)
4041{
4042
4043 if (!str)
4044 return -1;
4045
Daniel Veillard4773df22004-01-23 13:15:13 +00004046 if (writer->ichar != NULL)
4047 xmlFree(writer->ichar);
Daniel Veillard2cca4462004-01-02 20:04:23 +00004048 writer->ichar = xmlStrdup (str);
4049
4050 if (!writer->ichar)
4051 return -1;
4052 else
4053 return 0;
4054}
4055
4056/**
4057 * xmlTextWriterWriteIndent:
4058 * @writer: the xmlTextWriterPtr
4059 *
4060 * Write indent string.
4061 *
4062 * Returns -1 on error or the number of strings written.
4063 */
4064static int
4065xmlTextWriterWriteIndent (xmlTextWriterPtr writer)
4066{
4067 int lksize;
4068 int i;
William M. Brack5d4cba42004-01-06 15:19:12 +00004069 int ret = -1; /* just in case of an empty list */
Daniel Veillard2cca4462004-01-02 20:04:23 +00004070
4071 lksize = xmlListSize (writer->nodes);
4072 for (i = 0; i < (lksize-1); i++) {
William M. Brack5d4cba42004-01-06 15:19:12 +00004073 ret = xmlOutputBufferWriteString (writer->out,
4074 (const char *)writer->ichar);
Daniel Veillard2cca4462004-01-02 20:04:23 +00004075 if (ret == -1)
4076 break;
4077 }
4078
4079 return (ret == -1)?ret:i;
4080}
4081
Daniel Veillard1d211e22003-10-20 22:32:39 +00004082#endif