blob: d4c717607fdbfee4ed0b8309e270b465e7c32ed1 [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,
Daniel Veillard500a1de2004-03-22 15:22:58 +000041 XML_TEXTWRITER_DTD_ELEM_TEXT,
Daniel Veillard1d211e22003-10-20 22:32:39 +000042 XML_TEXTWRITER_DTD_ATTL,
Daniel Veillard500a1de2004-03-22 15:22:58 +000043 XML_TEXTWRITER_DTD_ATTL_TEXT,
44 XML_TEXTWRITER_DTD_ENTY, /* entity */
45 XML_TEXTWRITER_DTD_ENTY_TEXT,
46 XML_TEXTWRITER_DTD_PENT, /* parameter entity */
William M. Brack87640d52004-04-17 14:58:15 +000047 XML_TEXTWRITER_COMMENT
Daniel Veillard1d211e22003-10-20 22:32:39 +000048} xmlTextWriterState;
49
50typedef struct _xmlTextWriterStackEntry xmlTextWriterStackEntry;
51
52struct _xmlTextWriterStackEntry {
53 xmlChar *name;
54 xmlTextWriterState state;
55};
56
57typedef struct _xmlTextWriterNsStackEntry xmlTextWriterNsStackEntry;
58struct _xmlTextWriterNsStackEntry {
59 xmlChar *prefix;
60 xmlChar *uri;
61 xmlLinkPtr elem;
62};
63
64struct _xmlTextWriter {
Daniel Veillardab69f362004-02-17 11:40:32 +000065 xmlOutputBufferPtr out; /* output buffer */
66 xmlListPtr nodes; /* element name stack */
67 xmlListPtr nsstack; /* name spaces stack */
Daniel Veillard1d211e22003-10-20 22:32:39 +000068 int level;
Daniel Veillardab69f362004-02-17 11:40:32 +000069 int indent; /* enable indent */
70 int doindent; /* internal indent flag */
71 xmlChar *ichar; /* indent character */
72 char qchar; /* character used for quoting attribute values */
Daniel Veillard20c5e782004-01-21 09:57:31 +000073 xmlParserCtxtPtr ctxt;
Daniel Veillard1d211e22003-10-20 22:32:39 +000074};
75
76static void xmlFreeTextWriterStackEntry(xmlLinkPtr lk);
77static int xmlCmpTextWriterStackEntry(const void *data0,
78 const void *data1);
79static void xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk);
80static int xmlCmpTextWriterNsStackEntry(const void *data0,
81 const void *data1);
82static int xmlTextWriterWriteMemCallback(void *context,
83 const xmlChar * str, int len);
84static int xmlTextWriterCloseMemCallback(void *context);
Daniel Veillard5841f0e2003-11-20 11:59:09 +000085static int xmlTextWriterWriteDocCallback(void *context,
86 const xmlChar * str, int len);
87static int xmlTextWriterCloseDocCallback(void *context);
88
Daniel Veillard1d211e22003-10-20 22:32:39 +000089static xmlChar *xmlTextWriterVSprintf(const char *format, va_list argptr);
90static int xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len,
91 const unsigned char *data);
Daniel Veillard5841f0e2003-11-20 11:59:09 +000092static void xmlTextWriterStartDocumentCallback(void *ctx);
Daniel Veillardab69f362004-02-17 11:40:32 +000093static int xmlTextWriterWriteIndent(xmlTextWriterPtr writer);
Daniel Veillard500a1de2004-03-22 15:22:58 +000094static int
95 xmlTextWriterHandleStateDependencies(xmlTextWriterPtr writer,
96 xmlTextWriterStackEntry * p);
Daniel Veillard1d211e22003-10-20 22:32:39 +000097
98/**
99 * xmlNewTextWriter:
100 * @out: an xmlOutputBufferPtr
101 *
102 * Create a new xmlNewTextWriter structure using an xmlOutputBufferPtr
103 *
104 * Returns the new xmlTextWriterPtr or NULL in case of error
105 */
106xmlTextWriterPtr
107xmlNewTextWriter(xmlOutputBufferPtr out)
108{
109 xmlTextWriterPtr ret;
110
111 ret = (xmlTextWriterPtr) xmlMalloc(sizeof(xmlTextWriter));
112 if (ret == NULL) {
113 xmlGenericError(xmlGenericErrorContext,
114 "xmlNewTextWriter : out of memory!\n");
115 return NULL;
116 }
117 memset(ret, 0, (size_t) sizeof(xmlTextWriter));
118
119 ret->nodes = xmlListCreate((xmlListDeallocator)
120 xmlFreeTextWriterStackEntry,
121 (xmlListDataCompare)
122 xmlCmpTextWriterStackEntry);
123 if (ret->nodes == NULL) {
124 xmlGenericError(xmlGenericErrorContext,
125 "xmlNewTextWriter : out of memory!\n");
126 xmlFree(ret);
127 return NULL;
128 }
129
130 ret->nsstack = xmlListCreate((xmlListDeallocator)
131 xmlFreeTextWriterNsStackEntry,
132 (xmlListDataCompare)
133 xmlCmpTextWriterNsStackEntry);
134 if (ret->nsstack == NULL) {
135 xmlGenericError(xmlGenericErrorContext,
136 "xmlNewTextWriter : out of memory!\n");
Daniel Veillard500a1de2004-03-22 15:22:58 +0000137 xmlListDelete(ret->nodes);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000138 xmlFree(ret);
139 return NULL;
140 }
141
142 ret->out = out;
Daniel Veillardab69f362004-02-17 11:40:32 +0000143 ret->ichar = xmlStrdup(BAD_CAST " ");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000144 ret->qchar = '"';
145
Daniel Veillard500a1de2004-03-22 15:22:58 +0000146 if (!ret->ichar) {
147 xmlListDelete(ret->nodes);
148 xmlListDelete(ret->nsstack);
149 xmlFree(ret);
150 xmlGenericError(xmlGenericErrorContext,
151 "xmlNewTextWriter : out of memory!\n");
Daniel Veillardab69f362004-02-17 11:40:32 +0000152 return NULL;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000153 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000154
Daniel Veillard1d211e22003-10-20 22:32:39 +0000155 return ret;
156}
157
158/**
159 * xmlNewTextWriterFilename:
160 * @uri: the URI of the resource for the output
161 * @compression: compress the output?
162 *
163 * Create a new xmlNewTextWriter structure with @uri as output
164 *
165 * Returns the new xmlTextWriterPtr or NULL in case of error
166 */
167xmlTextWriterPtr
168xmlNewTextWriterFilename(const char *uri, int compression)
169{
170 xmlTextWriterPtr ret;
171 xmlOutputBufferPtr out;
172
173 out = xmlOutputBufferCreateFilename(uri, NULL, compression);
174 if (out == NULL) {
175 xmlGenericError(xmlGenericErrorContext,
176 "xmlNewTextWriterFilename : out of memory!\n");
177 return NULL;
178 }
179
180 ret = xmlNewTextWriter(out);
181 if (ret == NULL) {
182 xmlGenericError(xmlGenericErrorContext,
183 "xmlNewTextWriterFilename : out of memory!\n");
184 xmlOutputBufferClose(out);
185 return NULL;
186 }
187
Daniel Veillard2cca4462004-01-02 20:04:23 +0000188 ret->indent = 0;
189 ret->doindent = 0;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000190 return ret;
191}
192
193/**
194 * xmlNewTextWriterMemory:
195 * @buf: xmlBufferPtr
196 * @compression: compress the output?
197 *
198 * Create a new xmlNewTextWriter structure with @buf as output
199 * TODO: handle compression
200 *
201 * Returns the new xmlTextWriterPtr or NULL in case of error
202 */
203xmlTextWriterPtr
204xmlNewTextWriterMemory(xmlBufferPtr buf, int compression ATTRIBUTE_UNUSED)
205{
206 xmlTextWriterPtr ret;
207 xmlOutputBufferPtr out;
208
209/*::todo handle compression */
210 out = xmlOutputBufferCreateIO((xmlOutputWriteCallback)
211 xmlTextWriterWriteMemCallback,
212 (xmlOutputCloseCallback)
213 xmlTextWriterCloseMemCallback,
214 (void *) buf, NULL);
215 if (out == NULL) {
216 xmlGenericError(xmlGenericErrorContext,
217 "xmlNewTextWriterMemory : out of memory!\n");
218 return NULL;
219 }
220
221 ret = xmlNewTextWriter(out);
222 if (ret == NULL) {
223 xmlGenericError(xmlGenericErrorContext,
224 "xmlNewTextWriterMemory : out of memory!\n");
225 xmlOutputBufferClose(out);
226 return NULL;
227 }
228
229 return ret;
230}
231
232/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000233 * xmlNewTextWriterPushParser:
234 * @ctxt: xmlParserCtxtPtr to hold the new XML document tree
235 * @compression: compress the output?
236 *
237 * Create a new xmlNewTextWriter structure with @ctxt as output
238 * TODO: handle compression
239 *
240 * Returns the new xmlTextWriterPtr or NULL in case of error
241 */
242xmlTextWriterPtr
Daniel Veillard1d913862003-11-21 00:28:39 +0000243xmlNewTextWriterPushParser(xmlParserCtxtPtr ctxt,
244 int compression ATTRIBUTE_UNUSED)
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000245{
246 xmlTextWriterPtr ret;
247 xmlOutputBufferPtr out;
248
Daniel Veillard500a1de2004-03-22 15:22:58 +0000249 if (ctxt == NULL) {
250 xmlGenericError(xmlGenericErrorContext,
251 "xmlNewTextWriterPushParser : invalid context!\n");
252 return NULL;
253 }
254
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000255 out = xmlOutputBufferCreateIO((xmlOutputWriteCallback)
256 xmlTextWriterWriteDocCallback,
257 (xmlOutputCloseCallback)
258 xmlTextWriterCloseDocCallback,
259 (void *) ctxt, NULL);
260 if (out == NULL) {
261 xmlGenericError(xmlGenericErrorContext,
262 "xmlNewTextWriterPushParser : error at xmlOutputBufferCreateIO!\n");
263 return NULL;
264 }
265
266 ret = xmlNewTextWriter(out);
267 if (ret == NULL) {
268 xmlGenericError(xmlGenericErrorContext,
269 "xmlNewTextWriterPushParser : error at xmlNewTextWriter!\n");
270 xmlOutputBufferClose(out);
271 return NULL;
272 }
273
Daniel Veillard20c5e782004-01-21 09:57:31 +0000274 ret->ctxt = ctxt;
275
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000276 return ret;
277}
278
279/**
280 * xmlNewTextWriterDoc:
281 * @doc: address of a xmlDocPtr to hold the new XML document tree
282 * @compression: compress the output?
283 *
284 * Create a new xmlNewTextWriter structure with @*doc as output
285 *
286 * Returns the new xmlTextWriterPtr or NULL in case of error
287 */
288xmlTextWriterPtr
289xmlNewTextWriterDoc(xmlDocPtr * doc, int compression)
290{
291 xmlTextWriterPtr ret;
292 xmlSAXHandler saxHandler;
293 xmlParserCtxtPtr ctxt;
294
295 memset(&saxHandler, '\0', sizeof(saxHandler));
296 xmlSAX2InitDefaultSAXHandler(&saxHandler, 1);
297 saxHandler.startDocument = xmlTextWriterStartDocumentCallback;
298 saxHandler.startElement = xmlSAX2StartElement;
299 saxHandler.endElement = xmlSAX2EndElement;
300
301 ctxt = xmlCreatePushParserCtxt(&saxHandler, NULL, NULL, 0, NULL);
302 if (ctxt == NULL) {
303 xmlGenericError(xmlGenericErrorContext,
304 "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\n");
305 return NULL;
306 }
Daniel Veillard03a53c32004-10-26 16:06:51 +0000307 /*
308 * For some reason this seems to completely break if node names
309 * are interned.
310 */
311 ctxt->dictNames = 0;
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000312
Daniel Veillard1d913862003-11-21 00:28:39 +0000313 ctxt->myDoc = xmlNewDoc(BAD_CAST XML_DEFAULT_VERSION);
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000314 if (ctxt->myDoc == NULL) {
315 xmlFreeParserCtxt(ctxt);
316 xmlGenericError(xmlGenericErrorContext,
317 "xmlNewTextWriterDoc : error at xmlNewDoc!\n");
318 return NULL;
319 }
320
321 ret = xmlNewTextWriterPushParser(ctxt, compression);
322 if (ret == NULL) {
323 xmlGenericError(xmlGenericErrorContext,
324 "xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n");
325 return NULL;
326 }
327
Daniel Veillard500a1de2004-03-22 15:22:58 +0000328 xmlSetDocCompressMode(ctxt->myDoc, compression);
329
330 if (doc != NULL)
331 *doc = ctxt->myDoc;
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000332
333 return ret;
334}
335
336/**
337 * xmlNewTextWriterTree:
338 * @doc: xmlDocPtr
339 * @node: xmlNodePtr or NULL for doc->children
340 * @compression: compress the output?
341 *
342 * Create a new xmlNewTextWriter structure with @doc as output
343 * starting at @node
344 *
345 * Returns the new xmlTextWriterPtr or NULL in case of error
346 */
347xmlTextWriterPtr
348xmlNewTextWriterTree(xmlDocPtr doc, xmlNodePtr node, int compression)
349{
350 xmlTextWriterPtr ret;
351 xmlSAXHandler saxHandler;
352 xmlParserCtxtPtr ctxt;
353
354 if (doc == NULL) {
Daniel Veillard500a1de2004-03-22 15:22:58 +0000355 xmlGenericError(xmlGenericErrorContext,
356 "xmlNewTextWriterTree : invalid document tree!\n");
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000357 return NULL;
358 }
359
360 memset(&saxHandler, '\0', sizeof(saxHandler));
361 xmlSAX2InitDefaultSAXHandler(&saxHandler, 1);
362 saxHandler.startDocument = xmlTextWriterStartDocumentCallback;
363 saxHandler.startElement = xmlSAX2StartElement;
364 saxHandler.endElement = xmlSAX2EndElement;
365
366 ctxt = xmlCreatePushParserCtxt(&saxHandler, NULL, NULL, 0, NULL);
367 if (ctxt == NULL) {
368 xmlGenericError(xmlGenericErrorContext,
369 "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\n");
370 return NULL;
371 }
Daniel Veillard03a53c32004-10-26 16:06:51 +0000372 /*
373 * For some reason this seems to completely break if node names
374 * are interned.
375 */
376 ctxt->dictNames = 0;
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000377
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000378 ret = xmlNewTextWriterPushParser(ctxt, compression);
379 if (ret == NULL) {
Daniel Veillard500a1de2004-03-22 15:22:58 +0000380 xmlFreeParserCtxt(ctxt);
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000381 xmlGenericError(xmlGenericErrorContext,
382 "xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n");
383 return NULL;
384 }
385
Daniel Veillard500a1de2004-03-22 15:22:58 +0000386 ctxt->myDoc = doc;
387 ctxt->node = node;
388
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000389 xmlSetDocCompressMode(doc, compression);
390
391 return ret;
392}
393
394/**
Daniel Veillard1d211e22003-10-20 22:32:39 +0000395 * xmlFreeTextWriter:
396 * @writer: the xmlTextWriterPtr
397 *
398 * Deallocate all the resources associated to the writer
399 */
400void
401xmlFreeTextWriter(xmlTextWriterPtr writer)
402{
403 if (writer == NULL)
404 return;
405
406 if (writer->out != NULL)
407 xmlOutputBufferClose(writer->out);
408
409 if (writer->nodes != NULL)
410 xmlListDelete(writer->nodes);
411
412 if (writer->nsstack != NULL)
413 xmlListDelete(writer->nsstack);
414
Daniel Veillard20c5e782004-01-21 09:57:31 +0000415 if (writer->ctxt != NULL)
416 xmlFreeParserCtxt(writer->ctxt);
417
Daniel Veillard4773df22004-01-23 13:15:13 +0000418 if (writer->ichar != NULL)
419 xmlFree(writer->ichar);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000420 xmlFree(writer);
421}
422
423/**
424 * xmlTextWriterStartDocument:
425 * @writer: the xmlTextWriterPtr
426 * @version: the xml version ("1.0") or NULL for default ("1.0")
427 * @encoding: the encoding or NULL for default
428 * @standalone: "yes" or "no" or NULL for default
429 *
430 * Start a new xml document
431 *
432 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
433 */
434int
435xmlTextWriterStartDocument(xmlTextWriterPtr writer, const char *version,
436 const char *encoding, const char *standalone)
437{
438 int count;
439 int sum;
440 xmlLinkPtr lk;
441 xmlCharEncodingHandlerPtr encoder;
442
Daniel Veillard500a1de2004-03-22 15:22:58 +0000443 if ((writer == NULL) || (writer->out == NULL)) {
444 xmlGenericError(xmlGenericErrorContext,
445 "xmlTextWriterStartDocument : invalid writer!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000446 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000447 }
Daniel Veillard1d211e22003-10-20 22:32:39 +0000448
449 lk = xmlListFront(writer->nodes);
450 if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) {
451 xmlGenericError(xmlGenericErrorContext,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000452 "xmlTextWriterStartDocument : not allowed in this context!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000453 return -1;
454 }
455
456 encoder = NULL;
457 if (encoding != NULL) {
458 encoder = xmlFindCharEncodingHandler(encoding);
459 if (encoder == NULL) {
460 xmlGenericError(xmlGenericErrorContext,
461 "xmlTextWriterStartDocument : out of memory!\n");
462 return -1;
463 }
464 }
465
466 writer->out->encoder = encoder;
467 if (encoder != NULL) {
468 writer->out->conv = xmlBufferCreateSize(4000);
469 xmlCharEncOutFunc(encoder, writer->out->conv, NULL);
470 } else
471 writer->out->conv = NULL;
472
473 sum = 0;
474 count = xmlOutputBufferWriteString(writer->out, "<?xml version=");
475 if (count < 0)
476 return -1;
477 sum += count;
478 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
479 if (count < 0)
480 return -1;
481 sum += count;
482 if (version != 0)
483 count = xmlOutputBufferWriteString(writer->out, version);
484 else
485 count = xmlOutputBufferWriteString(writer->out, "1.0");
486 if (count < 0)
487 return -1;
488 sum += count;
489 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
490 if (count < 0)
491 return -1;
492 sum += count;
493 if (writer->out->encoder != 0) {
494 count = xmlOutputBufferWriteString(writer->out, " encoding=");
495 if (count < 0)
496 return -1;
497 sum += count;
498 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
499 if (count < 0)
500 return -1;
501 sum += count;
502 count =
503 xmlOutputBufferWriteString(writer->out,
504 writer->out->encoder->name);
505 if (count < 0)
506 return -1;
507 sum += count;
508 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
509 if (count < 0)
510 return -1;
511 sum += count;
512 }
513
514 if (standalone != 0) {
515 count = xmlOutputBufferWriteString(writer->out, " standalone=");
516 if (count < 0)
517 return -1;
518 sum += count;
519 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
520 if (count < 0)
521 return -1;
522 sum += count;
523 count = xmlOutputBufferWriteString(writer->out, standalone);
524 if (count < 0)
525 return -1;
526 sum += count;
527 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
528 if (count < 0)
529 return -1;
530 sum += count;
531 }
532
533 count = xmlOutputBufferWriteString(writer->out, "?>\n");
534 if (count < 0)
535 return -1;
536 sum += count;
537
538 return sum;
539}
540
541/**
542 * xmlTextWriterEndDocument:
543 * @writer: the xmlTextWriterPtr
544 *
545 * End an xml document. All open elements are closed
546 *
547 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
548 */
549int
550xmlTextWriterEndDocument(xmlTextWriterPtr writer)
551{
552 int count;
553 int sum;
554 xmlLinkPtr lk;
555 xmlTextWriterStackEntry *p;
556
Daniel Veillard500a1de2004-03-22 15:22:58 +0000557 if (writer == NULL) {
558 xmlGenericError(xmlGenericErrorContext,
559 "xmlTextWriterEndDocument : invalid writer!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000560 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000561 }
Daniel Veillard1d211e22003-10-20 22:32:39 +0000562
563 sum = 0;
564 while ((lk = xmlListFront(writer->nodes)) != NULL) {
565 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
566 if (p == 0)
567 break;
568 switch (p->state) {
569 case XML_TEXTWRITER_NAME:
570 case XML_TEXTWRITER_ATTRIBUTE:
571 case XML_TEXTWRITER_TEXT:
572 count = xmlTextWriterEndElement(writer);
573 if (count < 0)
574 return -1;
575 sum += count;
576 break;
577 case XML_TEXTWRITER_PI:
578 case XML_TEXTWRITER_PI_TEXT:
579 count = xmlTextWriterEndPI(writer);
580 if (count < 0)
581 return -1;
582 sum += count;
583 break;
584 case XML_TEXTWRITER_CDATA:
585 count = xmlTextWriterEndCDATA(writer);
586 if (count < 0)
587 return -1;
588 sum += count;
589 break;
590 case XML_TEXTWRITER_DTD:
Daniel Veillard500a1de2004-03-22 15:22:58 +0000591 case XML_TEXTWRITER_DTD_TEXT:
592 case XML_TEXTWRITER_DTD_ELEM:
593 case XML_TEXTWRITER_DTD_ELEM_TEXT:
594 case XML_TEXTWRITER_DTD_ATTL:
595 case XML_TEXTWRITER_DTD_ATTL_TEXT:
596 case XML_TEXTWRITER_DTD_ENTY:
597 case XML_TEXTWRITER_DTD_ENTY_TEXT:
598 case XML_TEXTWRITER_DTD_PENT:
Daniel Veillard1d211e22003-10-20 22:32:39 +0000599 count = xmlTextWriterEndDTD(writer);
600 if (count < 0)
601 return -1;
602 sum += count;
603 break;
Daniel Veillardab69f362004-02-17 11:40:32 +0000604 case XML_TEXTWRITER_COMMENT:
605 count = xmlTextWriterEndComment(writer);
606 if (count < 0)
607 return -1;
608 sum += count;
609 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000610 default:
Daniel Veillardab69f362004-02-17 11:40:32 +0000611 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000612 }
613 }
614
Daniel Veillard2cca4462004-01-02 20:04:23 +0000615 if (!writer->indent) {
Daniel Veillardab69f362004-02-17 11:40:32 +0000616 count = xmlOutputBufferWriteString(writer->out, "\n");
617 if (count < 0)
618 return -1;
619 sum += count;
620 }
621 return sum;
622}
623
Daniel Veillardab69f362004-02-17 11:40:32 +0000624/**
625 * xmlTextWriterStartComment:
626 * @writer: the xmlTextWriterPtr
627 *
628 * Start an xml comment.
629 *
630 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
631 */
632int
633xmlTextWriterStartComment(xmlTextWriterPtr writer)
634{
635 int count;
636 int sum;
637 xmlLinkPtr lk;
638 xmlTextWriterStackEntry *p;
639
Daniel Veillard500a1de2004-03-22 15:22:58 +0000640 if (writer == NULL) {
641 xmlGenericError(xmlGenericErrorContext,
642 "xmlTextWriterStartComment : invalid writer!\n");
Daniel Veillardab69f362004-02-17 11:40:32 +0000643 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000644 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000645
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_TEXT:
653 case XML_TEXTWRITER_NONE:
654 break;
655 case XML_TEXTWRITER_NAME:
656 count = xmlOutputBufferWriteString(writer->out, ">");
657 if (count < 0)
658 return -1;
659 sum += count;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000660 if (writer->indent) {
661 count =
662 xmlOutputBufferWriteString(writer->out, "\n");
663 if (count < 0)
664 return -1;
665 sum += count;
666 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000667 p->state = XML_TEXTWRITER_TEXT;
668 break;
669 default:
670 return -1;
671 }
672 }
673 }
674
675 p = (xmlTextWriterStackEntry *)
676 xmlMalloc(sizeof(xmlTextWriterStackEntry));
677 if (p == 0) {
678 xmlGenericError(xmlGenericErrorContext,
679 "xmlTextWriterStartElement : out of memory!\n");
680 return -1;
681 }
682
683 p->name = 0;
684 p->state = XML_TEXTWRITER_COMMENT;
685
686 xmlListPushFront(writer->nodes, p);
687
688 if (writer->indent) {
Daniel Veillardab69f362004-02-17 11:40:32 +0000689 count = xmlTextWriterWriteIndent(writer);
690 if (count < 0)
691 return -1;
692 sum += count;
693 }
694
695 count = xmlOutputBufferWriteString(writer->out, "<!--");
696 if (count < 0)
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000697 return -1;
698 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +0000699
700 return sum;
701}
702
703/**
704 * xmlTextWriterEndComment:
705 * @writer: the xmlTextWriterPtr
706 *
707 * End the current xml coment.
708 *
709 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
710 */
711int
712xmlTextWriterEndComment(xmlTextWriterPtr writer)
713{
714 int count;
715 int sum;
716 xmlLinkPtr lk;
717 xmlTextWriterStackEntry *p;
718
Daniel Veillard500a1de2004-03-22 15:22:58 +0000719 if (writer == NULL) {
720 xmlGenericError(xmlGenericErrorContext,
721 "xmlTextWriterEndComment : invalid writer!\n");
Daniel Veillardab69f362004-02-17 11:40:32 +0000722 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000723 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000724
725 lk = xmlListFront(writer->nodes);
Daniel Veillard500a1de2004-03-22 15:22:58 +0000726 if (lk == 0) {
727 xmlGenericError(xmlGenericErrorContext,
728 "xmlTextWriterEndComment : not allowed in this context!\n");
Daniel Veillardab69f362004-02-17 11:40:32 +0000729 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000730 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000731
732 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
733 if (p == 0)
734 return -1;
735
736 sum = 0;
737 switch (p->state) {
738 case XML_TEXTWRITER_COMMENT:
739 count = xmlOutputBufferWriteString(writer->out, "-->");
740 if (count < 0)
741 return -1;
742 sum += count;
743 break;
744 default:
745 return -1;
Daniel Veillard2cca4462004-01-02 20:04:23 +0000746 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000747
748 if (writer->indent) {
749 count = xmlOutputBufferWriteString(writer->out, "\n");
750 if (count < 0)
751 return -1;
752 sum += count;
753 }
754
755 xmlListPopFront(writer->nodes);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000756 return sum;
757}
758
759/**
760 * xmlTextWriterWriteFormatComment:
761 * @writer: the xmlTextWriterPtr
762 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +0000763 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +0000764 *
765 * Write an xml comment.
766 *
767 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
768 */
769int
770xmlTextWriterWriteFormatComment(xmlTextWriterPtr writer,
771 const char *format, ...)
772{
773 int rc;
774 va_list ap;
775
776 va_start(ap, format);
777
778 rc = xmlTextWriterWriteVFormatComment(writer, format, ap);
779
780 va_end(ap);
781 return rc;
782}
783
784/**
785 * xmlTextWriterWriteVFormatComment:
786 * @writer: the xmlTextWriterPtr
787 * @format: format string (see printf)
788 * @argptr: pointer to the first member of the variable argument list.
789 *
790 * Write an xml comment.
791 *
792 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
793 */
794int
795xmlTextWriterWriteVFormatComment(xmlTextWriterPtr writer,
796 const char *format, va_list argptr)
797{
798 int rc;
799 xmlChar *buf;
800
Daniel Veillard500a1de2004-03-22 15:22:58 +0000801 if (writer == NULL) {
802 xmlGenericError(xmlGenericErrorContext,
803 "xmlTextWriterWriteVFormatComment : invalid writer!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000804 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000805 }
Daniel Veillard1d211e22003-10-20 22:32:39 +0000806
807 buf = xmlTextWriterVSprintf(format, argptr);
808 if (buf == 0)
809 return 0;
810
811 rc = xmlTextWriterWriteComment(writer, buf);
812
813 xmlFree(buf);
814 return rc;
815}
816
817/**
818 * xmlTextWriterWriteComment:
819 * @writer: the xmlTextWriterPtr
820 * @content: comment string
821 *
822 * Write an xml comment.
823 *
824 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
825 */
826int
827xmlTextWriterWriteComment(xmlTextWriterPtr writer, const xmlChar * content)
828{
829 int count;
830 int sum;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000831
832 sum = 0;
Daniel Veillardab69f362004-02-17 11:40:32 +0000833 count = xmlTextWriterStartComment(writer);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000834 if (count < 0)
835 return -1;
836 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +0000837 count = xmlTextWriterWriteString(writer, content);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000838 if (count < 0)
839 return -1;
840 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +0000841 count = xmlTextWriterEndComment(writer);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000842 if (count < 0)
843 return -1;
844 sum += count;
845
846 return sum;
847}
848
849/**
850 * xmlTextWriterStartElement:
851 * @writer: the xmlTextWriterPtr
852 * @name: element name
853 *
854 * Start an xml element.
855 *
856 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
857 */
858int
859xmlTextWriterStartElement(xmlTextWriterPtr writer, const xmlChar * name)
860{
861 int count;
862 int sum;
863 xmlLinkPtr lk;
864 xmlTextWriterStackEntry *p;
865
866 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
867 return -1;
868
869 sum = 0;
870 lk = xmlListFront(writer->nodes);
871 if (lk != 0) {
872 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
873 if (p != 0) {
874 switch (p->state) {
875 case XML_TEXTWRITER_PI:
876 case XML_TEXTWRITER_PI_TEXT:
877 return -1;
878 case XML_TEXTWRITER_NONE:
879 break;
880 case XML_TEXTWRITER_NAME:
881 count = xmlOutputBufferWriteString(writer->out, ">");
882 if (count < 0)
883 return -1;
884 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +0000885 if (writer->indent)
886 count =
887 xmlOutputBufferWriteString(writer->out, "\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000888 p->state = XML_TEXTWRITER_TEXT;
889 break;
Daniel Veillardab69f362004-02-17 11:40:32 +0000890 default:
891 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000892 }
893 }
894 }
895
896 p = (xmlTextWriterStackEntry *)
897 xmlMalloc(sizeof(xmlTextWriterStackEntry));
898 if (p == 0) {
899 xmlGenericError(xmlGenericErrorContext,
900 "xmlTextWriterStartElement : out of memory!\n");
901 return -1;
902 }
903
904 p->name = xmlStrdup(name);
905 if (p->name == 0) {
906 xmlGenericError(xmlGenericErrorContext,
907 "xmlTextWriterStartElement : out of memory!\n");
908 xmlFree(p);
909 return -1;
910 }
911 p->state = XML_TEXTWRITER_NAME;
912
913 xmlListPushFront(writer->nodes, p);
914
Daniel Veillardab69f362004-02-17 11:40:32 +0000915 if (writer->indent) {
916 count = xmlTextWriterWriteIndent(writer);
917 sum += count;
Daniel Veillard2cca4462004-01-02 20:04:23 +0000918 }
919
Daniel Veillard1d211e22003-10-20 22:32:39 +0000920 count = xmlOutputBufferWriteString(writer->out, "<");
921 if (count < 0)
922 return -1;
923 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000924 count =
925 xmlOutputBufferWriteString(writer->out, (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000926 if (count < 0)
927 return -1;
928 sum += count;
929
930 return sum;
931}
932
933/**
934 * xmlTextWriterStartElementNS:
935 * @writer: the xmlTextWriterPtr
936 * @prefix: namespace prefix or NULL
937 * @name: element local name
938 * @namespaceURI: namespace URI or NULL
939 *
940 * Start an xml element with namespace support.
941 *
942 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
943 */
944int
945xmlTextWriterStartElementNS(xmlTextWriterPtr writer,
946 const xmlChar * prefix, const xmlChar * name,
947 const xmlChar * namespaceURI)
948{
949 int count;
950 int sum;
951 xmlChar *buf;
952
953 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
954 return -1;
955
956 buf = 0;
957 if (prefix != 0) {
958 buf = xmlStrdup(prefix);
959 buf = xmlStrcat(buf, BAD_CAST ":");
960 }
961 buf = xmlStrcat(buf, name);
962
963 sum = 0;
964 count = xmlTextWriterStartElement(writer, buf);
965 xmlFree(buf);
966 if (count < 0)
967 return -1;
968 sum += count;
969
970 if (namespaceURI != 0) {
971 buf = xmlStrdup(BAD_CAST "xmlns");
972 if (prefix != 0) {
973 buf = xmlStrcat(buf, BAD_CAST ":");
974 buf = xmlStrcat(buf, prefix);
975 }
976
977 count = xmlTextWriterWriteAttribute(writer, buf, namespaceURI);
978 xmlFree(buf);
979 if (count < 0)
980 return -1;
981 sum += count;
982 }
983
984 return sum;
985}
986
987/**
988 * xmlTextWriterEndElement:
989 * @writer: the xmlTextWriterPtr
990 *
991 * End the current xml element.
992 *
993 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
994 */
995int
996xmlTextWriterEndElement(xmlTextWriterPtr writer)
997{
998 int count;
999 int sum;
1000 xmlLinkPtr lk;
1001 xmlTextWriterStackEntry *p;
1002
1003 if (writer == NULL)
1004 return -1;
1005
1006 lk = xmlListFront(writer->nodes);
1007 if (lk == 0)
1008 return -1;
1009
1010 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1011 if (p == 0)
1012 return -1;
1013
1014 sum = 0;
1015 switch (p->state) {
1016 case XML_TEXTWRITER_ATTRIBUTE:
1017 count = xmlTextWriterEndAttribute(writer);
1018 if (count < 0)
1019 return -1;
1020 sum += count;
1021 /* fallthrough */
1022 case XML_TEXTWRITER_NAME:
Daniel Veillardab69f362004-02-17 11:40:32 +00001023 if (writer->indent) /* next element needs indent */
1024 writer->doindent = 1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001025 count = xmlOutputBufferWriteString(writer->out, "/>");
1026 if (count < 0)
1027 return -1;
1028 sum += count;
1029 break;
1030 case XML_TEXTWRITER_TEXT:
Daniel Veillardab69f362004-02-17 11:40:32 +00001031 if ((writer->indent) && (writer->doindent)) {
1032 count = xmlTextWriterWriteIndent(writer);
1033 sum += count;
1034 writer->doindent = 1;
1035 } else
1036 writer->doindent = 1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001037 count = xmlOutputBufferWriteString(writer->out, "</");
1038 if (count < 0)
1039 return -1;
1040 sum += count;
1041 count = xmlOutputBufferWriteString(writer->out,
Daniel Veillardab69f362004-02-17 11:40:32 +00001042 (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001043 if (count < 0)
1044 return -1;
1045 sum += count;
1046 count = xmlOutputBufferWriteString(writer->out, ">");
1047 if (count < 0)
1048 return -1;
1049 sum += count;
1050 break;
1051 default:
1052 return -1;
1053 }
1054
Daniel Veillard2cca4462004-01-02 20:04:23 +00001055 if (writer->indent) {
Daniel Veillardab69f362004-02-17 11:40:32 +00001056 count = xmlOutputBufferWriteString(writer->out, "\n");
1057 sum += count;
Daniel Veillard2cca4462004-01-02 20:04:23 +00001058 }
1059
Daniel Veillard1d211e22003-10-20 22:32:39 +00001060 xmlListPopFront(writer->nodes);
1061 return sum;
1062}
1063
1064/**
1065 * xmlTextWriterFullEndElement:
1066 * @writer: the xmlTextWriterPtr
1067 *
1068 * End the current xml element. Writes an end tag even if the element is empty
1069 *
1070 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1071 */
1072int
1073xmlTextWriterFullEndElement(xmlTextWriterPtr writer)
1074{
1075 int count;
1076 int sum;
1077 xmlLinkPtr lk;
1078 xmlTextWriterStackEntry *p;
1079
1080 if (writer == NULL)
1081 return -1;
1082
1083 lk = xmlListFront(writer->nodes);
1084 if (lk == 0)
1085 return -1;
1086
1087 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1088 if (p == 0)
1089 return -1;
1090
1091 sum = 0;
1092 switch (p->state) {
1093 case XML_TEXTWRITER_ATTRIBUTE:
1094 count = xmlTextWriterEndAttribute(writer);
1095 if (count < 0)
1096 return -1;
1097 sum += count;
1098 /* fallthrough */
1099 case XML_TEXTWRITER_NAME:
1100 count = xmlOutputBufferWriteString(writer->out, ">");
1101 if (count < 0)
1102 return -1;
1103 sum += count;
1104 /* fallthrough */
1105 case XML_TEXTWRITER_TEXT:
1106 count = xmlOutputBufferWriteString(writer->out, "</");
1107 if (count < 0)
1108 return -1;
1109 sum += count;
1110 count = xmlOutputBufferWriteString(writer->out,
Daniel Veillardab69f362004-02-17 11:40:32 +00001111 (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001112 if (count < 0)
1113 return -1;
1114 sum += count;
1115 count = xmlOutputBufferWriteString(writer->out, ">");
1116 if (count < 0)
1117 return -1;
1118 sum += count;
1119 break;
1120 default:
1121 return -1;
1122 }
1123
1124 xmlListPopFront(writer->nodes);
1125 return sum;
1126}
1127
1128/**
1129 * xmlTextWriterWriteFormatRaw:
1130 * @writer: the xmlTextWriterPtr
1131 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001132 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001133 *
1134 * Write a formatted raw xml text.
1135 *
1136 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1137 */
1138int
1139xmlTextWriterWriteFormatRaw(xmlTextWriterPtr writer, const char *format,
1140 ...)
1141{
1142 int rc;
1143 va_list ap;
1144
1145 va_start(ap, format);
1146
1147 rc = xmlTextWriterWriteVFormatRaw(writer, format, ap);
1148
1149 va_end(ap);
1150 return rc;
1151}
1152
1153/**
1154 * xmlTextWriterWriteVFormatRaw:
1155 * @writer: the xmlTextWriterPtr
1156 * @format: format string (see printf)
1157 * @argptr: pointer to the first member of the variable argument list.
1158 *
1159 * Write a formatted raw xml text.
1160 *
1161 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1162 */
1163int
1164xmlTextWriterWriteVFormatRaw(xmlTextWriterPtr writer, const char *format,
1165 va_list argptr)
1166{
1167 int rc;
1168 xmlChar *buf;
1169
1170 if (writer == NULL)
1171 return -1;
1172
1173 buf = xmlTextWriterVSprintf(format, argptr);
1174 if (buf == 0)
1175 return 0;
1176
1177 rc = xmlTextWriterWriteRaw(writer, buf);
1178
1179 xmlFree(buf);
1180 return rc;
1181}
1182
1183/**
Daniel Veillard1e906612003-12-05 14:57:46 +00001184 * xmlTextWriterWriteRawLen:
Daniel Veillard1d211e22003-10-20 22:32:39 +00001185 * @writer: the xmlTextWriterPtr
1186 * @content: text string
1187 * @len: length of the text string
1188 *
1189 * Write an xml text.
1190 * TODO: what about entities and special chars??
1191 *
1192 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1193 */
1194int
1195xmlTextWriterWriteRawLen(xmlTextWriterPtr writer, const xmlChar * content,
1196 int len)
1197{
1198 int count;
1199 int sum;
1200 xmlLinkPtr lk;
1201 xmlTextWriterStackEntry *p;
1202
Daniel Veillard500a1de2004-03-22 15:22:58 +00001203 if (writer == NULL) {
1204 xmlGenericError(xmlGenericErrorContext,
1205 "xmlTextWriterWriteRawLen : invalid writer!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +00001206 return -1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001207 }
1208
Daniel Veillarde43cc572004-11-03 11:50:29 +00001209 if ((content == NULL) || (len < 0)) {
Daniel Veillard500a1de2004-03-22 15:22:58 +00001210 xmlGenericError(xmlGenericErrorContext,
1211 "xmlTextWriterWriteRawLen : invalid content!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +00001212 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001213 }
1214
1215 sum = 0;
1216 lk = xmlListFront(writer->nodes);
1217 if (lk != 0) {
1218 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1219 count = xmlTextWriterHandleStateDependencies(writer, p);
1220 if (count < 0)
1221 return -1;
1222 sum += count;
1223 }
1224
1225 if (writer->indent)
1226 writer->doindent = 0;
1227
1228 if (content != NULL) {
1229 count =
1230 xmlOutputBufferWrite(writer->out, len, (const char *) content);
1231 if (count < 0)
1232 return -1;
1233 sum += count;
1234 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001235
1236 return sum;
1237}
1238
1239/**
1240 * xmlTextWriterWriteRaw:
1241 * @writer: the xmlTextWriterPtr
1242 * @content: text string
1243 *
1244 * Write a raw xml text.
1245 *
1246 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1247 */
1248int
1249xmlTextWriterWriteRaw(xmlTextWriterPtr writer, const xmlChar * content)
1250{
1251 return xmlTextWriterWriteRawLen(writer, content, xmlStrlen(content));
1252}
1253
1254/**
1255 * xmlTextWriterWriteFormatString:
1256 * @writer: the xmlTextWriterPtr
1257 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001258 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001259 *
1260 * Write a formatted xml text.
1261 *
1262 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1263 */
1264int
1265xmlTextWriterWriteFormatString(xmlTextWriterPtr writer, const char *format,
1266 ...)
1267{
1268 int rc;
1269 va_list ap;
1270
Daniel Veillarde43cc572004-11-03 11:50:29 +00001271 if ((writer == NULL) || (format == NULL))
1272 return -1;
1273
Daniel Veillard1d211e22003-10-20 22:32:39 +00001274 va_start(ap, format);
1275
1276 rc = xmlTextWriterWriteVFormatString(writer, format, ap);
1277
1278 va_end(ap);
1279 return rc;
1280}
1281
1282/**
1283 * xmlTextWriterWriteVFormatString:
1284 * @writer: the xmlTextWriterPtr
1285 * @format: format string (see printf)
1286 * @argptr: pointer to the first member of the variable argument list.
1287 *
1288 * Write a formatted xml text.
1289 *
1290 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1291 */
1292int
1293xmlTextWriterWriteVFormatString(xmlTextWriterPtr writer,
1294 const char *format, va_list argptr)
1295{
1296 int rc;
1297 xmlChar *buf;
1298
Daniel Veillarde43cc572004-11-03 11:50:29 +00001299 if ((writer == NULL) || (format == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00001300 return -1;
1301
1302 buf = xmlTextWriterVSprintf(format, argptr);
1303 if (buf == 0)
1304 return 0;
1305
1306 rc = xmlTextWriterWriteString(writer, buf);
1307
1308 xmlFree(buf);
1309 return rc;
1310}
1311
1312/**
1313 * xmlTextWriterWriteString:
1314 * @writer: the xmlTextWriterPtr
1315 * @content: text string
1316 *
1317 * Write an xml text.
1318 *
1319 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1320 */
1321int
1322xmlTextWriterWriteString(xmlTextWriterPtr writer, const xmlChar * content)
1323{
Daniel Veillard500a1de2004-03-22 15:22:58 +00001324 int count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001325 int sum;
1326 xmlLinkPtr lk;
1327 xmlTextWriterStackEntry *p;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001328 xmlChar *buf;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001329
Daniel Veillarde43cc572004-11-03 11:50:29 +00001330 if ((writer == NULL) || (content == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00001331 return -1;
1332
Daniel Veillard1d211e22003-10-20 22:32:39 +00001333 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001334 buf = (xmlChar *) content;
1335 lk = xmlListFront(writer->nodes);
1336 if (lk != 0) {
1337 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1338 if (p != 0) {
1339 switch (p->state) {
1340 case XML_TEXTWRITER_NAME:
1341 case XML_TEXTWRITER_TEXT:
Daniel Veillard62040be2004-05-17 03:17:26 +00001342#if 0
1343 buf = NULL;
1344 xmlOutputBufferWriteEscape(writer->out, content, NULL);
1345#endif
Daniel Veillard500a1de2004-03-22 15:22:58 +00001346 buf = xmlEncodeSpecialChars(NULL, content);
1347 break;
1348 case XML_TEXTWRITER_ATTRIBUTE:
1349 buf = NULL;
1350 xmlAttrSerializeTxtContent(writer->out->buffer, NULL,
1351 NULL, content);
1352 break;
William M. Brack87640d52004-04-17 14:58:15 +00001353 default:
1354 break;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001355 }
1356 }
1357 }
1358
1359 if (buf != NULL) {
1360 count = xmlTextWriterWriteRaw(writer, buf);
1361 if (count < 0)
Daniel Veillard1d211e22003-10-20 22:32:39 +00001362 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001363 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001364
Daniel Veillard500a1de2004-03-22 15:22:58 +00001365 if (buf != content) /* buf was allocated by us, so free it */
1366 xmlFree(buf);
William M. Bracka9c612c2004-02-01 10:04:05 +00001367 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001368
1369 return sum;
1370}
1371
1372/**
1373 * xmlOutputBufferWriteBase64:
1374 * @out: the xmlOutputBufferPtr
1375 * @data: binary data
1376 * @len: the number of bytes to encode
1377 *
1378 * Write base64 encoded data to an xmlOutputBuffer.
1379 * Adapted from John Walker's base64.c (http://www.fourmilab.ch/).
1380 *
1381 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1382 */
1383static int
1384xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len,
1385 const unsigned char *data)
1386{
1387 static unsigned char dtable[64] =
William M. Brack47a31882004-09-11 16:09:09 +00001388 {'A','B','C','D','E','F','G','H','I','J','K','L','M',
1389 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
1390 'a','b','c','d','e','f','g','h','i','j','k','l','m',
1391 'n','o','p','q','r','s','t','u','v','w','x','y','z',
1392 '0','1','2','3','4','5','6','7','8','9','+','/'};
1393
Daniel Veillard1d211e22003-10-20 22:32:39 +00001394 int i;
1395 int linelen;
1396 int count;
1397 int sum;
1398
Daniel Veillarde43cc572004-11-03 11:50:29 +00001399 if ((out == NULL) || (len < 0) || (data == NULL))
1400 return(-1);
1401
Daniel Veillard1d211e22003-10-20 22:32:39 +00001402 linelen = 0;
1403 sum = 0;
1404
1405 i = 0;
1406 while (1) {
1407 unsigned char igroup[3];
1408 unsigned char ogroup[4];
1409 int c;
1410 int n;
1411
1412 igroup[0] = igroup[1] = igroup[2] = 0;
1413 for (n = 0; n < 3 && i < len; n++, i++) {
1414 c = data[i];
1415 igroup[n] = (unsigned char) c;
1416 }
1417
1418 if (n > 0) {
1419 ogroup[0] = dtable[igroup[0] >> 2];
1420 ogroup[1] = dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)];
1421 ogroup[2] =
1422 dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)];
1423 ogroup[3] = dtable[igroup[2] & 0x3F];
1424
1425 if (n < 3) {
1426 ogroup[3] = '=';
1427 if (n < 2) {
1428 ogroup[2] = '=';
1429 }
1430 }
1431
1432 if (linelen >= B64LINELEN) {
1433 count = xmlOutputBufferWrite(out, 2, B64CRLF);
1434 if (count == -1)
1435 return -1;
1436 sum += count;
1437 linelen = 0;
1438 }
1439 count = xmlOutputBufferWrite(out, 4, (const char *) ogroup);
1440 if (count == -1)
1441 return -1;
1442 sum += count;
1443
1444 linelen += 4;
1445 }
Daniel Veillard929714b2003-10-22 12:34:36 +00001446
1447 if (i >= len)
1448 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001449 }
1450
Daniel Veillard1d211e22003-10-20 22:32:39 +00001451 return sum;
1452}
1453
1454/**
1455 * xmlTextWriterWriteBase64:
1456 * @writer: the xmlTextWriterPtr
1457 * @data: binary data
1458 * @start: the position within the data of the first byte to encode
1459 * @len: the number of bytes to encode
1460 *
1461 * Write an base64 encoded xml text.
1462 *
1463 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1464 */
1465int
Daniel Veillardab69f362004-02-17 11:40:32 +00001466xmlTextWriterWriteBase64(xmlTextWriterPtr writer, const char *data,
Daniel Veillard1d211e22003-10-20 22:32:39 +00001467 int start, int len)
1468{
1469 int count;
1470 int sum;
1471 xmlLinkPtr lk;
1472 xmlTextWriterStackEntry *p;
1473
Daniel Veillarde43cc572004-11-03 11:50:29 +00001474 if ((writer == NULL) || (data == NULL) || (start < 0) || (len < 0))
Daniel Veillard1d211e22003-10-20 22:32:39 +00001475 return -1;
1476
Daniel Veillard1d211e22003-10-20 22:32:39 +00001477 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001478 lk = xmlListFront(writer->nodes);
1479 if (lk != 0) {
1480 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1481 if (p != 0) {
1482 count = xmlTextWriterHandleStateDependencies(writer, p);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001483 if (count < 0)
1484 return -1;
1485 sum += count;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001486 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001487 }
1488
Daniel Veillardab69f362004-02-17 11:40:32 +00001489 if (writer->indent)
1490 writer->doindent = 0;
1491
Daniel Veillard1d211e22003-10-20 22:32:39 +00001492 count =
1493 xmlOutputBufferWriteBase64(writer->out, len,
1494 (unsigned char *) data + start);
1495 if (count < 0)
1496 return -1;
1497 sum += count;
1498
1499 return sum;
1500}
1501
1502/**
1503 * xmlOutputBufferWriteBinHex:
1504 * @out: the xmlOutputBufferPtr
1505 * @data: binary data
1506 * @len: the number of bytes to encode
1507 *
1508 * Write hqx encoded data to an xmlOutputBuffer.
1509 * ::todo
1510 *
William M. Brack47a31882004-09-11 16:09:09 +00001511 * Returns the bytes written (may be 0 because of buffering)
1512 * or -1 in case of error
Daniel Veillard1d211e22003-10-20 22:32:39 +00001513 */
1514static int
Daniel Veillardab69f362004-02-17 11:40:32 +00001515xmlOutputBufferWriteBinHex(xmlOutputBufferPtr out,
1516 int len, const unsigned char *data)
Daniel Veillard1d211e22003-10-20 22:32:39 +00001517{
Daniel Veillardab69f362004-02-17 11:40:32 +00001518 int count;
1519 int sum;
William M. Brack47a31882004-09-11 16:09:09 +00001520 static char hex[16] =
1521 {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
Daniel Veillardab69f362004-02-17 11:40:32 +00001522 int i;
1523
Daniel Veillarde43cc572004-11-03 11:50:29 +00001524 if ((out == NULL) || (data == NULL) || (len < 0)) {
Daniel Veillardab69f362004-02-17 11:40:32 +00001525 return -1;
1526 }
1527
1528 sum = 0;
1529 for (i = 0; i < len; i++) {
1530 count =
1531 xmlOutputBufferWrite(out, 1,
1532 (const char *) &hex[data[i] >> 4]);
1533 if (count == -1)
1534 return -1;
1535 sum += count;
1536 count =
1537 xmlOutputBufferWrite(out, 1,
1538 (const char *) &hex[data[i] & 0xF]);
1539 if (count == -1)
1540 return -1;
1541 sum += count;
1542 }
1543
1544 return sum;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001545}
1546
1547/**
1548 * xmlTextWriterWriteBinHex:
1549 * @writer: the xmlTextWriterPtr
1550 * @data: binary data
1551 * @start: the position within the data of the first byte to encode
1552 * @len: the number of bytes to encode
1553 *
1554 * Write a BinHex encoded xml text.
1555 *
1556 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1557 */
1558int
Daniel Veillardab69f362004-02-17 11:40:32 +00001559xmlTextWriterWriteBinHex(xmlTextWriterPtr writer, const char *data,
Daniel Veillard1d211e22003-10-20 22:32:39 +00001560 int start, int len)
1561{
1562 int count;
1563 int sum;
1564 xmlLinkPtr lk;
1565 xmlTextWriterStackEntry *p;
1566
Daniel Veillarde43cc572004-11-03 11:50:29 +00001567 if ((writer == NULL) || (data == NULL) || (start < 0) || (len < 0))
Daniel Veillard1d211e22003-10-20 22:32:39 +00001568 return -1;
1569
Daniel Veillard1d211e22003-10-20 22:32:39 +00001570 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001571 lk = xmlListFront(writer->nodes);
1572 if (lk != 0) {
1573 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1574 if (p != 0) {
1575 count = xmlTextWriterHandleStateDependencies(writer, p);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001576 if (count < 0)
1577 return -1;
1578 sum += count;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001579 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001580 }
1581
Daniel Veillardab69f362004-02-17 11:40:32 +00001582 if (writer->indent)
1583 writer->doindent = 0;
1584
Daniel Veillard1d211e22003-10-20 22:32:39 +00001585 count =
1586 xmlOutputBufferWriteBinHex(writer->out, len,
1587 (unsigned char *) data + start);
1588 if (count < 0)
1589 return -1;
1590 sum += count;
1591
1592 return sum;
1593}
1594
1595/**
1596 * xmlTextWriterStartAttribute:
1597 * @writer: the xmlTextWriterPtr
1598 * @name: element name
1599 *
1600 * Start an xml attribute.
1601 *
1602 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1603 */
1604int
1605xmlTextWriterStartAttribute(xmlTextWriterPtr writer, const xmlChar * name)
1606{
1607 int count;
1608 int sum;
1609 xmlLinkPtr lk;
1610 xmlTextWriterStackEntry *p;
1611
1612 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1613 return -1;
1614
1615 sum = 0;
1616 lk = xmlListFront(writer->nodes);
1617 if (lk == 0)
1618 return -1;
1619
1620 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1621 if (p == 0)
1622 return -1;
1623
1624 switch (p->state) {
1625 case XML_TEXTWRITER_ATTRIBUTE:
1626 count = xmlTextWriterEndAttribute(writer);
1627 if (count < 0)
1628 return -1;
1629 sum += count;
1630 /* fallthrough */
1631 case XML_TEXTWRITER_NAME:
1632 count = xmlOutputBufferWriteString(writer->out, " ");
1633 if (count < 0)
1634 return -1;
1635 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00001636 count =
1637 xmlOutputBufferWriteString(writer->out,
1638 (const char *) name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001639 if (count < 0)
1640 return -1;
1641 sum += count;
1642 count = xmlOutputBufferWriteString(writer->out, "=");
1643 if (count < 0)
1644 return -1;
1645 sum += count;
1646 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
1647 if (count < 0)
1648 return -1;
1649 sum += count;
1650 p->state = XML_TEXTWRITER_ATTRIBUTE;
1651 break;
1652 default:
1653 return -1;
1654 }
1655
1656 return sum;
1657}
1658
1659/**
1660 * xmlTextWriterStartAttributeNS:
1661 * @writer: the xmlTextWriterPtr
1662 * @prefix: namespace prefix or NULL
1663 * @name: element local name
1664 * @namespaceURI: namespace URI or NULL
1665 *
1666 * Start an xml attribute with namespace support.
1667 *
1668 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1669 */
1670int
1671xmlTextWriterStartAttributeNS(xmlTextWriterPtr writer,
1672 const xmlChar * prefix, const xmlChar * name,
1673 const xmlChar * namespaceURI)
1674{
1675 int count;
1676 int sum;
1677 xmlChar *buf;
1678 xmlTextWriterNsStackEntry *p;
1679
1680 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1681 return -1;
1682
1683 buf = 0;
1684 if (prefix != 0) {
1685 buf = xmlStrdup(prefix);
1686 buf = xmlStrcat(buf, BAD_CAST ":");
1687 }
1688 buf = xmlStrcat(buf, name);
1689
1690 sum = 0;
1691 count = xmlTextWriterStartAttribute(writer, buf);
1692 xmlFree(buf);
1693 if (count < 0)
1694 return -1;
1695 sum += count;
1696
1697 if (namespaceURI != 0) {
1698 buf = xmlStrdup(BAD_CAST "xmlns");
1699 if (prefix != 0) {
1700 buf = xmlStrcat(buf, BAD_CAST ":");
1701 buf = xmlStrcat(buf, prefix);
1702 }
1703
1704 p = (xmlTextWriterNsStackEntry *)
1705 xmlMalloc(sizeof(xmlTextWriterNsStackEntry));
1706 if (p == 0) {
1707 xmlGenericError(xmlGenericErrorContext,
1708 "xmlTextWriterStartAttributeNS : out of memory!\n");
1709 return -1;
1710 }
1711
1712 p->prefix = buf;
1713 p->uri = xmlStrdup(namespaceURI);
1714 if (p->uri == 0) {
1715 xmlGenericError(xmlGenericErrorContext,
1716 "xmlTextWriterStartAttributeNS : out of memory!\n");
1717 xmlFree(p);
1718 return -1;
1719 }
1720 p->elem = xmlListFront(writer->nodes);
1721
1722 xmlListPushFront(writer->nsstack, p);
1723 }
1724
1725 return sum;
1726}
1727
1728/**
1729 * xmlTextWriterEndAttribute:
1730 * @writer: the xmlTextWriterPtr
1731 *
1732 * End the current xml element.
1733 *
1734 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1735 */
1736int
1737xmlTextWriterEndAttribute(xmlTextWriterPtr writer)
1738{
1739 int count;
1740 int sum;
1741 xmlLinkPtr lk;
1742 xmlTextWriterStackEntry *p;
1743 xmlTextWriterNsStackEntry *np;
1744
1745 if (writer == NULL)
1746 return -1;
1747
1748 lk = xmlListFront(writer->nodes);
1749 if (lk == 0) {
1750 xmlListDelete(writer->nsstack);
Daniel Veillarde43cc572004-11-03 11:50:29 +00001751 writer->nsstack = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001752 return -1;
1753 }
1754
1755 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1756 if (p == 0) {
1757 xmlListDelete(writer->nsstack);
Daniel Veillarde43cc572004-11-03 11:50:29 +00001758 writer->nsstack = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001759 return -1;
1760 }
1761
1762 sum = 0;
1763 switch (p->state) {
1764 case XML_TEXTWRITER_ATTRIBUTE:
1765 p->state = XML_TEXTWRITER_NAME;
1766
1767 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
1768 if (count < 0) {
1769 xmlListDelete(writer->nsstack);
Daniel Veillarde43cc572004-11-03 11:50:29 +00001770 writer->nsstack = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001771 return -1;
1772 }
1773 sum += count;
1774
1775 while (!xmlListEmpty(writer->nsstack)) {
1776 lk = xmlListFront(writer->nsstack);
1777 np = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
1778 if (np != 0) {
1779 count =
1780 xmlTextWriterWriteAttribute(writer, np->prefix,
1781 np->uri);
1782 if (count < 0) {
1783 xmlListDelete(writer->nsstack);
Daniel Veillarde43cc572004-11-03 11:50:29 +00001784 writer->nsstack = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001785 return -1;
1786 }
1787 sum += count;
1788 }
1789
1790 xmlListPopFront(writer->nsstack);
1791 }
1792 break;
1793
1794 default:
1795 xmlListClear(writer->nsstack);
1796 return -1;
1797 }
1798
1799 return sum;
1800}
1801
1802/**
1803 * xmlTextWriterWriteFormatAttribute:
1804 * @writer: the xmlTextWriterPtr
1805 * @name: attribute name
1806 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001807 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001808 *
1809 * Write a formatted xml attribute.
1810 *
1811 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1812 */
1813int
1814xmlTextWriterWriteFormatAttribute(xmlTextWriterPtr writer,
1815 const xmlChar * name, const char *format,
1816 ...)
1817{
1818 int rc;
1819 va_list ap;
1820
1821 va_start(ap, format);
1822
1823 rc = xmlTextWriterWriteVFormatAttribute(writer, name, format, ap);
1824
1825 va_end(ap);
1826 return rc;
1827}
1828
1829/**
1830 * xmlTextWriterWriteVFormatAttribute:
1831 * @writer: the xmlTextWriterPtr
1832 * @name: attribute name
1833 * @format: format string (see printf)
1834 * @argptr: pointer to the first member of the variable argument list.
1835 *
1836 * Write a formatted xml attribute.
1837 *
1838 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1839 */
1840int
1841xmlTextWriterWriteVFormatAttribute(xmlTextWriterPtr writer,
1842 const xmlChar * name,
1843 const char *format, va_list argptr)
1844{
1845 int rc;
1846 xmlChar *buf;
1847
1848 if (writer == NULL)
1849 return -1;
1850
1851 buf = xmlTextWriterVSprintf(format, argptr);
1852 if (buf == 0)
1853 return 0;
1854
1855 rc = xmlTextWriterWriteAttribute(writer, name, buf);
1856
1857 xmlFree(buf);
1858 return rc;
1859}
1860
1861/**
1862 * xmlTextWriterWriteAttribute:
1863 * @writer: the xmlTextWriterPtr
1864 * @name: attribute name
1865 * @content: attribute content
1866 *
1867 * Write an xml attribute.
1868 *
1869 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1870 */
1871int
1872xmlTextWriterWriteAttribute(xmlTextWriterPtr writer, const xmlChar * name,
1873 const xmlChar * content)
1874{
1875 int count;
1876 int sum;
1877
1878 sum = 0;
1879 count = xmlTextWriterStartAttribute(writer, name);
1880 if (count < 0)
1881 return -1;
1882 sum += count;
1883 count = xmlTextWriterWriteString(writer, content);
1884 if (count < 0)
1885 return -1;
1886 sum += count;
1887 count = xmlTextWriterEndAttribute(writer);
1888 if (count < 0)
1889 return -1;
1890 sum += count;
1891
1892 return sum;
1893}
1894
1895/**
1896 * xmlTextWriterWriteFormatAttributeNS:
1897 * @writer: the xmlTextWriterPtr
1898 * @prefix: namespace prefix
1899 * @name: attribute local name
1900 * @namespaceURI: namespace URI
1901 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001902 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001903 *
1904 * Write a formatted xml attribute.with namespace support
1905 *
1906 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1907 */
1908int
1909xmlTextWriterWriteFormatAttributeNS(xmlTextWriterPtr writer,
1910 const xmlChar * prefix,
1911 const xmlChar * name,
1912 const xmlChar * namespaceURI,
1913 const char *format, ...)
1914{
1915 int rc;
1916 va_list ap;
1917
1918 va_start(ap, format);
1919
1920 rc = xmlTextWriterWriteVFormatAttributeNS(writer, prefix, name,
1921 namespaceURI, format, ap);
1922
1923 va_end(ap);
1924 return rc;
1925}
1926
1927/**
1928 * xmlTextWriterWriteVFormatAttributeNS:
1929 * @writer: the xmlTextWriterPtr
1930 * @prefix: namespace prefix
1931 * @name: attribute local name
1932 * @namespaceURI: namespace URI
1933 * @format: format string (see printf)
1934 * @argptr: pointer to the first member of the variable argument list.
1935 *
1936 * Write a formatted xml attribute.with namespace support
1937 *
1938 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1939 */
1940int
1941xmlTextWriterWriteVFormatAttributeNS(xmlTextWriterPtr writer,
1942 const xmlChar * prefix,
1943 const xmlChar * name,
1944 const xmlChar * namespaceURI,
1945 const char *format, va_list argptr)
1946{
1947 int rc;
1948 xmlChar *buf;
1949
1950 if (writer == NULL)
1951 return -1;
1952
1953 buf = xmlTextWriterVSprintf(format, argptr);
1954 if (buf == 0)
1955 return 0;
1956
1957 rc = xmlTextWriterWriteAttributeNS(writer, prefix, name, namespaceURI,
1958 buf);
1959
1960 xmlFree(buf);
1961 return rc;
1962}
1963
1964/**
1965 * xmlTextWriterWriteAttributeNS:
1966 * @writer: the xmlTextWriterPtr
1967 * @prefix: namespace prefix
1968 * @name: attribute local name
1969 * @namespaceURI: namespace URI
1970 * @content: attribute content
1971 *
1972 * Write an xml attribute.
1973 *
1974 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1975 */
1976int
1977xmlTextWriterWriteAttributeNS(xmlTextWriterPtr writer,
1978 const xmlChar * prefix, const xmlChar * name,
1979 const xmlChar * namespaceURI,
1980 const xmlChar * content)
1981{
1982 int count;
1983 int sum;
1984 xmlChar *buf;
1985
1986 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1987 return -1;
1988
1989 buf = 0;
1990 if (prefix != NULL) {
1991 buf = xmlStrdup(prefix);
1992 buf = xmlStrcat(buf, BAD_CAST ":");
1993 }
1994 buf = xmlStrcat(buf, name);
1995
1996 sum = 0;
1997 count = xmlTextWriterWriteAttribute(writer, buf, content);
1998 xmlFree(buf);
1999 if (count < 0)
2000 return -1;
2001 sum += count;
2002
2003 if (namespaceURI != NULL) {
2004 buf = 0;
2005 buf = xmlStrdup(BAD_CAST "xmlns");
2006 if (prefix != NULL) {
2007 buf = xmlStrcat(buf, BAD_CAST ":");
2008 buf = xmlStrcat(buf, prefix);
2009 }
2010 count = xmlTextWriterWriteAttribute(writer, buf, namespaceURI);
2011 xmlFree(buf);
2012 if (count < 0)
2013 return -1;
2014 sum += count;
2015 }
2016 return sum;
2017}
2018
2019/**
2020 * xmlTextWriterWriteFormatElement:
2021 * @writer: the xmlTextWriterPtr
2022 * @name: element name
2023 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002024 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002025 *
2026 * Write a formatted xml element.
2027 *
2028 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2029 */
2030int
2031xmlTextWriterWriteFormatElement(xmlTextWriterPtr writer,
2032 const xmlChar * name, const char *format,
2033 ...)
2034{
2035 int rc;
2036 va_list ap;
2037
2038 va_start(ap, format);
2039
2040 rc = xmlTextWriterWriteVFormatElement(writer, name, format, ap);
2041
2042 va_end(ap);
2043 return rc;
2044}
2045
2046/**
2047 * xmlTextWriterWriteVFormatElement:
2048 * @writer: the xmlTextWriterPtr
2049 * @name: element name
2050 * @format: format string (see printf)
2051 * @argptr: pointer to the first member of the variable argument list.
2052 *
2053 * Write a formatted xml element.
2054 *
2055 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2056 */
2057int
2058xmlTextWriterWriteVFormatElement(xmlTextWriterPtr writer,
2059 const xmlChar * name, const char *format,
2060 va_list argptr)
2061{
2062 int rc;
2063 xmlChar *buf;
2064
2065 if (writer == NULL)
2066 return -1;
2067
2068 buf = xmlTextWriterVSprintf(format, argptr);
2069 if (buf == 0)
2070 return 0;
2071
2072 rc = xmlTextWriterWriteElement(writer, name, buf);
2073
2074 xmlFree(buf);
2075 return rc;
2076}
2077
2078/**
2079 * xmlTextWriterWriteElement:
2080 * @writer: the xmlTextWriterPtr
2081 * @name: element name
2082 * @content: element content
2083 *
2084 * Write an xml element.
2085 *
2086 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2087 */
2088int
2089xmlTextWriterWriteElement(xmlTextWriterPtr writer, const xmlChar * name,
2090 const xmlChar * content)
2091{
2092 int count;
2093 int sum;
2094
2095 sum = 0;
2096 count = xmlTextWriterStartElement(writer, name);
2097 if (count == -1)
2098 return -1;
2099 sum += count;
2100 count = xmlTextWriterWriteString(writer, content);
2101 if (count == -1)
2102 return -1;
2103 sum += count;
2104 count = xmlTextWriterEndElement(writer);
2105 if (count == -1)
2106 return -1;
2107 sum += count;
2108
2109 return sum;
2110}
2111
2112/**
2113 * xmlTextWriterWriteFormatElementNS:
2114 * @writer: the xmlTextWriterPtr
2115 * @prefix: namespace prefix
2116 * @name: element local name
2117 * @namespaceURI: namespace URI
2118 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002119 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002120 *
2121 * Write a formatted xml element with namespace support.
2122 *
2123 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2124 */
2125int
2126xmlTextWriterWriteFormatElementNS(xmlTextWriterPtr writer,
2127 const xmlChar * prefix,
2128 const xmlChar * name,
2129 const xmlChar * namespaceURI,
2130 const char *format, ...)
2131{
2132 int rc;
2133 va_list ap;
2134
2135 va_start(ap, format);
2136
2137 rc = xmlTextWriterWriteVFormatElementNS(writer, prefix, name,
2138 namespaceURI, format, ap);
2139
2140 va_end(ap);
2141 return rc;
2142}
2143
2144/**
2145 * xmlTextWriterWriteVFormatElementNS:
2146 * @writer: the xmlTextWriterPtr
2147 * @prefix: namespace prefix
2148 * @name: element local name
2149 * @namespaceURI: namespace URI
2150 * @format: format string (see printf)
2151 * @argptr: pointer to the first member of the variable argument list.
2152 *
2153 * Write a formatted xml element with namespace support.
2154 *
2155 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2156 */
2157int
2158xmlTextWriterWriteVFormatElementNS(xmlTextWriterPtr writer,
2159 const xmlChar * prefix,
2160 const xmlChar * name,
2161 const xmlChar * namespaceURI,
2162 const char *format, va_list argptr)
2163{
2164 int rc;
2165 xmlChar *buf;
2166
2167 if (writer == NULL)
2168 return -1;
2169
2170 buf = xmlTextWriterVSprintf(format, argptr);
2171 if (buf == 0)
2172 return 0;
2173
2174 rc = xmlTextWriterWriteElementNS(writer, prefix, name, namespaceURI,
2175 buf);
2176
2177 xmlFree(buf);
2178 return rc;
2179}
2180
2181/**
2182 * xmlTextWriterWriteElementNS:
2183 * @writer: the xmlTextWriterPtr
2184 * @prefix: namespace prefix
2185 * @name: element local name
2186 * @namespaceURI: namespace URI
2187 * @content: element content
2188 *
2189 * Write an xml element with namespace support.
2190 *
2191 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2192 */
2193int
2194xmlTextWriterWriteElementNS(xmlTextWriterPtr writer,
2195 const xmlChar * prefix, const xmlChar * name,
2196 const xmlChar * namespaceURI,
2197 const xmlChar * content)
2198{
2199 int count;
2200 int sum;
2201
2202 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
2203 return -1;
2204
2205 sum = 0;
2206 count =
2207 xmlTextWriterStartElementNS(writer, prefix, name, namespaceURI);
2208 if (count < 0)
2209 return -1;
2210 sum += count;
2211 count = xmlTextWriterWriteString(writer, content);
2212 if (count == -1)
2213 return -1;
2214 sum += count;
2215 count = xmlTextWriterEndElement(writer);
2216 if (count == -1)
2217 return -1;
2218 sum += count;
2219
2220 return sum;
2221}
2222
2223/**
2224 * xmlTextWriterStartPI:
2225 * @writer: the xmlTextWriterPtr
2226 * @target: PI target
2227 *
2228 * Start an xml PI.
2229 *
2230 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2231 */
2232int
2233xmlTextWriterStartPI(xmlTextWriterPtr writer, const xmlChar * target)
2234{
2235 int count;
2236 int sum;
2237 xmlLinkPtr lk;
2238 xmlTextWriterStackEntry *p;
2239
2240 if ((writer == NULL) || (target == NULL) || (*target == '\0'))
2241 return -1;
2242
2243 if (xmlStrcasecmp(target, (const xmlChar *) "xml") == 0) {
2244 xmlGenericError(xmlGenericErrorContext,
2245 "xmlTextWriterStartPI : target name [Xx][Mm][Ll] is reserved for xml standardization!\n");
2246 return -1;
2247 }
2248
2249 sum = 0;
2250 lk = xmlListFront(writer->nodes);
2251 if (lk != 0) {
2252 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2253 if (p != 0) {
2254 switch (p->state) {
2255 case XML_TEXTWRITER_ATTRIBUTE:
2256 count = xmlTextWriterEndAttribute(writer);
2257 if (count < 0)
2258 return -1;
2259 sum += count;
2260 /* fallthrough */
2261 case XML_TEXTWRITER_NAME:
2262 count = xmlOutputBufferWriteString(writer->out, ">");
2263 if (count < 0)
2264 return -1;
2265 sum += count;
2266 p->state = XML_TEXTWRITER_TEXT;
2267 break;
Daniel Veillardab69f362004-02-17 11:40:32 +00002268 case XML_TEXTWRITER_NONE:
2269 case XML_TEXTWRITER_TEXT:
2270 case XML_TEXTWRITER_DTD:
2271 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002272 case XML_TEXTWRITER_PI:
2273 case XML_TEXTWRITER_PI_TEXT:
2274 xmlGenericError(xmlGenericErrorContext,
2275 "xmlTextWriterStartPI : nested PI!\n");
2276 return -1;
2277 default:
2278 return -1;
2279 }
2280 }
2281 }
2282
2283 p = (xmlTextWriterStackEntry *)
2284 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2285 if (p == 0) {
2286 xmlGenericError(xmlGenericErrorContext,
2287 "xmlTextWriterStartPI : out of memory!\n");
2288 return -1;
2289 }
2290
2291 p->name = xmlStrdup(target);
2292 if (p->name == 0) {
2293 xmlGenericError(xmlGenericErrorContext,
2294 "xmlTextWriterStartPI : out of memory!\n");
2295 xmlFree(p);
2296 return -1;
2297 }
2298 p->state = XML_TEXTWRITER_PI;
2299
2300 xmlListPushFront(writer->nodes, p);
2301
2302 count = xmlOutputBufferWriteString(writer->out, "<?");
2303 if (count < 0)
2304 return -1;
2305 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002306 count =
2307 xmlOutputBufferWriteString(writer->out, (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002308 if (count < 0)
2309 return -1;
2310 sum += count;
2311
2312 return sum;
2313}
2314
2315/**
2316 * xmlTextWriterEndPI:
2317 * @writer: the xmlTextWriterPtr
2318 *
2319 * End the current xml PI.
2320 *
2321 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2322 */
2323int
2324xmlTextWriterEndPI(xmlTextWriterPtr writer)
2325{
2326 int count;
2327 int sum;
2328 xmlLinkPtr lk;
2329 xmlTextWriterStackEntry *p;
2330
2331 if (writer == NULL)
2332 return -1;
2333
2334 lk = xmlListFront(writer->nodes);
2335 if (lk == 0)
2336 return 0;
2337
2338 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2339 if (p == 0)
2340 return 0;
2341
2342 sum = 0;
2343 switch (p->state) {
2344 case XML_TEXTWRITER_PI:
2345 case XML_TEXTWRITER_PI_TEXT:
2346 count = xmlOutputBufferWriteString(writer->out, "?>");
2347 if (count < 0)
2348 return -1;
2349 sum += count;
2350 break;
2351 default:
2352 return -1;
2353 }
2354
2355 xmlListPopFront(writer->nodes);
2356 return sum;
2357}
2358
2359/**
2360 * xmlTextWriterWriteFormatPI:
2361 * @writer: the xmlTextWriterPtr
2362 * @target: PI target
2363 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002364 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002365 *
2366 * Write a formatted PI.
2367 *
2368 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2369 */
2370int
2371xmlTextWriterWriteFormatPI(xmlTextWriterPtr writer, const xmlChar * target,
2372 const char *format, ...)
2373{
2374 int rc;
2375 va_list ap;
2376
2377 va_start(ap, format);
2378
2379 rc = xmlTextWriterWriteVFormatPI(writer, target, format, ap);
2380
2381 va_end(ap);
2382 return rc;
2383}
2384
2385/**
2386 * xmlTextWriterWriteVFormatPI:
2387 * @writer: the xmlTextWriterPtr
2388 * @target: PI target
2389 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002390 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00002391 *
2392 * Write a formatted xml PI.
2393 *
2394 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2395 */
2396int
2397xmlTextWriterWriteVFormatPI(xmlTextWriterPtr writer,
2398 const xmlChar * target, const char *format,
2399 va_list argptr)
2400{
2401 int rc;
2402 xmlChar *buf;
2403
2404 if (writer == NULL)
2405 return -1;
2406
2407 buf = xmlTextWriterVSprintf(format, argptr);
2408 if (buf == 0)
2409 return 0;
2410
2411 rc = xmlTextWriterWritePI(writer, target, buf);
2412
2413 xmlFree(buf);
2414 return rc;
2415}
2416
2417/**
2418 * xmlTextWriterWritePI:
2419 * @writer: the xmlTextWriterPtr
2420 * @target: PI target
2421 * @content: PI content
2422 *
2423 * Write an xml PI.
2424 *
2425 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2426 */
2427int
2428xmlTextWriterWritePI(xmlTextWriterPtr writer, const xmlChar * target,
2429 const xmlChar * content)
2430{
2431 int count;
2432 int sum;
2433
2434 sum = 0;
2435 count = xmlTextWriterStartPI(writer, target);
2436 if (count == -1)
2437 return -1;
2438 sum += count;
2439 if (content != 0) {
2440 count = xmlTextWriterWriteString(writer, content);
2441 if (count == -1)
2442 return -1;
2443 sum += count;
2444 }
2445 count = xmlTextWriterEndPI(writer);
2446 if (count == -1)
2447 return -1;
2448 sum += count;
2449
2450 return sum;
2451}
2452
2453/**
2454 * xmlTextWriterStartCDATA:
2455 * @writer: the xmlTextWriterPtr
2456 *
2457 * Start an xml CDATA section.
2458 *
2459 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2460 */
2461int
2462xmlTextWriterStartCDATA(xmlTextWriterPtr writer)
2463{
2464 int count;
2465 int sum;
2466 xmlLinkPtr lk;
2467 xmlTextWriterStackEntry *p;
2468
2469 if (writer == NULL)
2470 return -1;
2471
2472 sum = 0;
2473 lk = xmlListFront(writer->nodes);
2474 if (lk != 0) {
2475 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2476 if (p != 0) {
2477 switch (p->state) {
2478 case XML_TEXTWRITER_NONE:
2479 case XML_TEXTWRITER_PI:
2480 case XML_TEXTWRITER_PI_TEXT:
2481 break;
2482 case XML_TEXTWRITER_ATTRIBUTE:
2483 count = xmlTextWriterEndAttribute(writer);
2484 if (count < 0)
2485 return -1;
2486 sum += count;
2487 /* fallthrough */
2488 case XML_TEXTWRITER_NAME:
2489 count = xmlOutputBufferWriteString(writer->out, ">");
2490 if (count < 0)
2491 return -1;
2492 sum += count;
2493 p->state = XML_TEXTWRITER_TEXT;
2494 break;
2495 case XML_TEXTWRITER_CDATA:
2496 xmlGenericError(xmlGenericErrorContext,
2497 "xmlTextWriterStartCDATA : CDATA not allowed in this context!\n");
2498 return -1;
2499 default:
2500 return -1;
2501 }
2502 }
2503 }
2504
2505 p = (xmlTextWriterStackEntry *)
2506 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2507 if (p == 0) {
2508 xmlGenericError(xmlGenericErrorContext,
2509 "xmlTextWriterStartCDATA : out of memory!\n");
2510 return -1;
2511 }
2512
2513 p->name = 0;
2514 p->state = XML_TEXTWRITER_CDATA;
2515
2516 xmlListPushFront(writer->nodes, p);
2517
2518 count = xmlOutputBufferWriteString(writer->out, "<![CDATA[");
2519 if (count < 0)
2520 return -1;
2521 sum += count;
2522
2523 return sum;
2524}
2525
2526/**
2527 * xmlTextWriterEndCDATA:
2528 * @writer: the xmlTextWriterPtr
2529 *
2530 * End an xml CDATA section.
2531 *
2532 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2533 */
2534int
2535xmlTextWriterEndCDATA(xmlTextWriterPtr writer)
2536{
2537 int count;
2538 int sum;
2539 xmlLinkPtr lk;
2540 xmlTextWriterStackEntry *p;
2541
2542 if (writer == NULL)
2543 return -1;
2544
2545 lk = xmlListFront(writer->nodes);
2546 if (lk == 0)
2547 return -1;
2548
2549 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2550 if (p == 0)
2551 return -1;
2552
2553 sum = 0;
2554 switch (p->state) {
2555 case XML_TEXTWRITER_CDATA:
2556 count = xmlOutputBufferWriteString(writer->out, "]]>");
2557 if (count < 0)
2558 return -1;
2559 sum += count;
2560 break;
2561 default:
2562 return -1;
2563 }
2564
2565 xmlListPopFront(writer->nodes);
2566 return sum;
2567}
2568
2569/**
2570 * xmlTextWriterWriteFormatCDATA:
2571 * @writer: the xmlTextWriterPtr
2572 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002573 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002574 *
2575 * Write a formatted xml CDATA.
2576 *
2577 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2578 */
2579int
2580xmlTextWriterWriteFormatCDATA(xmlTextWriterPtr writer, const char *format,
2581 ...)
2582{
2583 int rc;
2584 va_list ap;
2585
2586 va_start(ap, format);
2587
2588 rc = xmlTextWriterWriteVFormatCDATA(writer, format, ap);
2589
2590 va_end(ap);
2591 return rc;
2592}
2593
2594/**
2595 * xmlTextWriterWriteVFormatCDATA:
2596 * @writer: the xmlTextWriterPtr
2597 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002598 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00002599 *
2600 * Write a formatted xml CDATA.
2601 *
2602 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2603 */
2604int
2605xmlTextWriterWriteVFormatCDATA(xmlTextWriterPtr writer, const char *format,
2606 va_list argptr)
2607{
2608 int rc;
2609 xmlChar *buf;
2610
2611 if (writer == NULL)
2612 return -1;
2613
2614 buf = xmlTextWriterVSprintf(format, argptr);
2615 if (buf == 0)
2616 return 0;
2617
2618 rc = xmlTextWriterWriteCDATA(writer, buf);
2619
2620 xmlFree(buf);
2621 return rc;
2622}
2623
2624/**
2625 * xmlTextWriterWriteCDATA:
2626 * @writer: the xmlTextWriterPtr
2627 * @content: CDATA content
2628 *
2629 * Write an xml CDATA.
2630 *
2631 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2632 */
2633int
2634xmlTextWriterWriteCDATA(xmlTextWriterPtr writer, const xmlChar * content)
2635{
2636 int count;
2637 int sum;
2638
2639 sum = 0;
2640 count = xmlTextWriterStartCDATA(writer);
2641 if (count == -1)
2642 return -1;
2643 sum += count;
2644 if (content != 0) {
2645 count = xmlTextWriterWriteString(writer, content);
2646 if (count == -1)
2647 return -1;
2648 sum += count;
2649 }
2650 count = xmlTextWriterEndCDATA(writer);
2651 if (count == -1)
2652 return -1;
2653 sum += count;
2654
2655 return sum;
2656}
2657
2658/**
2659 * xmlTextWriterStartDTD:
2660 * @writer: the xmlTextWriterPtr
2661 * @name: the name of the DTD
2662 * @pubid: the public identifier, which is an alternative to the system identifier
2663 * @sysid: the system identifier, which is the URI of the DTD
2664 *
2665 * Start an xml DTD.
2666 *
2667 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2668 */
2669int
2670xmlTextWriterStartDTD(xmlTextWriterPtr writer,
2671 const xmlChar * name,
2672 const xmlChar * pubid, const xmlChar * sysid)
2673{
2674 int count;
2675 int sum;
2676 xmlLinkPtr lk;
2677 xmlTextWriterStackEntry *p;
2678
2679 if (writer == NULL || name == NULL || *name == '\0')
2680 return -1;
2681
2682 sum = 0;
2683 lk = xmlListFront(writer->nodes);
Daniel Veillardab69f362004-02-17 11:40:32 +00002684 if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) {
Daniel Veillard1d211e22003-10-20 22:32:39 +00002685 xmlGenericError(xmlGenericErrorContext,
2686 "xmlTextWriterStartDTD : DTD allowed only in prolog!\n");
2687 return -1;
2688 }
2689
2690 p = (xmlTextWriterStackEntry *)
2691 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2692 if (p == 0) {
2693 xmlGenericError(xmlGenericErrorContext,
2694 "xmlTextWriterStartDTD : out of memory!\n");
2695 return -1;
2696 }
2697
2698 p->name = xmlStrdup(name);
2699 if (p->name == 0) {
2700 xmlGenericError(xmlGenericErrorContext,
2701 "xmlTextWriterStartDTD : out of memory!\n");
2702 xmlFree(p);
2703 return -1;
2704 }
2705 p->state = XML_TEXTWRITER_DTD;
2706
2707 xmlListPushFront(writer->nodes, p);
2708
2709 count = xmlOutputBufferWriteString(writer->out, "<!DOCTYPE ");
2710 if (count < 0)
2711 return -1;
2712 sum += count;
2713 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
2714 if (count < 0)
2715 return -1;
2716 sum += count;
2717
2718 if (pubid != 0) {
2719 if (sysid == 0) {
2720 xmlGenericError(xmlGenericErrorContext,
2721 "xmlTextWriterStartDTD : system identifier needed!\n");
2722 return -1;
2723 }
2724
Daniel Veillard500a1de2004-03-22 15:22:58 +00002725 if (writer->indent)
2726 count = xmlOutputBufferWrite(writer->out, 1, "\n");
2727 else
2728 count = xmlOutputBufferWrite(writer->out, 1, " ");
2729 if (count < 0)
2730 return -1;
2731 sum += count;
2732
2733 count = xmlOutputBufferWriteString(writer->out, "PUBLIC ");
2734 if (count < 0)
2735 return -1;
2736 sum += count;
2737
2738 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002739 if (count < 0)
2740 return -1;
2741 sum += count;
2742
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002743 count =
2744 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002745 if (count < 0)
2746 return -1;
2747 sum += count;
2748
Daniel Veillard500a1de2004-03-22 15:22:58 +00002749 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002750 if (count < 0)
2751 return -1;
2752 sum += count;
2753 }
2754
2755 if (sysid != 0) {
2756 if (pubid == 0) {
Daniel Veillard500a1de2004-03-22 15:22:58 +00002757 if (writer->indent)
2758 count = xmlOutputBufferWrite(writer->out, 1, "\n");
2759 else
2760 count = xmlOutputBufferWrite(writer->out, 1, " ");
2761 if (count < 0)
2762 return -1;
2763 sum += count;
2764 count = xmlOutputBufferWriteString(writer->out, "SYSTEM ");
2765 if (count < 0)
2766 return -1;
2767 sum += count;
2768 } else if (writer->indent) {
2769 count = xmlOutputBufferWriteString(writer->out, "\n ");
Daniel Veillard1d211e22003-10-20 22:32:39 +00002770 if (count < 0)
2771 return -1;
2772 sum += count;
2773 }
2774
Daniel Veillard500a1de2004-03-22 15:22:58 +00002775 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002776 if (count < 0)
2777 return -1;
2778 sum += count;
2779
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002780 count =
2781 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002782 if (count < 0)
2783 return -1;
2784 sum += count;
2785
Daniel Veillard500a1de2004-03-22 15:22:58 +00002786 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002787 if (count < 0)
2788 return -1;
2789 sum += count;
2790 }
2791
2792 return sum;
2793}
2794
2795/**
2796 * xmlTextWriterEndDTD:
2797 * @writer: the xmlTextWriterPtr
2798 *
2799 * End an xml DTD.
2800 *
2801 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2802 */
2803int
2804xmlTextWriterEndDTD(xmlTextWriterPtr writer)
2805{
Daniel Veillard500a1de2004-03-22 15:22:58 +00002806 int loop;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002807 int count;
2808 int sum;
2809 xmlLinkPtr lk;
2810 xmlTextWriterStackEntry *p;
2811
2812 if (writer == NULL)
2813 return -1;
2814
2815 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00002816 loop = 1;
2817 while (loop) {
2818 lk = xmlListFront(writer->nodes);
2819 if (lk == NULL)
Daniel Veillard1d211e22003-10-20 22:32:39 +00002820 break;
Daniel Veillard500a1de2004-03-22 15:22:58 +00002821 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2822 if (p == 0)
2823 break;
2824 switch (p->state) {
2825 case XML_TEXTWRITER_DTD_TEXT:
2826 count = xmlOutputBufferWriteString(writer->out, "]");
2827 if (count < 0)
2828 return -1;
2829 sum += count;
2830 /* fallthrough */
2831 case XML_TEXTWRITER_DTD:
2832 count = xmlOutputBufferWriteString(writer->out, ">");
2833
2834 if (writer->indent) {
2835 if (count < 0)
2836 return -1;
2837 sum += count;
2838 count = xmlOutputBufferWriteString(writer->out, "\n");
2839 }
2840
2841 xmlListPopFront(writer->nodes);
2842 break;
2843 case XML_TEXTWRITER_DTD_ELEM:
2844 case XML_TEXTWRITER_DTD_ELEM_TEXT:
2845 count = xmlTextWriterEndDTDElement(writer);
2846 break;
2847 case XML_TEXTWRITER_DTD_ATTL:
2848 case XML_TEXTWRITER_DTD_ATTL_TEXT:
2849 count = xmlTextWriterEndDTDAttlist(writer);
2850 break;
2851 case XML_TEXTWRITER_DTD_ENTY:
2852 case XML_TEXTWRITER_DTD_PENT:
2853 case XML_TEXTWRITER_DTD_ENTY_TEXT:
2854 count = xmlTextWriterEndDTDEntity(writer);
2855 break;
2856 case XML_TEXTWRITER_COMMENT:
2857 count = xmlTextWriterEndComment(writer);
2858 break;
2859 default:
2860 loop = 0;
2861 continue;
2862 }
2863
2864 if (count < 0)
Daniel Veillard1d211e22003-10-20 22:32:39 +00002865 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00002866 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002867 }
2868
Daniel Veillard1d211e22003-10-20 22:32:39 +00002869 return sum;
2870}
2871
2872/**
2873 * xmlTextWriterWriteFormatDTD:
2874 * @writer: the xmlTextWriterPtr
2875 * @name: the name of the DTD
2876 * @pubid: the public identifier, which is an alternative to the system identifier
2877 * @sysid: the system identifier, which is the URI of the DTD
2878 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002879 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002880 *
2881 * Write a DTD with a formatted markup declarations part.
2882 *
2883 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2884 */
2885int
2886xmlTextWriterWriteFormatDTD(xmlTextWriterPtr writer,
2887 const xmlChar * name,
2888 const xmlChar * pubid,
2889 const xmlChar * sysid, const char *format, ...)
2890{
2891 int rc;
2892 va_list ap;
2893
2894 va_start(ap, format);
2895
2896 rc = xmlTextWriterWriteVFormatDTD(writer, name, pubid, sysid, format,
2897 ap);
2898
2899 va_end(ap);
2900 return rc;
2901}
2902
2903/**
2904 * xmlTextWriterWriteVFormatDTD:
2905 * @writer: the xmlTextWriterPtr
2906 * @name: the name of the DTD
2907 * @pubid: the public identifier, which is an alternative to the system identifier
2908 * @sysid: the system identifier, which is the URI of the DTD
2909 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002910 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00002911 *
2912 * Write a DTD with a formatted markup declarations part.
2913 *
2914 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2915 */
2916int
2917xmlTextWriterWriteVFormatDTD(xmlTextWriterPtr writer,
2918 const xmlChar * name,
2919 const xmlChar * pubid,
2920 const xmlChar * sysid,
2921 const char *format, va_list argptr)
2922{
2923 int rc;
2924 xmlChar *buf;
2925
2926 if (writer == NULL)
2927 return -1;
2928
2929 buf = xmlTextWriterVSprintf(format, argptr);
2930 if (buf == 0)
2931 return 0;
2932
2933 rc = xmlTextWriterWriteDTD(writer, name, pubid, sysid, buf);
2934
2935 xmlFree(buf);
2936 return rc;
2937}
2938
2939/**
2940 * xmlTextWriterWriteDTD:
2941 * @writer: the xmlTextWriterPtr
2942 * @name: the name of the DTD
2943 * @pubid: the public identifier, which is an alternative to the system identifier
2944 * @sysid: the system identifier, which is the URI of the DTD
William M. Brackb1d53162003-11-18 06:54:40 +00002945 * @subset: string content of the DTD
Daniel Veillard1d211e22003-10-20 22:32:39 +00002946 *
2947 * Write a DTD.
2948 *
2949 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2950 */
2951int
2952xmlTextWriterWriteDTD(xmlTextWriterPtr writer,
2953 const xmlChar * name,
2954 const xmlChar * pubid,
2955 const xmlChar * sysid, const xmlChar * subset)
2956{
2957 int count;
2958 int sum;
2959
2960 sum = 0;
2961 count = xmlTextWriterStartDTD(writer, name, pubid, sysid);
2962 if (count == -1)
2963 return -1;
2964 sum += count;
2965 if (subset != 0) {
2966 count = xmlTextWriterWriteString(writer, subset);
2967 if (count == -1)
2968 return -1;
2969 sum += count;
2970 }
2971 count = xmlTextWriterEndDTD(writer);
2972 if (count == -1)
2973 return -1;
2974 sum += count;
2975
2976 return sum;
2977}
2978
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002979/**
2980 * xmlTextWriterStartDTDElement:
2981 * @writer: the xmlTextWriterPtr
2982 * @name: the name of the DTD element
2983 *
2984 * Start an xml DTD element.
2985 *
2986 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2987 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00002988int
2989xmlTextWriterStartDTDElement(xmlTextWriterPtr writer, const xmlChar * name)
2990{
2991 int count;
2992 int sum;
2993 xmlLinkPtr lk;
2994 xmlTextWriterStackEntry *p;
2995
2996 if (writer == NULL || name == NULL || *name == '\0')
2997 return -1;
2998
2999 sum = 0;
3000 lk = xmlListFront(writer->nodes);
3001 if (lk == 0) {
3002 return -1;
3003 }
3004
3005 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
Daniel Veillard500a1de2004-03-22 15:22:58 +00003006 if (p != 0) {
3007 switch (p->state) {
3008 case XML_TEXTWRITER_DTD:
3009 count = xmlOutputBufferWriteString(writer->out, " [");
3010 if (count < 0)
3011 return -1;
3012 sum += count;
3013 if (writer->indent) {
3014 count = xmlOutputBufferWriteString(writer->out, "\n");
3015 if (count < 0)
3016 return -1;
3017 sum += count;
3018 }
3019 p->state = XML_TEXTWRITER_DTD_TEXT;
3020 /* fallthrough */
3021 case XML_TEXTWRITER_DTD_TEXT:
3022 case XML_TEXTWRITER_NONE:
3023 break;
3024 default:
Daniel Veillard1d211e22003-10-20 22:32:39 +00003025 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00003026 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00003027 }
3028
3029 p = (xmlTextWriterStackEntry *)
3030 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3031 if (p == 0) {
3032 xmlGenericError(xmlGenericErrorContext,
3033 "xmlTextWriterStartDTDElement : out of memory!\n");
3034 return -1;
3035 }
3036
3037 p->name = xmlStrdup(name);
3038 if (p->name == 0) {
3039 xmlGenericError(xmlGenericErrorContext,
3040 "xmlTextWriterStartDTDElement : out of memory!\n");
3041 xmlFree(p);
3042 return -1;
3043 }
3044 p->state = XML_TEXTWRITER_DTD_ELEM;
3045
3046 xmlListPushFront(writer->nodes, p);
3047
Daniel Veillard500a1de2004-03-22 15:22:58 +00003048 if (writer->indent) {
3049 count = xmlTextWriterWriteIndent(writer);
3050 if (count < 0)
3051 return -1;
3052 sum += count;
3053 }
3054
Daniel Veillard1d211e22003-10-20 22:32:39 +00003055 count = xmlOutputBufferWriteString(writer->out, "<!ELEMENT ");
3056 if (count < 0)
3057 return -1;
3058 sum += count;
3059 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
3060 if (count < 0)
3061 return -1;
3062 sum += count;
3063
3064 return sum;
3065}
3066
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003067/**
Daniel Veillard500a1de2004-03-22 15:22:58 +00003068 * xmlTextWriterEndDTDElement:
3069 * @writer: the xmlTextWriterPtr
3070 *
3071 * End an xml DTD element.
3072 *
3073 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3074 */
3075int
3076xmlTextWriterEndDTDElement(xmlTextWriterPtr writer)
3077{
3078 int count;
3079 int sum;
3080 xmlLinkPtr lk;
3081 xmlTextWriterStackEntry *p;
3082
3083 if (writer == NULL)
3084 return -1;
3085
3086 sum = 0;
3087 lk = xmlListFront(writer->nodes);
3088 if (lk == 0)
3089 return -1;
3090
3091 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3092 if (p == 0)
3093 return -1;
3094
3095 switch (p->state) {
3096 case XML_TEXTWRITER_DTD_ELEM:
3097 case XML_TEXTWRITER_DTD_ELEM_TEXT:
3098 count = xmlOutputBufferWriteString(writer->out, ">");
3099 if (count < 0)
3100 return -1;
3101 sum += count;
3102 break;
3103 default:
3104 return -1;
3105 }
3106
3107 if (writer->indent) {
3108 count = xmlOutputBufferWriteString(writer->out, "\n");
3109 if (count < 0)
3110 return -1;
3111 sum += count;
3112 }
3113
3114 xmlListPopFront(writer->nodes);
3115 return sum;
3116}
3117
3118/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003119 * xmlTextWriterWriteFormatDTDElement:
3120 * @writer: the xmlTextWriterPtr
3121 * @name: the name of the DTD element
3122 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003123 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003124 *
3125 * Write a formatted DTD element.
3126 *
3127 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3128 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003129int
3130xmlTextWriterWriteFormatDTDElement(xmlTextWriterPtr writer,
3131 const xmlChar * name,
3132 const char *format, ...)
3133{
3134 int rc;
3135 va_list ap;
3136
3137 va_start(ap, format);
3138
3139 rc = xmlTextWriterWriteVFormatDTDElement(writer, name, format, ap);
3140
3141 va_end(ap);
3142 return rc;
3143}
3144
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003145/**
3146 * xmlTextWriterWriteVFormatDTDElement:
3147 * @writer: the xmlTextWriterPtr
3148 * @name: the name of the DTD element
3149 * @format: format string (see printf)
3150 * @argptr: pointer to the first member of the variable argument list.
3151 *
3152 * Write a formatted DTD element.
3153 *
3154 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3155 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003156int
3157xmlTextWriterWriteVFormatDTDElement(xmlTextWriterPtr writer,
3158 const xmlChar * name,
3159 const char *format, va_list argptr)
3160{
3161 int rc;
3162 xmlChar *buf;
3163
3164 if (writer == NULL)
3165 return -1;
3166
3167 buf = xmlTextWriterVSprintf(format, argptr);
3168 if (buf == 0)
3169 return 0;
3170
3171 rc = xmlTextWriterWriteDTDElement(writer, name, buf);
3172
3173 xmlFree(buf);
3174 return rc;
3175}
3176
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003177/**
3178 * xmlTextWriterWriteDTDElement:
3179 * @writer: the xmlTextWriterPtr
3180 * @name: the name of the DTD element
3181 * @content: content of the element
3182 *
3183 * Write a DTD element.
3184 *
3185 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3186 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003187int
3188xmlTextWriterWriteDTDElement(xmlTextWriterPtr writer,
3189 const xmlChar * name, const xmlChar * content)
3190{
3191 int count;
3192 int sum;
3193
3194 if (content == NULL)
3195 return -1;
3196
3197 sum = 0;
3198 count = xmlTextWriterStartDTDElement(writer, name);
3199 if (count == -1)
3200 return -1;
3201 sum += count;
3202
Daniel Veillard1d211e22003-10-20 22:32:39 +00003203 count = xmlTextWriterWriteString(writer, content);
3204 if (count == -1)
3205 return -1;
3206 sum += count;
3207
3208 count = xmlTextWriterEndDTDElement(writer);
3209 if (count == -1)
3210 return -1;
3211 sum += count;
3212
3213 return sum;
3214}
3215
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003216/**
3217 * xmlTextWriterStartDTDAttlist:
3218 * @writer: the xmlTextWriterPtr
3219 * @name: the name of the DTD ATTLIST
3220 *
3221 * Start an xml DTD ATTLIST.
3222 *
3223 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3224 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003225int
3226xmlTextWriterStartDTDAttlist(xmlTextWriterPtr writer, const xmlChar * name)
3227{
3228 int count;
3229 int sum;
3230 xmlLinkPtr lk;
3231 xmlTextWriterStackEntry *p;
3232
3233 if (writer == NULL || name == NULL || *name == '\0')
3234 return -1;
3235
3236 sum = 0;
3237 lk = xmlListFront(writer->nodes);
3238 if (lk == 0) {
3239 return -1;
3240 }
3241
3242 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
Daniel Veillard500a1de2004-03-22 15:22:58 +00003243 if (p != 0) {
3244 switch (p->state) {
3245 case XML_TEXTWRITER_DTD:
3246 count = xmlOutputBufferWriteString(writer->out, " [");
3247 if (count < 0)
3248 return -1;
3249 sum += count;
3250 if (writer->indent) {
3251 count = xmlOutputBufferWriteString(writer->out, "\n");
3252 if (count < 0)
3253 return -1;
3254 sum += count;
3255 }
3256 p->state = XML_TEXTWRITER_DTD_TEXT;
3257 /* fallthrough */
3258 case XML_TEXTWRITER_DTD_TEXT:
3259 case XML_TEXTWRITER_NONE:
3260 break;
3261 default:
Daniel Veillard1d211e22003-10-20 22:32:39 +00003262 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00003263 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00003264 }
3265
3266 p = (xmlTextWriterStackEntry *)
3267 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3268 if (p == 0) {
3269 xmlGenericError(xmlGenericErrorContext,
3270 "xmlTextWriterStartDTDAttlist : out of memory!\n");
3271 return -1;
3272 }
3273
3274 p->name = xmlStrdup(name);
3275 if (p->name == 0) {
3276 xmlGenericError(xmlGenericErrorContext,
3277 "xmlTextWriterStartDTDAttlist : out of memory!\n");
3278 xmlFree(p);
3279 return -1;
3280 }
3281 p->state = XML_TEXTWRITER_DTD_ATTL;
3282
3283 xmlListPushFront(writer->nodes, p);
3284
Daniel Veillard500a1de2004-03-22 15:22:58 +00003285 if (writer->indent) {
3286 count = xmlTextWriterWriteIndent(writer);
3287 if (count < 0)
3288 return -1;
3289 sum += count;
3290 }
3291
Daniel Veillard1d211e22003-10-20 22:32:39 +00003292 count = xmlOutputBufferWriteString(writer->out, "<!ATTLIST ");
3293 if (count < 0)
3294 return -1;
3295 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +00003296 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003297 if (count < 0)
3298 return -1;
3299 sum += count;
3300
3301 return sum;
3302}
3303
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003304/**
Daniel Veillard500a1de2004-03-22 15:22:58 +00003305 * xmlTextWriterEndDTDAttlist:
3306 * @writer: the xmlTextWriterPtr
3307 *
3308 * End an xml DTD attribute list.
3309 *
3310 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3311 */
3312int
3313xmlTextWriterEndDTDAttlist(xmlTextWriterPtr writer)
3314{
3315 int count;
3316 int sum;
3317 xmlLinkPtr lk;
3318 xmlTextWriterStackEntry *p;
3319
3320 if (writer == NULL)
3321 return -1;
3322
3323 sum = 0;
3324 lk = xmlListFront(writer->nodes);
3325 if (lk == 0)
3326 return -1;
3327
3328 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3329 if (p == 0)
3330 return -1;
3331
3332 switch (p->state) {
3333 case XML_TEXTWRITER_DTD_ATTL:
3334 case XML_TEXTWRITER_DTD_ATTL_TEXT:
3335 count = xmlOutputBufferWriteString(writer->out, ">");
3336 if (count < 0)
3337 return -1;
3338 sum += count;
3339 break;
3340 default:
3341 return -1;
3342 }
3343
3344 if (writer->indent) {
3345 count = xmlOutputBufferWriteString(writer->out, "\n");
3346 if (count < 0)
3347 return -1;
3348 sum += count;
3349 }
3350
3351 xmlListPopFront(writer->nodes);
3352 return sum;
3353}
3354
3355/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003356 * xmlTextWriterWriteFormatDTDAttlist:
3357 * @writer: the xmlTextWriterPtr
3358 * @name: the name of the DTD ATTLIST
3359 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003360 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003361 *
3362 * Write a formatted DTD ATTLIST.
3363 *
3364 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3365 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003366int
3367xmlTextWriterWriteFormatDTDAttlist(xmlTextWriterPtr writer,
3368 const xmlChar * name,
3369 const char *format, ...)
3370{
3371 int rc;
3372 va_list ap;
3373
3374 va_start(ap, format);
3375
3376 rc = xmlTextWriterWriteVFormatDTDAttlist(writer, name, format, ap);
3377
3378 va_end(ap);
3379 return rc;
3380}
3381
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003382/**
3383 * xmlTextWriterWriteVFormatDTDAttlist:
3384 * @writer: the xmlTextWriterPtr
3385 * @name: the name of the DTD ATTLIST
3386 * @format: format string (see printf)
3387 * @argptr: pointer to the first member of the variable argument list.
3388 *
3389 * Write a formatted DTD ATTLIST.
3390 *
3391 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3392 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003393int
3394xmlTextWriterWriteVFormatDTDAttlist(xmlTextWriterPtr writer,
3395 const xmlChar * name,
3396 const char *format, va_list argptr)
3397{
3398 int rc;
3399 xmlChar *buf;
3400
3401 if (writer == NULL)
3402 return -1;
3403
3404 buf = xmlTextWriterVSprintf(format, argptr);
3405 if (buf == 0)
3406 return 0;
3407
3408 rc = xmlTextWriterWriteDTDAttlist(writer, name, buf);
3409
3410 xmlFree(buf);
3411 return rc;
3412}
3413
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003414/**
3415 * xmlTextWriterWriteDTDAttlist:
3416 * @writer: the xmlTextWriterPtr
3417 * @name: the name of the DTD ATTLIST
3418 * @content: content of the ATTLIST
3419 *
3420 * Write a DTD ATTLIST.
3421 *
3422 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3423 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003424int
3425xmlTextWriterWriteDTDAttlist(xmlTextWriterPtr writer,
3426 const xmlChar * name, const xmlChar * content)
3427{
3428 int count;
3429 int sum;
3430
3431 if (content == NULL)
3432 return -1;
3433
3434 sum = 0;
3435 count = xmlTextWriterStartDTDAttlist(writer, name);
3436 if (count == -1)
3437 return -1;
3438 sum += count;
3439
Daniel Veillard1d211e22003-10-20 22:32:39 +00003440 count = xmlTextWriterWriteString(writer, content);
3441 if (count == -1)
3442 return -1;
3443 sum += count;
3444
3445 count = xmlTextWriterEndDTDAttlist(writer);
3446 if (count == -1)
3447 return -1;
3448 sum += count;
3449
3450 return sum;
3451}
3452
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003453/**
3454 * xmlTextWriterStartDTDEntity:
3455 * @writer: the xmlTextWriterPtr
3456 * @pe: TRUE if this is a parameter entity, FALSE if not
3457 * @name: the name of the DTD ATTLIST
3458 *
3459 * Start an xml DTD ATTLIST.
3460 *
3461 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3462 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003463int
3464xmlTextWriterStartDTDEntity(xmlTextWriterPtr writer,
3465 int pe, const xmlChar * name)
3466{
3467 int count;
3468 int sum;
3469 xmlLinkPtr lk;
3470 xmlTextWriterStackEntry *p;
3471
3472 if (writer == NULL || name == NULL || *name == '\0')
3473 return -1;
3474
3475 sum = 0;
3476 lk = xmlListFront(writer->nodes);
Daniel Veillard500a1de2004-03-22 15:22:58 +00003477 if (lk != 0) {
Daniel Veillard1d211e22003-10-20 22:32:39 +00003478
Daniel Veillard500a1de2004-03-22 15:22:58 +00003479 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3480 if (p != 0) {
3481 switch (p->state) {
3482 case XML_TEXTWRITER_DTD:
3483 count = xmlOutputBufferWriteString(writer->out, " [");
3484 if (count < 0)
3485 return -1;
3486 sum += count;
3487 if (writer->indent) {
3488 count =
3489 xmlOutputBufferWriteString(writer->out, "\n");
3490 if (count < 0)
3491 return -1;
3492 sum += count;
3493 }
3494 p->state = XML_TEXTWRITER_DTD_TEXT;
3495 /* fallthrough */
3496 case XML_TEXTWRITER_DTD_TEXT:
3497 case XML_TEXTWRITER_NONE:
3498 break;
3499 default:
3500 return -1;
3501 }
3502 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00003503 }
3504
3505 p = (xmlTextWriterStackEntry *)
3506 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3507 if (p == 0) {
3508 xmlGenericError(xmlGenericErrorContext,
3509 "xmlTextWriterStartDTDElement : out of memory!\n");
3510 return -1;
3511 }
3512
3513 p->name = xmlStrdup(name);
3514 if (p->name == 0) {
3515 xmlGenericError(xmlGenericErrorContext,
3516 "xmlTextWriterStartDTDElement : out of memory!\n");
3517 xmlFree(p);
3518 return -1;
3519 }
Daniel Veillard500a1de2004-03-22 15:22:58 +00003520
3521 if (pe != 0)
3522 p->state = XML_TEXTWRITER_DTD_PENT;
3523 else
3524 p->state = XML_TEXTWRITER_DTD_ENTY;
Daniel Veillard1d211e22003-10-20 22:32:39 +00003525
3526 xmlListPushFront(writer->nodes, p);
3527
Daniel Veillard500a1de2004-03-22 15:22:58 +00003528 if (writer->indent) {
3529 count = xmlTextWriterWriteIndent(writer);
3530 if (count < 0)
3531 return -1;
3532 sum += count;
3533 }
3534
Daniel Veillard1d211e22003-10-20 22:32:39 +00003535 count = xmlOutputBufferWriteString(writer->out, "<!ENTITY ");
3536 if (count < 0)
3537 return -1;
3538 sum += count;
3539
3540 if (pe != 0) {
Daniel Veillard500a1de2004-03-22 15:22:58 +00003541 count = xmlOutputBufferWriteString(writer->out, "% ");
Daniel Veillard1d211e22003-10-20 22:32:39 +00003542 if (count < 0)
3543 return -1;
3544 sum += count;
3545 }
3546
Daniel Veillardab69f362004-02-17 11:40:32 +00003547 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003548 if (count < 0)
3549 return -1;
3550 sum += count;
3551
3552 return sum;
3553}
3554
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003555/**
Daniel Veillard500a1de2004-03-22 15:22:58 +00003556 * xmlTextWriterEndDTDEntity:
3557 * @writer: the xmlTextWriterPtr
3558 *
3559 * End an xml DTD entity.
3560 *
3561 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3562 */
3563int
3564xmlTextWriterEndDTDEntity(xmlTextWriterPtr writer)
3565{
3566 int count;
3567 int sum;
3568 xmlLinkPtr lk;
3569 xmlTextWriterStackEntry *p;
3570
3571 if (writer == NULL)
3572 return -1;
3573
3574 sum = 0;
3575 lk = xmlListFront(writer->nodes);
3576 if (lk == 0)
3577 return -1;
3578
3579 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3580 if (p == 0)
3581 return -1;
3582
3583 switch (p->state) {
3584 case XML_TEXTWRITER_DTD_ENTY_TEXT:
3585 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3586 if (count < 0)
3587 return -1;
3588 sum += count;
3589 case XML_TEXTWRITER_DTD_ENTY:
3590 case XML_TEXTWRITER_DTD_PENT:
Daniel Veillard500a1de2004-03-22 15:22:58 +00003591 count = xmlOutputBufferWriteString(writer->out, ">");
3592 if (count < 0)
3593 return -1;
3594 sum += count;
3595 break;
3596 default:
3597 return -1;
3598 }
3599
3600 if (writer->indent) {
3601 count = xmlOutputBufferWriteString(writer->out, "\n");
3602 if (count < 0)
3603 return -1;
3604 sum += count;
3605 }
3606
3607 xmlListPopFront(writer->nodes);
3608 return sum;
3609}
3610
3611/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003612 * xmlTextWriterWriteFormatDTDInternalEntity:
3613 * @writer: the xmlTextWriterPtr
3614 * @pe: TRUE if this is a parameter entity, FALSE if not
3615 * @name: the name of the DTD entity
3616 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003617 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003618 *
3619 * Write a formatted DTD internal entity.
3620 *
3621 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3622 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003623int
3624xmlTextWriterWriteFormatDTDInternalEntity(xmlTextWriterPtr writer,
3625 int pe,
3626 const xmlChar * name,
3627 const char *format, ...)
3628{
3629 int rc;
3630 va_list ap;
3631
3632 va_start(ap, format);
3633
3634 rc = xmlTextWriterWriteVFormatDTDInternalEntity(writer, pe, name,
3635 format, ap);
3636
3637 va_end(ap);
3638 return rc;
3639}
3640
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003641/**
3642 * xmlTextWriterWriteVFormatDTDInternalEntity:
3643 * @writer: the xmlTextWriterPtr
3644 * @pe: TRUE if this is a parameter entity, FALSE if not
3645 * @name: the name of the DTD entity
3646 * @format: format string (see printf)
3647 * @argptr: pointer to the first member of the variable argument list.
3648 *
3649 * Write a formatted DTD internal entity.
3650 *
3651 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3652 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003653int
3654xmlTextWriterWriteVFormatDTDInternalEntity(xmlTextWriterPtr writer,
3655 int pe,
3656 const xmlChar * name,
3657 const char *format,
3658 va_list argptr)
3659{
3660 int rc;
3661 xmlChar *buf;
3662
3663 if (writer == NULL)
3664 return -1;
3665
3666 buf = xmlTextWriterVSprintf(format, argptr);
3667 if (buf == 0)
3668 return 0;
3669
3670 rc = xmlTextWriterWriteDTDInternalEntity(writer, pe, name, buf);
3671
3672 xmlFree(buf);
3673 return rc;
3674}
3675
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003676/**
3677 * xmlTextWriterWriteDTDEntity:
3678 * @writer: the xmlTextWriterPtr
3679 * @pe: TRUE if this is a parameter entity, FALSE if not
3680 * @name: the name of the DTD entity
3681 * @pubid: the public identifier, which is an alternative to the system identifier
3682 * @sysid: the system identifier, which is the URI of the DTD
3683 * @ndataid: the xml notation name.
3684 * @content: content of the entity
3685 *
3686 * Write a DTD entity.
3687 *
3688 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3689 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003690int
3691xmlTextWriterWriteDTDEntity(xmlTextWriterPtr writer,
3692 int pe,
3693 const xmlChar * name,
3694 const xmlChar * pubid,
3695 const xmlChar * sysid,
3696 const xmlChar * ndataid,
3697 const xmlChar * content)
3698{
Daniel Veillard500a1de2004-03-22 15:22:58 +00003699 if ((content == NULL) && (pubid == NULL) && (sysid == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00003700 return -1;
3701 if ((pe != 0) && (ndataid != NULL))
3702 return -1;
3703
Daniel Veillard500a1de2004-03-22 15:22:58 +00003704 if ((pubid == NULL) && (sysid == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00003705 return xmlTextWriterWriteDTDInternalEntity(writer, pe, name,
3706 content);
3707
3708 return xmlTextWriterWriteDTDExternalEntity(writer, pe, name, pubid,
3709 sysid, ndataid);
3710}
3711
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003712/**
3713 * xmlTextWriterWriteDTDInternalEntity:
3714 * @writer: the xmlTextWriterPtr
3715 * @pe: TRUE if this is a parameter entity, FALSE if not
3716 * @name: the name of the DTD entity
3717 * @content: content of the entity
3718 *
3719 * Write a DTD internal entity.
3720 *
3721 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3722 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003723int
3724xmlTextWriterWriteDTDInternalEntity(xmlTextWriterPtr writer,
3725 int pe,
3726 const xmlChar * name,
3727 const xmlChar * content)
3728{
3729 int count;
3730 int sum;
3731
3732 if ((name == NULL) || (*name == '\0') || (content == NULL))
3733 return -1;
3734
3735 sum = 0;
3736 count = xmlTextWriterStartDTDEntity(writer, pe, name);
3737 if (count == -1)
3738 return -1;
3739 sum += count;
3740
Daniel Veillard1d211e22003-10-20 22:32:39 +00003741 count = xmlTextWriterWriteString(writer, content);
3742 if (count == -1)
3743 return -1;
3744 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00003745
3746 count = xmlTextWriterEndDTDEntity(writer);
3747 if (count == -1)
3748 return -1;
3749 sum += count;
3750
3751 return sum;
3752}
3753
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003754/**
3755 * xmlTextWriterWriteDTDExternalEntity:
3756 * @writer: the xmlTextWriterPtr
3757 * @pe: TRUE if this is a parameter entity, FALSE if not
3758 * @name: the name of the DTD entity
3759 * @pubid: the public identifier, which is an alternative to the system identifier
3760 * @sysid: the system identifier, which is the URI of the DTD
3761 * @ndataid: the xml notation name.
3762 *
Daniel Veillard500a1de2004-03-22 15:22:58 +00003763 * Write a DTD external entity. The entity must have been started with xmlTextWriterStartDTDEntity
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003764 *
3765 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3766 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003767int
3768xmlTextWriterWriteDTDExternalEntity(xmlTextWriterPtr writer,
3769 int pe,
3770 const xmlChar * name,
3771 const xmlChar * pubid,
3772 const xmlChar * sysid,
3773 const xmlChar * ndataid)
3774{
3775 int count;
3776 int sum;
3777
Daniel Veillard500a1de2004-03-22 15:22:58 +00003778 if (((pubid == NULL) && (sysid == NULL)))
Daniel Veillard1d211e22003-10-20 22:32:39 +00003779 return -1;
3780 if ((pe != 0) && (ndataid != NULL))
3781 return -1;
3782
3783 sum = 0;
3784 count = xmlTextWriterStartDTDEntity(writer, pe, name);
3785 if (count == -1)
3786 return -1;
3787 sum += count;
3788
Daniel Veillard500a1de2004-03-22 15:22:58 +00003789 count =
3790 xmlTextWriterWriteDTDExternalEntityContents(writer, pubid, sysid,
3791 ndataid);
3792 if (count < 0)
3793 return -1;
3794 sum += count;
3795
3796 count = xmlTextWriterEndDTDEntity(writer);
3797 if (count == -1)
3798 return -1;
3799 sum += count;
3800
3801 return sum;
3802}
3803
3804/**
3805 * xmlTextWriterWriteDTDExternalEntityContents:
3806 * @writer: the xmlTextWriterPtr
3807 * @pubid: the public identifier, which is an alternative to the system identifier
3808 * @sysid: the system identifier, which is the URI of the DTD
3809 * @ndataid: the xml notation name.
3810 *
3811 * Write the contents of a DTD external entity.
3812 *
3813 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3814 */
3815int
3816xmlTextWriterWriteDTDExternalEntityContents(xmlTextWriterPtr writer,
3817 const xmlChar * pubid,
3818 const xmlChar * sysid,
3819 const xmlChar * ndataid)
3820{
3821 int count;
3822 int sum;
3823 xmlLinkPtr lk;
3824 xmlTextWriterStackEntry *p;
3825
3826 if (writer == NULL) {
3827 xmlGenericError(xmlGenericErrorContext,
3828 "xmlTextWriterWriteDTDExternalEntityContents: xmlTextWriterPtr invalid!\n");
3829 return -1;
3830 }
3831
3832 sum = 0;
3833 lk = xmlListFront(writer->nodes);
3834 if (lk == 0) {
3835 xmlGenericError(xmlGenericErrorContext,
3836 "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n");
3837 return -1;
3838 }
3839
3840 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3841 if (p == 0)
3842 return -1;
3843
3844 switch (p->state) {
3845 case XML_TEXTWRITER_DTD_ENTY:
3846 break;
3847 case XML_TEXTWRITER_DTD_PENT:
3848 if (ndataid != NULL) {
3849 xmlGenericError(xmlGenericErrorContext,
3850 "xmlTextWriterWriteDTDExternalEntityContents: notation not allowed with parameter entities!\n");
3851 return -1;
3852 }
3853 break;
3854 default:
3855 xmlGenericError(xmlGenericErrorContext,
3856 "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n");
3857 return -1;
3858 }
3859
Daniel Veillard1d211e22003-10-20 22:32:39 +00003860 if (pubid != 0) {
3861 if (sysid == 0) {
3862 xmlGenericError(xmlGenericErrorContext,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003863 "xmlTextWriterWriteDTDExternalEntityContents: system identifier needed!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +00003864 return -1;
3865 }
3866
3867 count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
3868 if (count < 0)
3869 return -1;
3870 sum += count;
3871
3872 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3873 if (count < 0)
3874 return -1;
3875 sum += count;
3876
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003877 count =
3878 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003879 if (count < 0)
3880 return -1;
3881 sum += count;
3882
3883 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3884 if (count < 0)
3885 return -1;
3886 sum += count;
3887 }
3888
3889 if (sysid != 0) {
3890 if (pubid == 0) {
3891 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
3892 if (count < 0)
3893 return -1;
3894 sum += count;
3895 }
3896
3897 count = xmlOutputBufferWriteString(writer->out, " ");
3898 if (count < 0)
3899 return -1;
3900 sum += count;
3901
3902 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3903 if (count < 0)
3904 return -1;
3905 sum += count;
3906
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003907 count =
3908 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003909 if (count < 0)
3910 return -1;
3911 sum += count;
3912
3913 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3914 if (count < 0)
3915 return -1;
3916 sum += count;
3917 }
3918
3919 if (ndataid != NULL) {
3920 count = xmlOutputBufferWriteString(writer->out, " NDATA ");
3921 if (count < 0)
3922 return -1;
3923 sum += count;
3924
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003925 count =
3926 xmlOutputBufferWriteString(writer->out,
3927 (const char *) ndataid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003928 if (count < 0)
3929 return -1;
3930 sum += count;
3931 }
3932
Daniel Veillard1d211e22003-10-20 22:32:39 +00003933 return sum;
3934}
3935
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003936/**
3937 * xmlTextWriterWriteDTDNotation:
3938 * @writer: the xmlTextWriterPtr
3939 * @name: the name of the xml notation
3940 * @pubid: the public identifier, which is an alternative to the system identifier
3941 * @sysid: the system identifier, which is the URI of the DTD
3942 *
3943 * Write a DTD entity.
3944 *
3945 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3946 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003947int
3948xmlTextWriterWriteDTDNotation(xmlTextWriterPtr writer,
3949 const xmlChar * name,
3950 const xmlChar * pubid, const xmlChar * sysid)
3951{
3952 int count;
3953 int sum;
3954 xmlLinkPtr lk;
3955 xmlTextWriterStackEntry *p;
3956
3957 if (writer == NULL || name == NULL || *name == '\0')
3958 return -1;
3959
3960 sum = 0;
3961 lk = xmlListFront(writer->nodes);
3962 if (lk == 0) {
3963 return -1;
3964 }
3965
3966 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
Daniel Veillard500a1de2004-03-22 15:22:58 +00003967 if (p != 0) {
3968 switch (p->state) {
3969 case XML_TEXTWRITER_DTD:
3970 count = xmlOutputBufferWriteString(writer->out, " [");
3971 if (count < 0)
3972 return -1;
3973 sum += count;
3974 if (writer->indent) {
3975 count = xmlOutputBufferWriteString(writer->out, "\n");
3976 if (count < 0)
3977 return -1;
3978 sum += count;
3979 }
3980 p->state = XML_TEXTWRITER_DTD_TEXT;
3981 /* fallthrough */
3982 case XML_TEXTWRITER_DTD_TEXT:
3983 break;
3984 default:
3985 return -1;
3986 }
3987 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00003988
Daniel Veillard500a1de2004-03-22 15:22:58 +00003989 if (writer->indent) {
3990 count = xmlTextWriterWriteIndent(writer);
3991 if (count < 0)
Daniel Veillard1d211e22003-10-20 22:32:39 +00003992 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00003993 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00003994 }
3995
3996 count = xmlOutputBufferWriteString(writer->out, "<!NOTATION ");
3997 if (count < 0)
3998 return -1;
3999 sum += count;
4000 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
4001 if (count < 0)
4002 return -1;
4003 sum += count;
4004
4005 if (pubid != 0) {
4006 count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
4007 if (count < 0)
4008 return -1;
4009 sum += count;
4010 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4011 if (count < 0)
4012 return -1;
4013 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004014 count =
4015 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004016 if (count < 0)
4017 return -1;
4018 sum += count;
4019 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4020 if (count < 0)
4021 return -1;
4022 sum += count;
4023 }
4024
4025 if (sysid != 0) {
4026 if (pubid == 0) {
4027 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
4028 if (count < 0)
4029 return -1;
4030 sum += count;
4031 }
4032 count = xmlOutputBufferWriteString(writer->out, " ");
4033 if (count < 0)
4034 return -1;
4035 sum += count;
4036 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4037 if (count < 0)
4038 return -1;
4039 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004040 count =
4041 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004042 if (count < 0)
4043 return -1;
4044 sum += count;
4045 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4046 if (count < 0)
4047 return -1;
4048 sum += count;
4049 }
4050
4051 count = xmlOutputBufferWriteString(writer->out, ">");
4052 if (count < 0)
4053 return -1;
4054 sum += count;
4055
4056 return sum;
4057}
4058
4059/**
4060 * xmlTextWriterFlush:
4061 * @writer: the xmlTextWriterPtr
4062 *
4063 * Flush the output buffer.
4064 *
4065 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
4066 */
4067int
4068xmlTextWriterFlush(xmlTextWriterPtr writer)
4069{
4070 int count;
4071
4072 if (writer == NULL)
4073 return -1;
4074
4075 if (writer->out == NULL)
4076 count = 0;
4077 else
4078 count = xmlOutputBufferFlush(writer->out);
4079
4080 return count;
4081}
4082
4083/**
4084 * misc
4085 */
4086
4087/**
4088 * xmlFreeTextWriterStackEntry:
4089 * @lk: the xmlLinkPtr
4090 *
4091 * Free callback for the xmlList.
4092 */
4093static void
4094xmlFreeTextWriterStackEntry(xmlLinkPtr lk)
4095{
4096 xmlTextWriterStackEntry *p;
4097
4098 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
4099 if (p == 0)
4100 return;
4101
4102 if (p->name != 0)
4103 xmlFree(p->name);
4104 xmlFree(p);
4105}
4106
4107/**
4108 * xmlCmpTextWriterStackEntry:
4109 * @data0: the first data
4110 * @data1: the second data
4111 *
4112 * Compare callback for the xmlList.
4113 *
4114 * Returns -1, 0, 1
4115 */
4116static int
4117xmlCmpTextWriterStackEntry(const void *data0, const void *data1)
4118{
4119 xmlTextWriterStackEntry *p0;
4120 xmlTextWriterStackEntry *p1;
4121
4122 if (data0 == data1)
4123 return 0;
4124
4125 if (data0 == 0)
4126 return -1;
4127
4128 if (data1 == 0)
4129 return 1;
4130
4131 p0 = (xmlTextWriterStackEntry *) data0;
4132 p1 = (xmlTextWriterStackEntry *) data1;
4133
4134 return xmlStrcmp(p0->name, p1->name);
4135}
4136
4137/**
4138 * misc
4139 */
4140
4141/**
4142 * xmlFreeTextWriterNsStackEntry:
4143 * @lk: the xmlLinkPtr
4144 *
4145 * Free callback for the xmlList.
4146 */
4147static void
4148xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk)
4149{
4150 xmlTextWriterNsStackEntry *p;
4151
4152 p = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
4153 if (p == 0)
4154 return;
4155
4156 if (p->prefix != 0)
4157 xmlFree(p->prefix);
4158 if (p->uri != 0)
4159 xmlFree(p->uri);
4160
4161 xmlFree(p);
4162}
4163
4164/**
4165 * xmlCmpTextWriterNsStackEntry:
4166 * @data0: the first data
4167 * @data1: the second data
4168 *
4169 * Compare callback for the xmlList.
4170 *
4171 * Returns -1, 0, 1
4172 */
4173static int
4174xmlCmpTextWriterNsStackEntry(const void *data0, const void *data1)
4175{
4176 xmlTextWriterNsStackEntry *p0;
4177 xmlTextWriterNsStackEntry *p1;
4178 int rc;
4179
4180 if (data0 == data1)
4181 return 0;
4182
4183 if (data0 == 0)
4184 return -1;
4185
4186 if (data1 == 0)
4187 return 1;
4188
4189 p0 = (xmlTextWriterNsStackEntry *) data0;
4190 p1 = (xmlTextWriterNsStackEntry *) data1;
4191
4192 rc = xmlStrcmp(p0->prefix, p1->prefix);
4193
4194 if (rc == 0)
4195 rc = p0->elem == p1->elem;
4196
4197 return rc;
4198}
4199
4200/**
4201 * xmlTextWriterWriteMemCallback:
4202 * @context: the xmlBufferPtr
4203 * @str: the data to write
4204 * @len: the length of the data
4205 *
4206 * Write callback for the xmlOutputBuffer with target xmlBuffer
4207 *
4208 * Returns -1, 0, 1
4209 */
4210static int
4211xmlTextWriterWriteMemCallback(void *context, const xmlChar * str, int len)
4212{
4213 xmlBufferPtr buf = (xmlBufferPtr) context;
4214
4215 xmlBufferAdd(buf, str, len);
4216
4217 return len;
4218}
4219
4220/**
4221 * xmlTextWriterCloseMemCallback:
4222 * @context: the xmlBufferPtr
4223 *
4224 * Close callback for the xmlOutputBuffer with target xmlBuffer
4225 *
4226 * Returns -1, 0, 1
4227 */
4228static int
4229xmlTextWriterCloseMemCallback(void *context ATTRIBUTE_UNUSED)
4230{
4231 return 0;
4232}
4233
4234/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004235 * xmlTextWriterWriteDocCallback:
4236 * @context: the xmlBufferPtr
4237 * @str: the data to write
4238 * @len: the length of the data
4239 *
4240 * Write callback for the xmlOutputBuffer with target xmlBuffer
4241 *
4242 * Returns -1, 0, 1
4243 */
4244static int
4245xmlTextWriterWriteDocCallback(void *context, const xmlChar * str, int len)
4246{
4247 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context;
4248 int rc;
4249
Daniel Veillard1d913862003-11-21 00:28:39 +00004250 if ((rc = xmlParseChunk(ctxt, (const char *) str, len, 0)) != 0) {
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004251 xmlGenericError(xmlGenericErrorContext,
4252 "xmlTextWriterWriteDocCallback : XML error %d !\n",
4253 rc);
4254 return -1;
4255 }
4256
4257 return len;
4258}
4259
4260/**
4261 * xmlTextWriterCloseDocCallback:
4262 * @context: the xmlBufferPtr
4263 *
4264 * Close callback for the xmlOutputBuffer with target xmlBuffer
4265 *
4266 * Returns -1, 0, 1
4267 */
4268static int
4269xmlTextWriterCloseDocCallback(void *context)
4270{
4271 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context;
4272 int rc;
4273
4274 if ((rc = xmlParseChunk(ctxt, NULL, 0, 1)) != 0) {
4275 xmlGenericError(xmlGenericErrorContext,
4276 "xmlTextWriterWriteDocCallback : XML error %d !\n",
4277 rc);
4278 return -1;
4279 }
4280
4281 return 0;
4282}
4283
4284/**
Daniel Veillard1d211e22003-10-20 22:32:39 +00004285 * xmlTextWriterVSprintf:
4286 * @format: see printf
4287 * @argptr: pointer to the first member of the variable argument list.
4288 *
4289 * Utility function for formatted output
4290 *
4291 * Returns a new xmlChar buffer with the data or NULL on error. This buffer must be freed.
4292 */
4293static xmlChar *
4294xmlTextWriterVSprintf(const char *format, va_list argptr)
4295{
4296 int size;
4297 int count;
4298 xmlChar *buf;
4299
4300 size = BUFSIZ;
4301 buf = (xmlChar *) xmlMalloc(size);
4302 if (buf == NULL) {
4303 xmlGenericError(xmlGenericErrorContext,
4304 "xmlTextWriterVSprintf : out of memory!\n");
4305 return NULL;
4306 }
4307
4308 while (((count = vsnprintf((char *) buf, size, format, argptr)) < 0)
4309 || (count == size - 1) || (count == size) || (count > size)) {
4310 xmlFree(buf);
4311 size += BUFSIZ;
4312 buf = (xmlChar *) xmlMalloc(size);
4313 if (buf == NULL) {
4314 xmlGenericError(xmlGenericErrorContext,
4315 "xmlTextWriterVSprintf : out of memory!\n");
4316 return NULL;
4317 }
4318 }
4319
4320 return buf;
4321}
4322
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004323/**
4324 * xmlTextWriterStartDocumentCallback:
4325 * @ctx: the user data (XML parser context)
4326 *
4327 * called at the start of document processing.
4328 */
4329static void
4330xmlTextWriterStartDocumentCallback(void *ctx)
4331{
4332 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
4333 xmlDocPtr doc;
4334
4335#ifdef DEBUG_SAX
4336 xmlGenericError(xmlGenericErrorContext, "SAX.startDocument()\n");
4337#endif
4338 if (ctxt->html) {
4339#ifdef LIBXML_HTML_ENABLED
4340 if (ctxt->myDoc == NULL)
4341 ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
4342 if (ctxt->myDoc == NULL) {
4343 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
4344 ctxt->sax->error(ctxt->userData,
4345 "SAX.startDocument(): out of memory\n");
4346 ctxt->errNo = XML_ERR_NO_MEMORY;
4347 ctxt->instate = XML_PARSER_EOF;
4348 ctxt->disableSAX = 1;
4349 return;
4350 }
4351#else
4352 xmlGenericError(xmlGenericErrorContext,
4353 "libxml2 built without HTML support\n");
4354 ctxt->errNo = XML_ERR_INTERNAL_ERROR;
4355 ctxt->instate = XML_PARSER_EOF;
4356 ctxt->disableSAX = 1;
4357 return;
4358#endif
4359 } else {
4360 doc = ctxt->myDoc;
4361 if (doc == NULL)
4362 doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
4363 if (doc != NULL) {
4364 if (doc->children == NULL) {
4365 if (ctxt->encoding != NULL)
4366 doc->encoding = xmlStrdup(ctxt->encoding);
4367 else
4368 doc->encoding = NULL;
4369 doc->standalone = ctxt->standalone;
4370 }
4371 } else {
4372 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
4373 ctxt->sax->error(ctxt->userData,
4374 "SAX.startDocument(): out of memory\n");
4375 ctxt->errNo = XML_ERR_NO_MEMORY;
4376 ctxt->instate = XML_PARSER_EOF;
4377 ctxt->disableSAX = 1;
4378 return;
4379 }
4380 }
4381 if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) &&
4382 (ctxt->input != NULL) && (ctxt->input->filename != NULL)) {
4383 ctxt->myDoc->URL =
4384 xmlCanonicPath((const xmlChar *) ctxt->input->filename);
4385 if (ctxt->myDoc->URL == NULL)
4386 ctxt->myDoc->URL =
4387 xmlStrdup((const xmlChar *) ctxt->input->filename);
4388 }
4389}
4390
Daniel Veillard2cca4462004-01-02 20:04:23 +00004391/**
4392 * xmlTextWriterSetIndent:
4393 * @writer: the xmlTextWriterPtr
4394 * @indent: do indentation?
4395 *
4396 * Set indentation output. indent = 0 do not indentation. indent > 0 do indentation.
4397 *
4398 * Returns -1 on error or 0 otherwise.
4399 */
4400int
Daniel Veillardab69f362004-02-17 11:40:32 +00004401xmlTextWriterSetIndent(xmlTextWriterPtr writer, int indent)
Daniel Veillard2cca4462004-01-02 20:04:23 +00004402{
Daniel Veillarde43cc572004-11-03 11:50:29 +00004403 if ((writer == NULL) || (indent < 0))
Daniel Veillardab69f362004-02-17 11:40:32 +00004404 return -1;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004405
Daniel Veillardab69f362004-02-17 11:40:32 +00004406 writer->indent = indent;
4407 writer->doindent = 1;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004408
Daniel Veillardab69f362004-02-17 11:40:32 +00004409 return 0;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004410}
4411
4412/**
4413 * xmlTextWriterSetIndentString:
4414 * @writer: the xmlTextWriterPtr
4415 * @str: the xmlChar string
4416 *
4417 * Set string indentation.
4418 *
4419 * Returns -1 on error or 0 otherwise.
4420 */
4421int
Daniel Veillardab69f362004-02-17 11:40:32 +00004422xmlTextWriterSetIndentString(xmlTextWriterPtr writer, const xmlChar * str)
Daniel Veillard2cca4462004-01-02 20:04:23 +00004423{
Daniel Veillarde43cc572004-11-03 11:50:29 +00004424 if ((writer == NULL) || (!str))
Daniel Veillardab69f362004-02-17 11:40:32 +00004425 return -1;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004426
Daniel Veillardab69f362004-02-17 11:40:32 +00004427 if (writer->ichar != NULL)
4428 xmlFree(writer->ichar);
4429 writer->ichar = xmlStrdup(str);
4430
4431 if (!writer->ichar)
4432 return -1;
4433 else
4434 return 0;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004435}
4436
4437/**
4438 * xmlTextWriterWriteIndent:
4439 * @writer: the xmlTextWriterPtr
4440 *
4441 * Write indent string.
4442 *
4443 * Returns -1 on error or the number of strings written.
Daniel Veillardab69f362004-02-17 11:40:32 +00004444 */
Daniel Veillard2cca4462004-01-02 20:04:23 +00004445static int
Daniel Veillardab69f362004-02-17 11:40:32 +00004446xmlTextWriterWriteIndent(xmlTextWriterPtr writer)
Daniel Veillard2cca4462004-01-02 20:04:23 +00004447{
Daniel Veillardab69f362004-02-17 11:40:32 +00004448 int lksize;
4449 int i;
4450 int ret;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004451
Daniel Veillardab69f362004-02-17 11:40:32 +00004452 lksize = xmlListSize(writer->nodes);
4453 if (lksize < 1)
4454 return (-1); /* list is empty */
4455 for (i = 0; i < (lksize - 1); i++) {
4456 ret = xmlOutputBufferWriteString(writer->out,
4457 (const char *) writer->ichar);
4458 if (ret == -1)
4459 return (-1);
4460 }
4461
4462 return (lksize - 1);
Daniel Veillard2cca4462004-01-02 20:04:23 +00004463}
4464
Daniel Veillard500a1de2004-03-22 15:22:58 +00004465/**
4466 * xmlTextWriterHandleStateDependencies:
4467 * @writer: the xmlTextWriterPtr
4468 * @p: the xmlTextWriterStackEntry
4469 *
4470 * Write state dependent strings.
4471 *
4472 * Returns -1 on error or the number of characters written.
4473 */
4474static int
4475xmlTextWriterHandleStateDependencies(xmlTextWriterPtr writer,
4476 xmlTextWriterStackEntry * p)
4477{
4478 int count;
4479 int sum;
4480 char extra[3];
4481
4482 if (writer == NULL)
4483 return -1;
4484
4485 if (p == NULL)
4486 return 0;
4487
4488 sum = 0;
4489 extra[0] = extra[1] = extra[2] = '\0';
4490 if (p != 0) {
4491 sum = 0;
4492 switch (p->state) {
4493 case XML_TEXTWRITER_NAME:
4494 extra[0] = '>';
4495 p->state = XML_TEXTWRITER_TEXT;
4496 break;
4497 case XML_TEXTWRITER_PI:
4498 extra[0] = ' ';
4499 p->state = XML_TEXTWRITER_PI_TEXT;
4500 break;
4501 case XML_TEXTWRITER_DTD:
4502 extra[0] = ' ';
4503 extra[1] = '[';
4504 p->state = XML_TEXTWRITER_DTD_TEXT;
4505 break;
4506 case XML_TEXTWRITER_DTD_ELEM:
4507 extra[0] = ' ';
4508 p->state = XML_TEXTWRITER_DTD_ELEM_TEXT;
4509 break;
4510 case XML_TEXTWRITER_DTD_ATTL:
4511 extra[0] = ' ';
4512 p->state = XML_TEXTWRITER_DTD_ATTL_TEXT;
4513 break;
4514 case XML_TEXTWRITER_DTD_ENTY:
4515 case XML_TEXTWRITER_DTD_PENT:
4516 extra[0] = ' ';
4517 extra[1] = writer->qchar;
4518 p->state = XML_TEXTWRITER_DTD_ENTY_TEXT;
4519 break;
4520 default:
4521 break;
4522 }
4523 }
4524
4525 if (*extra != '\0') {
4526 count = xmlOutputBufferWriteString(writer->out, extra);
4527 if (count < 0)
4528 return -1;
4529 sum += count;
4530 }
4531
4532 return sum;
4533}
4534
Daniel Veillard1d211e22003-10-20 22:32:39 +00004535#endif