blob: e7d4cc8acb2f1e27aa7dcb1410d57ad243f270ff [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 }
307
Daniel Veillard1d913862003-11-21 00:28:39 +0000308 ctxt->myDoc = xmlNewDoc(BAD_CAST XML_DEFAULT_VERSION);
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000309 if (ctxt->myDoc == NULL) {
310 xmlFreeParserCtxt(ctxt);
311 xmlGenericError(xmlGenericErrorContext,
312 "xmlNewTextWriterDoc : error at xmlNewDoc!\n");
313 return NULL;
314 }
315
316 ret = xmlNewTextWriterPushParser(ctxt, compression);
317 if (ret == NULL) {
318 xmlGenericError(xmlGenericErrorContext,
319 "xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n");
320 return NULL;
321 }
322
Daniel Veillard500a1de2004-03-22 15:22:58 +0000323 xmlSetDocCompressMode(ctxt->myDoc, compression);
324
325 if (doc != NULL)
326 *doc = ctxt->myDoc;
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000327
328 return ret;
329}
330
331/**
332 * xmlNewTextWriterTree:
333 * @doc: xmlDocPtr
334 * @node: xmlNodePtr or NULL for doc->children
335 * @compression: compress the output?
336 *
337 * Create a new xmlNewTextWriter structure with @doc as output
338 * starting at @node
339 *
340 * Returns the new xmlTextWriterPtr or NULL in case of error
341 */
342xmlTextWriterPtr
343xmlNewTextWriterTree(xmlDocPtr doc, xmlNodePtr node, int compression)
344{
345 xmlTextWriterPtr ret;
346 xmlSAXHandler saxHandler;
347 xmlParserCtxtPtr ctxt;
348
349 if (doc == NULL) {
Daniel Veillard500a1de2004-03-22 15:22:58 +0000350 xmlGenericError(xmlGenericErrorContext,
351 "xmlNewTextWriterTree : invalid document tree!\n");
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000352 return NULL;
353 }
354
355 memset(&saxHandler, '\0', sizeof(saxHandler));
356 xmlSAX2InitDefaultSAXHandler(&saxHandler, 1);
357 saxHandler.startDocument = xmlTextWriterStartDocumentCallback;
358 saxHandler.startElement = xmlSAX2StartElement;
359 saxHandler.endElement = xmlSAX2EndElement;
360
361 ctxt = xmlCreatePushParserCtxt(&saxHandler, NULL, NULL, 0, NULL);
362 if (ctxt == NULL) {
363 xmlGenericError(xmlGenericErrorContext,
364 "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\n");
365 return NULL;
366 }
367
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000368 ret = xmlNewTextWriterPushParser(ctxt, compression);
369 if (ret == NULL) {
Daniel Veillard500a1de2004-03-22 15:22:58 +0000370 xmlFreeParserCtxt(ctxt);
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000371 xmlGenericError(xmlGenericErrorContext,
372 "xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n");
373 return NULL;
374 }
375
Daniel Veillard500a1de2004-03-22 15:22:58 +0000376 ctxt->myDoc = doc;
377 ctxt->node = node;
378
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000379 xmlSetDocCompressMode(doc, compression);
380
381 return ret;
382}
383
384/**
Daniel Veillard1d211e22003-10-20 22:32:39 +0000385 * xmlFreeTextWriter:
386 * @writer: the xmlTextWriterPtr
387 *
388 * Deallocate all the resources associated to the writer
389 */
390void
391xmlFreeTextWriter(xmlTextWriterPtr writer)
392{
393 if (writer == NULL)
394 return;
395
396 if (writer->out != NULL)
397 xmlOutputBufferClose(writer->out);
398
399 if (writer->nodes != NULL)
400 xmlListDelete(writer->nodes);
401
402 if (writer->nsstack != NULL)
403 xmlListDelete(writer->nsstack);
404
Daniel Veillard20c5e782004-01-21 09:57:31 +0000405 if (writer->ctxt != NULL)
406 xmlFreeParserCtxt(writer->ctxt);
407
Daniel Veillard4773df22004-01-23 13:15:13 +0000408 if (writer->ichar != NULL)
409 xmlFree(writer->ichar);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000410 xmlFree(writer);
411}
412
413/**
414 * xmlTextWriterStartDocument:
415 * @writer: the xmlTextWriterPtr
416 * @version: the xml version ("1.0") or NULL for default ("1.0")
417 * @encoding: the encoding or NULL for default
418 * @standalone: "yes" or "no" or NULL for default
419 *
420 * Start a new xml document
421 *
422 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
423 */
424int
425xmlTextWriterStartDocument(xmlTextWriterPtr writer, const char *version,
426 const char *encoding, const char *standalone)
427{
428 int count;
429 int sum;
430 xmlLinkPtr lk;
431 xmlCharEncodingHandlerPtr encoder;
432
Daniel Veillard500a1de2004-03-22 15:22:58 +0000433 if ((writer == NULL) || (writer->out == NULL)) {
434 xmlGenericError(xmlGenericErrorContext,
435 "xmlTextWriterStartDocument : invalid writer!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000436 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000437 }
Daniel Veillard1d211e22003-10-20 22:32:39 +0000438
439 lk = xmlListFront(writer->nodes);
440 if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) {
441 xmlGenericError(xmlGenericErrorContext,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000442 "xmlTextWriterStartDocument : not allowed in this context!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000443 return -1;
444 }
445
446 encoder = NULL;
447 if (encoding != NULL) {
448 encoder = xmlFindCharEncodingHandler(encoding);
449 if (encoder == NULL) {
450 xmlGenericError(xmlGenericErrorContext,
451 "xmlTextWriterStartDocument : out of memory!\n");
452 return -1;
453 }
454 }
455
456 writer->out->encoder = encoder;
457 if (encoder != NULL) {
458 writer->out->conv = xmlBufferCreateSize(4000);
459 xmlCharEncOutFunc(encoder, writer->out->conv, NULL);
460 } else
461 writer->out->conv = NULL;
462
463 sum = 0;
464 count = xmlOutputBufferWriteString(writer->out, "<?xml version=");
465 if (count < 0)
466 return -1;
467 sum += count;
468 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
469 if (count < 0)
470 return -1;
471 sum += count;
472 if (version != 0)
473 count = xmlOutputBufferWriteString(writer->out, version);
474 else
475 count = xmlOutputBufferWriteString(writer->out, "1.0");
476 if (count < 0)
477 return -1;
478 sum += count;
479 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
480 if (count < 0)
481 return -1;
482 sum += count;
483 if (writer->out->encoder != 0) {
484 count = xmlOutputBufferWriteString(writer->out, " encoding=");
485 if (count < 0)
486 return -1;
487 sum += count;
488 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
489 if (count < 0)
490 return -1;
491 sum += count;
492 count =
493 xmlOutputBufferWriteString(writer->out,
494 writer->out->encoder->name);
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 }
503
504 if (standalone != 0) {
505 count = xmlOutputBufferWriteString(writer->out, " standalone=");
506 if (count < 0)
507 return -1;
508 sum += count;
509 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
510 if (count < 0)
511 return -1;
512 sum += count;
513 count = xmlOutputBufferWriteString(writer->out, standalone);
514 if (count < 0)
515 return -1;
516 sum += count;
517 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
518 if (count < 0)
519 return -1;
520 sum += count;
521 }
522
523 count = xmlOutputBufferWriteString(writer->out, "?>\n");
524 if (count < 0)
525 return -1;
526 sum += count;
527
528 return sum;
529}
530
531/**
532 * xmlTextWriterEndDocument:
533 * @writer: the xmlTextWriterPtr
534 *
535 * End an xml document. All open elements are closed
536 *
537 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
538 */
539int
540xmlTextWriterEndDocument(xmlTextWriterPtr writer)
541{
542 int count;
543 int sum;
544 xmlLinkPtr lk;
545 xmlTextWriterStackEntry *p;
546
Daniel Veillard500a1de2004-03-22 15:22:58 +0000547 if (writer == NULL) {
548 xmlGenericError(xmlGenericErrorContext,
549 "xmlTextWriterEndDocument : invalid writer!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000550 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000551 }
Daniel Veillard1d211e22003-10-20 22:32:39 +0000552
553 sum = 0;
554 while ((lk = xmlListFront(writer->nodes)) != NULL) {
555 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
556 if (p == 0)
557 break;
558 switch (p->state) {
559 case XML_TEXTWRITER_NAME:
560 case XML_TEXTWRITER_ATTRIBUTE:
561 case XML_TEXTWRITER_TEXT:
562 count = xmlTextWriterEndElement(writer);
563 if (count < 0)
564 return -1;
565 sum += count;
566 break;
567 case XML_TEXTWRITER_PI:
568 case XML_TEXTWRITER_PI_TEXT:
569 count = xmlTextWriterEndPI(writer);
570 if (count < 0)
571 return -1;
572 sum += count;
573 break;
574 case XML_TEXTWRITER_CDATA:
575 count = xmlTextWriterEndCDATA(writer);
576 if (count < 0)
577 return -1;
578 sum += count;
579 break;
580 case XML_TEXTWRITER_DTD:
Daniel Veillard500a1de2004-03-22 15:22:58 +0000581 case XML_TEXTWRITER_DTD_TEXT:
582 case XML_TEXTWRITER_DTD_ELEM:
583 case XML_TEXTWRITER_DTD_ELEM_TEXT:
584 case XML_TEXTWRITER_DTD_ATTL:
585 case XML_TEXTWRITER_DTD_ATTL_TEXT:
586 case XML_TEXTWRITER_DTD_ENTY:
587 case XML_TEXTWRITER_DTD_ENTY_TEXT:
588 case XML_TEXTWRITER_DTD_PENT:
Daniel Veillard1d211e22003-10-20 22:32:39 +0000589 count = xmlTextWriterEndDTD(writer);
590 if (count < 0)
591 return -1;
592 sum += count;
593 break;
Daniel Veillardab69f362004-02-17 11:40:32 +0000594 case XML_TEXTWRITER_COMMENT:
595 count = xmlTextWriterEndComment(writer);
596 if (count < 0)
597 return -1;
598 sum += count;
599 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000600 default:
Daniel Veillardab69f362004-02-17 11:40:32 +0000601 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000602 }
603 }
604
Daniel Veillard2cca4462004-01-02 20:04:23 +0000605 if (!writer->indent) {
Daniel Veillardab69f362004-02-17 11:40:32 +0000606 count = xmlOutputBufferWriteString(writer->out, "\n");
607 if (count < 0)
608 return -1;
609 sum += count;
610 }
611 return sum;
612}
613
Daniel Veillardab69f362004-02-17 11:40:32 +0000614/**
615 * xmlTextWriterStartComment:
616 * @writer: the xmlTextWriterPtr
617 *
618 * Start an xml comment.
619 *
620 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
621 */
622int
623xmlTextWriterStartComment(xmlTextWriterPtr writer)
624{
625 int count;
626 int sum;
627 xmlLinkPtr lk;
628 xmlTextWriterStackEntry *p;
629
Daniel Veillard500a1de2004-03-22 15:22:58 +0000630 if (writer == NULL) {
631 xmlGenericError(xmlGenericErrorContext,
632 "xmlTextWriterStartComment : invalid writer!\n");
Daniel Veillardab69f362004-02-17 11:40:32 +0000633 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000634 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000635
636 sum = 0;
637 lk = xmlListFront(writer->nodes);
638 if (lk != 0) {
639 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
640 if (p != 0) {
641 switch (p->state) {
642 case XML_TEXTWRITER_TEXT:
643 case XML_TEXTWRITER_NONE:
644 break;
645 case XML_TEXTWRITER_NAME:
646 count = xmlOutputBufferWriteString(writer->out, ">");
647 if (count < 0)
648 return -1;
649 sum += count;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000650 if (writer->indent) {
651 count =
652 xmlOutputBufferWriteString(writer->out, "\n");
653 if (count < 0)
654 return -1;
655 sum += count;
656 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000657 p->state = XML_TEXTWRITER_TEXT;
658 break;
659 default:
660 return -1;
661 }
662 }
663 }
664
665 p = (xmlTextWriterStackEntry *)
666 xmlMalloc(sizeof(xmlTextWriterStackEntry));
667 if (p == 0) {
668 xmlGenericError(xmlGenericErrorContext,
669 "xmlTextWriterStartElement : out of memory!\n");
670 return -1;
671 }
672
673 p->name = 0;
674 p->state = XML_TEXTWRITER_COMMENT;
675
676 xmlListPushFront(writer->nodes, p);
677
678 if (writer->indent) {
Daniel Veillardab69f362004-02-17 11:40:32 +0000679 count = xmlTextWriterWriteIndent(writer);
680 if (count < 0)
681 return -1;
682 sum += count;
683 }
684
685 count = xmlOutputBufferWriteString(writer->out, "<!--");
686 if (count < 0)
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000687 return -1;
688 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +0000689
690 return sum;
691}
692
693/**
694 * xmlTextWriterEndComment:
695 * @writer: the xmlTextWriterPtr
696 *
697 * End the current xml coment.
698 *
699 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
700 */
701int
702xmlTextWriterEndComment(xmlTextWriterPtr writer)
703{
704 int count;
705 int sum;
706 xmlLinkPtr lk;
707 xmlTextWriterStackEntry *p;
708
Daniel Veillard500a1de2004-03-22 15:22:58 +0000709 if (writer == NULL) {
710 xmlGenericError(xmlGenericErrorContext,
711 "xmlTextWriterEndComment : invalid writer!\n");
Daniel Veillardab69f362004-02-17 11:40:32 +0000712 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000713 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000714
715 lk = xmlListFront(writer->nodes);
Daniel Veillard500a1de2004-03-22 15:22:58 +0000716 if (lk == 0) {
717 xmlGenericError(xmlGenericErrorContext,
718 "xmlTextWriterEndComment : not allowed in this context!\n");
Daniel Veillardab69f362004-02-17 11:40:32 +0000719 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000720 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000721
722 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
723 if (p == 0)
724 return -1;
725
726 sum = 0;
727 switch (p->state) {
728 case XML_TEXTWRITER_COMMENT:
729 count = xmlOutputBufferWriteString(writer->out, "-->");
730 if (count < 0)
731 return -1;
732 sum += count;
733 break;
734 default:
735 return -1;
Daniel Veillard2cca4462004-01-02 20:04:23 +0000736 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000737
738 if (writer->indent) {
739 count = xmlOutputBufferWriteString(writer->out, "\n");
740 if (count < 0)
741 return -1;
742 sum += count;
743 }
744
745 xmlListPopFront(writer->nodes);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000746 return sum;
747}
748
749/**
750 * xmlTextWriterWriteFormatComment:
751 * @writer: the xmlTextWriterPtr
752 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +0000753 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +0000754 *
755 * Write an xml comment.
756 *
757 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
758 */
759int
760xmlTextWriterWriteFormatComment(xmlTextWriterPtr writer,
761 const char *format, ...)
762{
763 int rc;
764 va_list ap;
765
766 va_start(ap, format);
767
768 rc = xmlTextWriterWriteVFormatComment(writer, format, ap);
769
770 va_end(ap);
771 return rc;
772}
773
774/**
775 * xmlTextWriterWriteVFormatComment:
776 * @writer: the xmlTextWriterPtr
777 * @format: format string (see printf)
778 * @argptr: pointer to the first member of the variable argument list.
779 *
780 * Write an xml comment.
781 *
782 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
783 */
784int
785xmlTextWriterWriteVFormatComment(xmlTextWriterPtr writer,
786 const char *format, va_list argptr)
787{
788 int rc;
789 xmlChar *buf;
790
Daniel Veillard500a1de2004-03-22 15:22:58 +0000791 if (writer == NULL) {
792 xmlGenericError(xmlGenericErrorContext,
793 "xmlTextWriterWriteVFormatComment : invalid writer!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000794 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000795 }
Daniel Veillard1d211e22003-10-20 22:32:39 +0000796
797 buf = xmlTextWriterVSprintf(format, argptr);
798 if (buf == 0)
799 return 0;
800
801 rc = xmlTextWriterWriteComment(writer, buf);
802
803 xmlFree(buf);
804 return rc;
805}
806
807/**
808 * xmlTextWriterWriteComment:
809 * @writer: the xmlTextWriterPtr
810 * @content: comment string
811 *
812 * Write an xml comment.
813 *
814 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
815 */
816int
817xmlTextWriterWriteComment(xmlTextWriterPtr writer, const xmlChar * content)
818{
819 int count;
820 int sum;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000821
822 sum = 0;
Daniel Veillardab69f362004-02-17 11:40:32 +0000823 count = xmlTextWriterStartComment(writer);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000824 if (count < 0)
825 return -1;
826 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +0000827 count = xmlTextWriterWriteString(writer, content);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000828 if (count < 0)
829 return -1;
830 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +0000831 count = xmlTextWriterEndComment(writer);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000832 if (count < 0)
833 return -1;
834 sum += count;
835
836 return sum;
837}
838
839/**
840 * xmlTextWriterStartElement:
841 * @writer: the xmlTextWriterPtr
842 * @name: element name
843 *
844 * Start an xml element.
845 *
846 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
847 */
848int
849xmlTextWriterStartElement(xmlTextWriterPtr writer, const xmlChar * name)
850{
851 int count;
852 int sum;
853 xmlLinkPtr lk;
854 xmlTextWriterStackEntry *p;
855
856 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
857 return -1;
858
859 sum = 0;
860 lk = xmlListFront(writer->nodes);
861 if (lk != 0) {
862 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
863 if (p != 0) {
864 switch (p->state) {
865 case XML_TEXTWRITER_PI:
866 case XML_TEXTWRITER_PI_TEXT:
867 return -1;
868 case XML_TEXTWRITER_NONE:
869 break;
870 case XML_TEXTWRITER_NAME:
871 count = xmlOutputBufferWriteString(writer->out, ">");
872 if (count < 0)
873 return -1;
874 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +0000875 if (writer->indent)
876 count =
877 xmlOutputBufferWriteString(writer->out, "\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000878 p->state = XML_TEXTWRITER_TEXT;
879 break;
Daniel Veillardab69f362004-02-17 11:40:32 +0000880 default:
881 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000882 }
883 }
884 }
885
886 p = (xmlTextWriterStackEntry *)
887 xmlMalloc(sizeof(xmlTextWriterStackEntry));
888 if (p == 0) {
889 xmlGenericError(xmlGenericErrorContext,
890 "xmlTextWriterStartElement : out of memory!\n");
891 return -1;
892 }
893
894 p->name = xmlStrdup(name);
895 if (p->name == 0) {
896 xmlGenericError(xmlGenericErrorContext,
897 "xmlTextWriterStartElement : out of memory!\n");
898 xmlFree(p);
899 return -1;
900 }
901 p->state = XML_TEXTWRITER_NAME;
902
903 xmlListPushFront(writer->nodes, p);
904
Daniel Veillardab69f362004-02-17 11:40:32 +0000905 if (writer->indent) {
906 count = xmlTextWriterWriteIndent(writer);
907 sum += count;
Daniel Veillard2cca4462004-01-02 20:04:23 +0000908 }
909
Daniel Veillard1d211e22003-10-20 22:32:39 +0000910 count = xmlOutputBufferWriteString(writer->out, "<");
911 if (count < 0)
912 return -1;
913 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000914 count =
915 xmlOutputBufferWriteString(writer->out, (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000916 if (count < 0)
917 return -1;
918 sum += count;
919
920 return sum;
921}
922
923/**
924 * xmlTextWriterStartElementNS:
925 * @writer: the xmlTextWriterPtr
926 * @prefix: namespace prefix or NULL
927 * @name: element local name
928 * @namespaceURI: namespace URI or NULL
929 *
930 * Start an xml element with namespace support.
931 *
932 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
933 */
934int
935xmlTextWriterStartElementNS(xmlTextWriterPtr writer,
936 const xmlChar * prefix, const xmlChar * name,
937 const xmlChar * namespaceURI)
938{
939 int count;
940 int sum;
941 xmlChar *buf;
942
943 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
944 return -1;
945
946 buf = 0;
947 if (prefix != 0) {
948 buf = xmlStrdup(prefix);
949 buf = xmlStrcat(buf, BAD_CAST ":");
950 }
951 buf = xmlStrcat(buf, name);
952
953 sum = 0;
954 count = xmlTextWriterStartElement(writer, buf);
955 xmlFree(buf);
956 if (count < 0)
957 return -1;
958 sum += count;
959
960 if (namespaceURI != 0) {
961 buf = xmlStrdup(BAD_CAST "xmlns");
962 if (prefix != 0) {
963 buf = xmlStrcat(buf, BAD_CAST ":");
964 buf = xmlStrcat(buf, prefix);
965 }
966
967 count = xmlTextWriterWriteAttribute(writer, buf, namespaceURI);
968 xmlFree(buf);
969 if (count < 0)
970 return -1;
971 sum += count;
972 }
973
974 return sum;
975}
976
977/**
978 * xmlTextWriterEndElement:
979 * @writer: the xmlTextWriterPtr
980 *
981 * End the current xml element.
982 *
983 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
984 */
985int
986xmlTextWriterEndElement(xmlTextWriterPtr writer)
987{
988 int count;
989 int sum;
990 xmlLinkPtr lk;
991 xmlTextWriterStackEntry *p;
992
993 if (writer == NULL)
994 return -1;
995
996 lk = xmlListFront(writer->nodes);
997 if (lk == 0)
998 return -1;
999
1000 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1001 if (p == 0)
1002 return -1;
1003
1004 sum = 0;
1005 switch (p->state) {
1006 case XML_TEXTWRITER_ATTRIBUTE:
1007 count = xmlTextWriterEndAttribute(writer);
1008 if (count < 0)
1009 return -1;
1010 sum += count;
1011 /* fallthrough */
1012 case XML_TEXTWRITER_NAME:
Daniel Veillardab69f362004-02-17 11:40:32 +00001013 if (writer->indent) /* next element needs indent */
1014 writer->doindent = 1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001015 count = xmlOutputBufferWriteString(writer->out, "/>");
1016 if (count < 0)
1017 return -1;
1018 sum += count;
1019 break;
1020 case XML_TEXTWRITER_TEXT:
Daniel Veillardab69f362004-02-17 11:40:32 +00001021 if ((writer->indent) && (writer->doindent)) {
1022 count = xmlTextWriterWriteIndent(writer);
1023 sum += count;
1024 writer->doindent = 1;
1025 } else
1026 writer->doindent = 1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001027 count = xmlOutputBufferWriteString(writer->out, "</");
1028 if (count < 0)
1029 return -1;
1030 sum += count;
1031 count = xmlOutputBufferWriteString(writer->out,
Daniel Veillardab69f362004-02-17 11:40:32 +00001032 (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001033 if (count < 0)
1034 return -1;
1035 sum += count;
1036 count = xmlOutputBufferWriteString(writer->out, ">");
1037 if (count < 0)
1038 return -1;
1039 sum += count;
1040 break;
1041 default:
1042 return -1;
1043 }
1044
Daniel Veillard2cca4462004-01-02 20:04:23 +00001045 if (writer->indent) {
Daniel Veillardab69f362004-02-17 11:40:32 +00001046 count = xmlOutputBufferWriteString(writer->out, "\n");
1047 sum += count;
Daniel Veillard2cca4462004-01-02 20:04:23 +00001048 }
1049
Daniel Veillard1d211e22003-10-20 22:32:39 +00001050 xmlListPopFront(writer->nodes);
1051 return sum;
1052}
1053
1054/**
1055 * xmlTextWriterFullEndElement:
1056 * @writer: the xmlTextWriterPtr
1057 *
1058 * End the current xml element. Writes an end tag even if the element is empty
1059 *
1060 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1061 */
1062int
1063xmlTextWriterFullEndElement(xmlTextWriterPtr writer)
1064{
1065 int count;
1066 int sum;
1067 xmlLinkPtr lk;
1068 xmlTextWriterStackEntry *p;
1069
1070 if (writer == NULL)
1071 return -1;
1072
1073 lk = xmlListFront(writer->nodes);
1074 if (lk == 0)
1075 return -1;
1076
1077 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1078 if (p == 0)
1079 return -1;
1080
1081 sum = 0;
1082 switch (p->state) {
1083 case XML_TEXTWRITER_ATTRIBUTE:
1084 count = xmlTextWriterEndAttribute(writer);
1085 if (count < 0)
1086 return -1;
1087 sum += count;
1088 /* fallthrough */
1089 case XML_TEXTWRITER_NAME:
1090 count = xmlOutputBufferWriteString(writer->out, ">");
1091 if (count < 0)
1092 return -1;
1093 sum += count;
1094 /* fallthrough */
1095 case XML_TEXTWRITER_TEXT:
1096 count = xmlOutputBufferWriteString(writer->out, "</");
1097 if (count < 0)
1098 return -1;
1099 sum += count;
1100 count = xmlOutputBufferWriteString(writer->out,
Daniel Veillardab69f362004-02-17 11:40:32 +00001101 (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001102 if (count < 0)
1103 return -1;
1104 sum += count;
1105 count = xmlOutputBufferWriteString(writer->out, ">");
1106 if (count < 0)
1107 return -1;
1108 sum += count;
1109 break;
1110 default:
1111 return -1;
1112 }
1113
1114 xmlListPopFront(writer->nodes);
1115 return sum;
1116}
1117
1118/**
1119 * xmlTextWriterWriteFormatRaw:
1120 * @writer: the xmlTextWriterPtr
1121 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001122 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001123 *
1124 * Write a formatted raw xml text.
1125 *
1126 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1127 */
1128int
1129xmlTextWriterWriteFormatRaw(xmlTextWriterPtr writer, const char *format,
1130 ...)
1131{
1132 int rc;
1133 va_list ap;
1134
1135 va_start(ap, format);
1136
1137 rc = xmlTextWriterWriteVFormatRaw(writer, format, ap);
1138
1139 va_end(ap);
1140 return rc;
1141}
1142
1143/**
1144 * xmlTextWriterWriteVFormatRaw:
1145 * @writer: the xmlTextWriterPtr
1146 * @format: format string (see printf)
1147 * @argptr: pointer to the first member of the variable argument list.
1148 *
1149 * Write a formatted raw xml text.
1150 *
1151 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1152 */
1153int
1154xmlTextWriterWriteVFormatRaw(xmlTextWriterPtr writer, const char *format,
1155 va_list argptr)
1156{
1157 int rc;
1158 xmlChar *buf;
1159
1160 if (writer == NULL)
1161 return -1;
1162
1163 buf = xmlTextWriterVSprintf(format, argptr);
1164 if (buf == 0)
1165 return 0;
1166
1167 rc = xmlTextWriterWriteRaw(writer, buf);
1168
1169 xmlFree(buf);
1170 return rc;
1171}
1172
1173/**
Daniel Veillard1e906612003-12-05 14:57:46 +00001174 * xmlTextWriterWriteRawLen:
Daniel Veillard1d211e22003-10-20 22:32:39 +00001175 * @writer: the xmlTextWriterPtr
1176 * @content: text string
1177 * @len: length of the text string
1178 *
1179 * Write an xml text.
1180 * TODO: what about entities and special chars??
1181 *
1182 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1183 */
1184int
1185xmlTextWriterWriteRawLen(xmlTextWriterPtr writer, const xmlChar * content,
1186 int len)
1187{
1188 int count;
1189 int sum;
1190 xmlLinkPtr lk;
1191 xmlTextWriterStackEntry *p;
1192
Daniel Veillard500a1de2004-03-22 15:22:58 +00001193 if (writer == NULL) {
1194 xmlGenericError(xmlGenericErrorContext,
1195 "xmlTextWriterWriteRawLen : invalid writer!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +00001196 return -1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001197 }
1198
Daniel Veillard500a1de2004-03-22 15:22:58 +00001199 if ((content == NULL) && (len > 0)) {
1200 xmlGenericError(xmlGenericErrorContext,
1201 "xmlTextWriterWriteRawLen : invalid content!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +00001202 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001203 }
1204
1205 sum = 0;
1206 lk = xmlListFront(writer->nodes);
1207 if (lk != 0) {
1208 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1209 count = xmlTextWriterHandleStateDependencies(writer, p);
1210 if (count < 0)
1211 return -1;
1212 sum += count;
1213 }
1214
1215 if (writer->indent)
1216 writer->doindent = 0;
1217
1218 if (content != NULL) {
1219 count =
1220 xmlOutputBufferWrite(writer->out, len, (const char *) content);
1221 if (count < 0)
1222 return -1;
1223 sum += count;
1224 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001225
1226 return sum;
1227}
1228
1229/**
1230 * xmlTextWriterWriteRaw:
1231 * @writer: the xmlTextWriterPtr
1232 * @content: text string
1233 *
1234 * Write a raw xml text.
1235 *
1236 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1237 */
1238int
1239xmlTextWriterWriteRaw(xmlTextWriterPtr writer, const xmlChar * content)
1240{
1241 return xmlTextWriterWriteRawLen(writer, content, xmlStrlen(content));
1242}
1243
1244/**
1245 * xmlTextWriterWriteFormatString:
1246 * @writer: the xmlTextWriterPtr
1247 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001248 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001249 *
1250 * Write a formatted xml text.
1251 *
1252 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1253 */
1254int
1255xmlTextWriterWriteFormatString(xmlTextWriterPtr writer, const char *format,
1256 ...)
1257{
1258 int rc;
1259 va_list ap;
1260
1261 va_start(ap, format);
1262
1263 rc = xmlTextWriterWriteVFormatString(writer, format, ap);
1264
1265 va_end(ap);
1266 return rc;
1267}
1268
1269/**
1270 * xmlTextWriterWriteVFormatString:
1271 * @writer: the xmlTextWriterPtr
1272 * @format: format string (see printf)
1273 * @argptr: pointer to the first member of the variable argument list.
1274 *
1275 * Write a formatted xml text.
1276 *
1277 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1278 */
1279int
1280xmlTextWriterWriteVFormatString(xmlTextWriterPtr writer,
1281 const char *format, va_list argptr)
1282{
1283 int rc;
1284 xmlChar *buf;
1285
1286 if (writer == NULL)
1287 return -1;
1288
1289 buf = xmlTextWriterVSprintf(format, argptr);
1290 if (buf == 0)
1291 return 0;
1292
1293 rc = xmlTextWriterWriteString(writer, buf);
1294
1295 xmlFree(buf);
1296 return rc;
1297}
1298
1299/**
1300 * xmlTextWriterWriteString:
1301 * @writer: the xmlTextWriterPtr
1302 * @content: text string
1303 *
1304 * Write an xml text.
1305 *
1306 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1307 */
1308int
1309xmlTextWriterWriteString(xmlTextWriterPtr writer, const xmlChar * content)
1310{
Daniel Veillard500a1de2004-03-22 15:22:58 +00001311 int count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001312 int sum;
1313 xmlLinkPtr lk;
1314 xmlTextWriterStackEntry *p;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001315 xmlChar *buf;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001316
1317 if (writer == NULL)
1318 return -1;
1319
Daniel Veillard1d211e22003-10-20 22:32:39 +00001320 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001321 buf = (xmlChar *) content;
1322 lk = xmlListFront(writer->nodes);
1323 if (lk != 0) {
1324 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1325 if (p != 0) {
1326 switch (p->state) {
1327 case XML_TEXTWRITER_NAME:
1328 case XML_TEXTWRITER_TEXT:
Daniel Veillard62040be2004-05-17 03:17:26 +00001329#if 0
1330 buf = NULL;
1331 xmlOutputBufferWriteEscape(writer->out, content, NULL);
1332#endif
Daniel Veillard500a1de2004-03-22 15:22:58 +00001333 buf = xmlEncodeSpecialChars(NULL, content);
1334 break;
1335 case XML_TEXTWRITER_ATTRIBUTE:
1336 buf = NULL;
1337 xmlAttrSerializeTxtContent(writer->out->buffer, NULL,
1338 NULL, content);
1339 break;
William M. Brack87640d52004-04-17 14:58:15 +00001340 default:
1341 break;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001342 }
1343 }
1344 }
1345
1346 if (buf != NULL) {
1347 count = xmlTextWriterWriteRaw(writer, buf);
1348 if (count < 0)
Daniel Veillard1d211e22003-10-20 22:32:39 +00001349 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001350 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001351
Daniel Veillard500a1de2004-03-22 15:22:58 +00001352 if (buf != content) /* buf was allocated by us, so free it */
1353 xmlFree(buf);
William M. Bracka9c612c2004-02-01 10:04:05 +00001354 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001355
1356 return sum;
1357}
1358
1359/**
1360 * xmlOutputBufferWriteBase64:
1361 * @out: the xmlOutputBufferPtr
1362 * @data: binary data
1363 * @len: the number of bytes to encode
1364 *
1365 * Write base64 encoded data to an xmlOutputBuffer.
1366 * Adapted from John Walker's base64.c (http://www.fourmilab.ch/).
1367 *
1368 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1369 */
1370static int
1371xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len,
1372 const unsigned char *data)
1373{
1374 static unsigned char dtable[64] =
1375 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1376 int i;
1377 int linelen;
1378 int count;
1379 int sum;
1380
1381 linelen = 0;
1382 sum = 0;
1383
1384 i = 0;
1385 while (1) {
1386 unsigned char igroup[3];
1387 unsigned char ogroup[4];
1388 int c;
1389 int n;
1390
1391 igroup[0] = igroup[1] = igroup[2] = 0;
1392 for (n = 0; n < 3 && i < len; n++, i++) {
1393 c = data[i];
1394 igroup[n] = (unsigned char) c;
1395 }
1396
1397 if (n > 0) {
1398 ogroup[0] = dtable[igroup[0] >> 2];
1399 ogroup[1] = dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)];
1400 ogroup[2] =
1401 dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)];
1402 ogroup[3] = dtable[igroup[2] & 0x3F];
1403
1404 if (n < 3) {
1405 ogroup[3] = '=';
1406 if (n < 2) {
1407 ogroup[2] = '=';
1408 }
1409 }
1410
1411 if (linelen >= B64LINELEN) {
1412 count = xmlOutputBufferWrite(out, 2, B64CRLF);
1413 if (count == -1)
1414 return -1;
1415 sum += count;
1416 linelen = 0;
1417 }
1418 count = xmlOutputBufferWrite(out, 4, (const char *) ogroup);
1419 if (count == -1)
1420 return -1;
1421 sum += count;
1422
1423 linelen += 4;
1424 }
Daniel Veillard929714b2003-10-22 12:34:36 +00001425
1426 if (i >= len)
1427 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001428 }
1429
Daniel Veillard1d211e22003-10-20 22:32:39 +00001430 return sum;
1431}
1432
1433/**
1434 * xmlTextWriterWriteBase64:
1435 * @writer: the xmlTextWriterPtr
1436 * @data: binary data
1437 * @start: the position within the data of the first byte to encode
1438 * @len: the number of bytes to encode
1439 *
1440 * Write an base64 encoded xml text.
1441 *
1442 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1443 */
1444int
Daniel Veillardab69f362004-02-17 11:40:32 +00001445xmlTextWriterWriteBase64(xmlTextWriterPtr writer, const char *data,
Daniel Veillard1d211e22003-10-20 22:32:39 +00001446 int start, int len)
1447{
1448 int count;
1449 int sum;
1450 xmlLinkPtr lk;
1451 xmlTextWriterStackEntry *p;
1452
1453 if (writer == NULL)
1454 return -1;
1455
Daniel Veillard1d211e22003-10-20 22:32:39 +00001456 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001457 lk = xmlListFront(writer->nodes);
1458 if (lk != 0) {
1459 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1460 if (p != 0) {
1461 count = xmlTextWriterHandleStateDependencies(writer, p);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001462 if (count < 0)
1463 return -1;
1464 sum += count;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001465 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001466 }
1467
Daniel Veillardab69f362004-02-17 11:40:32 +00001468 if (writer->indent)
1469 writer->doindent = 0;
1470
Daniel Veillard1d211e22003-10-20 22:32:39 +00001471 count =
1472 xmlOutputBufferWriteBase64(writer->out, len,
1473 (unsigned char *) data + start);
1474 if (count < 0)
1475 return -1;
1476 sum += count;
1477
1478 return sum;
1479}
1480
1481/**
1482 * xmlOutputBufferWriteBinHex:
1483 * @out: the xmlOutputBufferPtr
1484 * @data: binary data
1485 * @len: the number of bytes to encode
1486 *
1487 * Write hqx encoded data to an xmlOutputBuffer.
1488 * ::todo
1489 *
1490 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1491 */
1492static int
Daniel Veillardab69f362004-02-17 11:40:32 +00001493xmlOutputBufferWriteBinHex(xmlOutputBufferPtr out,
1494 int len, const unsigned char *data)
Daniel Veillard1d211e22003-10-20 22:32:39 +00001495{
Daniel Veillardab69f362004-02-17 11:40:32 +00001496 int count;
1497 int sum;
1498 static char hex[] = "0123456789ABCDEF";
1499 int i;
1500
1501 if ((out == NULL) || ((data == 0) && (len != 0))) {
1502 return -1;
1503 }
1504
1505 sum = 0;
1506 for (i = 0; i < len; i++) {
1507 count =
1508 xmlOutputBufferWrite(out, 1,
1509 (const char *) &hex[data[i] >> 4]);
1510 if (count == -1)
1511 return -1;
1512 sum += count;
1513 count =
1514 xmlOutputBufferWrite(out, 1,
1515 (const char *) &hex[data[i] & 0xF]);
1516 if (count == -1)
1517 return -1;
1518 sum += count;
1519 }
1520
1521 return sum;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001522}
1523
1524/**
1525 * xmlTextWriterWriteBinHex:
1526 * @writer: the xmlTextWriterPtr
1527 * @data: binary data
1528 * @start: the position within the data of the first byte to encode
1529 * @len: the number of bytes to encode
1530 *
1531 * Write a BinHex encoded xml text.
1532 *
1533 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1534 */
1535int
Daniel Veillardab69f362004-02-17 11:40:32 +00001536xmlTextWriterWriteBinHex(xmlTextWriterPtr writer, const char *data,
Daniel Veillard1d211e22003-10-20 22:32:39 +00001537 int start, int len)
1538{
1539 int count;
1540 int sum;
1541 xmlLinkPtr lk;
1542 xmlTextWriterStackEntry *p;
1543
1544 if (writer == NULL)
1545 return -1;
1546
Daniel Veillard1d211e22003-10-20 22:32:39 +00001547 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001548 lk = xmlListFront(writer->nodes);
1549 if (lk != 0) {
1550 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1551 if (p != 0) {
1552 count = xmlTextWriterHandleStateDependencies(writer, p);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001553 if (count < 0)
1554 return -1;
1555 sum += count;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001556 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001557 }
1558
Daniel Veillardab69f362004-02-17 11:40:32 +00001559 if (writer->indent)
1560 writer->doindent = 0;
1561
Daniel Veillard1d211e22003-10-20 22:32:39 +00001562 count =
1563 xmlOutputBufferWriteBinHex(writer->out, len,
1564 (unsigned char *) data + start);
1565 if (count < 0)
1566 return -1;
1567 sum += count;
1568
1569 return sum;
1570}
1571
1572/**
1573 * xmlTextWriterStartAttribute:
1574 * @writer: the xmlTextWriterPtr
1575 * @name: element name
1576 *
1577 * Start an xml attribute.
1578 *
1579 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1580 */
1581int
1582xmlTextWriterStartAttribute(xmlTextWriterPtr writer, const xmlChar * name)
1583{
1584 int count;
1585 int sum;
1586 xmlLinkPtr lk;
1587 xmlTextWriterStackEntry *p;
1588
1589 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1590 return -1;
1591
1592 sum = 0;
1593 lk = xmlListFront(writer->nodes);
1594 if (lk == 0)
1595 return -1;
1596
1597 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1598 if (p == 0)
1599 return -1;
1600
1601 switch (p->state) {
1602 case XML_TEXTWRITER_ATTRIBUTE:
1603 count = xmlTextWriterEndAttribute(writer);
1604 if (count < 0)
1605 return -1;
1606 sum += count;
1607 /* fallthrough */
1608 case XML_TEXTWRITER_NAME:
1609 count = xmlOutputBufferWriteString(writer->out, " ");
1610 if (count < 0)
1611 return -1;
1612 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00001613 count =
1614 xmlOutputBufferWriteString(writer->out,
1615 (const char *) name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001616 if (count < 0)
1617 return -1;
1618 sum += count;
1619 count = xmlOutputBufferWriteString(writer->out, "=");
1620 if (count < 0)
1621 return -1;
1622 sum += count;
1623 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
1624 if (count < 0)
1625 return -1;
1626 sum += count;
1627 p->state = XML_TEXTWRITER_ATTRIBUTE;
1628 break;
1629 default:
1630 return -1;
1631 }
1632
1633 return sum;
1634}
1635
1636/**
1637 * xmlTextWriterStartAttributeNS:
1638 * @writer: the xmlTextWriterPtr
1639 * @prefix: namespace prefix or NULL
1640 * @name: element local name
1641 * @namespaceURI: namespace URI or NULL
1642 *
1643 * Start an xml attribute with namespace support.
1644 *
1645 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1646 */
1647int
1648xmlTextWriterStartAttributeNS(xmlTextWriterPtr writer,
1649 const xmlChar * prefix, const xmlChar * name,
1650 const xmlChar * namespaceURI)
1651{
1652 int count;
1653 int sum;
1654 xmlChar *buf;
1655 xmlTextWriterNsStackEntry *p;
1656
1657 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1658 return -1;
1659
1660 buf = 0;
1661 if (prefix != 0) {
1662 buf = xmlStrdup(prefix);
1663 buf = xmlStrcat(buf, BAD_CAST ":");
1664 }
1665 buf = xmlStrcat(buf, name);
1666
1667 sum = 0;
1668 count = xmlTextWriterStartAttribute(writer, buf);
1669 xmlFree(buf);
1670 if (count < 0)
1671 return -1;
1672 sum += count;
1673
1674 if (namespaceURI != 0) {
1675 buf = xmlStrdup(BAD_CAST "xmlns");
1676 if (prefix != 0) {
1677 buf = xmlStrcat(buf, BAD_CAST ":");
1678 buf = xmlStrcat(buf, prefix);
1679 }
1680
1681 p = (xmlTextWriterNsStackEntry *)
1682 xmlMalloc(sizeof(xmlTextWriterNsStackEntry));
1683 if (p == 0) {
1684 xmlGenericError(xmlGenericErrorContext,
1685 "xmlTextWriterStartAttributeNS : out of memory!\n");
1686 return -1;
1687 }
1688
1689 p->prefix = buf;
1690 p->uri = xmlStrdup(namespaceURI);
1691 if (p->uri == 0) {
1692 xmlGenericError(xmlGenericErrorContext,
1693 "xmlTextWriterStartAttributeNS : out of memory!\n");
1694 xmlFree(p);
1695 return -1;
1696 }
1697 p->elem = xmlListFront(writer->nodes);
1698
1699 xmlListPushFront(writer->nsstack, p);
1700 }
1701
1702 return sum;
1703}
1704
1705/**
1706 * xmlTextWriterEndAttribute:
1707 * @writer: the xmlTextWriterPtr
1708 *
1709 * End the current xml element.
1710 *
1711 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1712 */
1713int
1714xmlTextWriterEndAttribute(xmlTextWriterPtr writer)
1715{
1716 int count;
1717 int sum;
1718 xmlLinkPtr lk;
1719 xmlTextWriterStackEntry *p;
1720 xmlTextWriterNsStackEntry *np;
1721
1722 if (writer == NULL)
1723 return -1;
1724
1725 lk = xmlListFront(writer->nodes);
1726 if (lk == 0) {
1727 xmlListDelete(writer->nsstack);
1728 return -1;
1729 }
1730
1731 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1732 if (p == 0) {
1733 xmlListDelete(writer->nsstack);
1734 return -1;
1735 }
1736
1737 sum = 0;
1738 switch (p->state) {
1739 case XML_TEXTWRITER_ATTRIBUTE:
1740 p->state = XML_TEXTWRITER_NAME;
1741
1742 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
1743 if (count < 0) {
1744 xmlListDelete(writer->nsstack);
1745 return -1;
1746 }
1747 sum += count;
1748
1749 while (!xmlListEmpty(writer->nsstack)) {
1750 lk = xmlListFront(writer->nsstack);
1751 np = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
1752 if (np != 0) {
1753 count =
1754 xmlTextWriterWriteAttribute(writer, np->prefix,
1755 np->uri);
1756 if (count < 0) {
1757 xmlListDelete(writer->nsstack);
1758 return -1;
1759 }
1760 sum += count;
1761 }
1762
1763 xmlListPopFront(writer->nsstack);
1764 }
1765 break;
1766
1767 default:
1768 xmlListClear(writer->nsstack);
1769 return -1;
1770 }
1771
1772 return sum;
1773}
1774
1775/**
1776 * xmlTextWriterWriteFormatAttribute:
1777 * @writer: the xmlTextWriterPtr
1778 * @name: attribute name
1779 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001780 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001781 *
1782 * Write a formatted xml attribute.
1783 *
1784 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1785 */
1786int
1787xmlTextWriterWriteFormatAttribute(xmlTextWriterPtr writer,
1788 const xmlChar * name, const char *format,
1789 ...)
1790{
1791 int rc;
1792 va_list ap;
1793
1794 va_start(ap, format);
1795
1796 rc = xmlTextWriterWriteVFormatAttribute(writer, name, format, ap);
1797
1798 va_end(ap);
1799 return rc;
1800}
1801
1802/**
1803 * xmlTextWriterWriteVFormatAttribute:
1804 * @writer: the xmlTextWriterPtr
1805 * @name: attribute name
1806 * @format: format string (see printf)
1807 * @argptr: pointer to the first member of the variable argument list.
1808 *
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
1814xmlTextWriterWriteVFormatAttribute(xmlTextWriterPtr writer,
1815 const xmlChar * name,
1816 const char *format, va_list argptr)
1817{
1818 int rc;
1819 xmlChar *buf;
1820
1821 if (writer == NULL)
1822 return -1;
1823
1824 buf = xmlTextWriterVSprintf(format, argptr);
1825 if (buf == 0)
1826 return 0;
1827
1828 rc = xmlTextWriterWriteAttribute(writer, name, buf);
1829
1830 xmlFree(buf);
1831 return rc;
1832}
1833
1834/**
1835 * xmlTextWriterWriteAttribute:
1836 * @writer: the xmlTextWriterPtr
1837 * @name: attribute name
1838 * @content: attribute content
1839 *
1840 * Write an xml attribute.
1841 *
1842 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1843 */
1844int
1845xmlTextWriterWriteAttribute(xmlTextWriterPtr writer, const xmlChar * name,
1846 const xmlChar * content)
1847{
1848 int count;
1849 int sum;
1850
1851 sum = 0;
1852 count = xmlTextWriterStartAttribute(writer, name);
1853 if (count < 0)
1854 return -1;
1855 sum += count;
1856 count = xmlTextWriterWriteString(writer, content);
1857 if (count < 0)
1858 return -1;
1859 sum += count;
1860 count = xmlTextWriterEndAttribute(writer);
1861 if (count < 0)
1862 return -1;
1863 sum += count;
1864
1865 return sum;
1866}
1867
1868/**
1869 * xmlTextWriterWriteFormatAttributeNS:
1870 * @writer: the xmlTextWriterPtr
1871 * @prefix: namespace prefix
1872 * @name: attribute local name
1873 * @namespaceURI: namespace URI
1874 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001875 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001876 *
1877 * Write a formatted xml attribute.with namespace support
1878 *
1879 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1880 */
1881int
1882xmlTextWriterWriteFormatAttributeNS(xmlTextWriterPtr writer,
1883 const xmlChar * prefix,
1884 const xmlChar * name,
1885 const xmlChar * namespaceURI,
1886 const char *format, ...)
1887{
1888 int rc;
1889 va_list ap;
1890
1891 va_start(ap, format);
1892
1893 rc = xmlTextWriterWriteVFormatAttributeNS(writer, prefix, name,
1894 namespaceURI, format, ap);
1895
1896 va_end(ap);
1897 return rc;
1898}
1899
1900/**
1901 * xmlTextWriterWriteVFormatAttributeNS:
1902 * @writer: the xmlTextWriterPtr
1903 * @prefix: namespace prefix
1904 * @name: attribute local name
1905 * @namespaceURI: namespace URI
1906 * @format: format string (see printf)
1907 * @argptr: pointer to the first member of the variable argument list.
1908 *
1909 * Write a formatted xml attribute.with namespace support
1910 *
1911 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1912 */
1913int
1914xmlTextWriterWriteVFormatAttributeNS(xmlTextWriterPtr writer,
1915 const xmlChar * prefix,
1916 const xmlChar * name,
1917 const xmlChar * namespaceURI,
1918 const char *format, va_list argptr)
1919{
1920 int rc;
1921 xmlChar *buf;
1922
1923 if (writer == NULL)
1924 return -1;
1925
1926 buf = xmlTextWriterVSprintf(format, argptr);
1927 if (buf == 0)
1928 return 0;
1929
1930 rc = xmlTextWriterWriteAttributeNS(writer, prefix, name, namespaceURI,
1931 buf);
1932
1933 xmlFree(buf);
1934 return rc;
1935}
1936
1937/**
1938 * xmlTextWriterWriteAttributeNS:
1939 * @writer: the xmlTextWriterPtr
1940 * @prefix: namespace prefix
1941 * @name: attribute local name
1942 * @namespaceURI: namespace URI
1943 * @content: attribute content
1944 *
1945 * Write an xml attribute.
1946 *
1947 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1948 */
1949int
1950xmlTextWriterWriteAttributeNS(xmlTextWriterPtr writer,
1951 const xmlChar * prefix, const xmlChar * name,
1952 const xmlChar * namespaceURI,
1953 const xmlChar * content)
1954{
1955 int count;
1956 int sum;
1957 xmlChar *buf;
1958
1959 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1960 return -1;
1961
1962 buf = 0;
1963 if (prefix != NULL) {
1964 buf = xmlStrdup(prefix);
1965 buf = xmlStrcat(buf, BAD_CAST ":");
1966 }
1967 buf = xmlStrcat(buf, name);
1968
1969 sum = 0;
1970 count = xmlTextWriterWriteAttribute(writer, buf, content);
1971 xmlFree(buf);
1972 if (count < 0)
1973 return -1;
1974 sum += count;
1975
1976 if (namespaceURI != NULL) {
1977 buf = 0;
1978 buf = xmlStrdup(BAD_CAST "xmlns");
1979 if (prefix != NULL) {
1980 buf = xmlStrcat(buf, BAD_CAST ":");
1981 buf = xmlStrcat(buf, prefix);
1982 }
1983 count = xmlTextWriterWriteAttribute(writer, buf, namespaceURI);
1984 xmlFree(buf);
1985 if (count < 0)
1986 return -1;
1987 sum += count;
1988 }
1989 return sum;
1990}
1991
1992/**
1993 * xmlTextWriterWriteFormatElement:
1994 * @writer: the xmlTextWriterPtr
1995 * @name: element name
1996 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001997 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001998 *
1999 * Write a formatted xml element.
2000 *
2001 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2002 */
2003int
2004xmlTextWriterWriteFormatElement(xmlTextWriterPtr writer,
2005 const xmlChar * name, const char *format,
2006 ...)
2007{
2008 int rc;
2009 va_list ap;
2010
2011 va_start(ap, format);
2012
2013 rc = xmlTextWriterWriteVFormatElement(writer, name, format, ap);
2014
2015 va_end(ap);
2016 return rc;
2017}
2018
2019/**
2020 * xmlTextWriterWriteVFormatElement:
2021 * @writer: the xmlTextWriterPtr
2022 * @name: element name
2023 * @format: format string (see printf)
2024 * @argptr: pointer to the first member of the variable argument list.
2025 *
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
2031xmlTextWriterWriteVFormatElement(xmlTextWriterPtr writer,
2032 const xmlChar * name, const char *format,
2033 va_list argptr)
2034{
2035 int rc;
2036 xmlChar *buf;
2037
2038 if (writer == NULL)
2039 return -1;
2040
2041 buf = xmlTextWriterVSprintf(format, argptr);
2042 if (buf == 0)
2043 return 0;
2044
2045 rc = xmlTextWriterWriteElement(writer, name, buf);
2046
2047 xmlFree(buf);
2048 return rc;
2049}
2050
2051/**
2052 * xmlTextWriterWriteElement:
2053 * @writer: the xmlTextWriterPtr
2054 * @name: element name
2055 * @content: element content
2056 *
2057 * Write an xml element.
2058 *
2059 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2060 */
2061int
2062xmlTextWriterWriteElement(xmlTextWriterPtr writer, const xmlChar * name,
2063 const xmlChar * content)
2064{
2065 int count;
2066 int sum;
2067
2068 sum = 0;
2069 count = xmlTextWriterStartElement(writer, name);
2070 if (count == -1)
2071 return -1;
2072 sum += count;
2073 count = xmlTextWriterWriteString(writer, content);
2074 if (count == -1)
2075 return -1;
2076 sum += count;
2077 count = xmlTextWriterEndElement(writer);
2078 if (count == -1)
2079 return -1;
2080 sum += count;
2081
2082 return sum;
2083}
2084
2085/**
2086 * xmlTextWriterWriteFormatElementNS:
2087 * @writer: the xmlTextWriterPtr
2088 * @prefix: namespace prefix
2089 * @name: element local name
2090 * @namespaceURI: namespace URI
2091 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002092 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002093 *
2094 * Write a formatted xml element with namespace support.
2095 *
2096 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2097 */
2098int
2099xmlTextWriterWriteFormatElementNS(xmlTextWriterPtr writer,
2100 const xmlChar * prefix,
2101 const xmlChar * name,
2102 const xmlChar * namespaceURI,
2103 const char *format, ...)
2104{
2105 int rc;
2106 va_list ap;
2107
2108 va_start(ap, format);
2109
2110 rc = xmlTextWriterWriteVFormatElementNS(writer, prefix, name,
2111 namespaceURI, format, ap);
2112
2113 va_end(ap);
2114 return rc;
2115}
2116
2117/**
2118 * xmlTextWriterWriteVFormatElementNS:
2119 * @writer: the xmlTextWriterPtr
2120 * @prefix: namespace prefix
2121 * @name: element local name
2122 * @namespaceURI: namespace URI
2123 * @format: format string (see printf)
2124 * @argptr: pointer to the first member of the variable argument list.
2125 *
2126 * Write a formatted xml element with namespace support.
2127 *
2128 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2129 */
2130int
2131xmlTextWriterWriteVFormatElementNS(xmlTextWriterPtr writer,
2132 const xmlChar * prefix,
2133 const xmlChar * name,
2134 const xmlChar * namespaceURI,
2135 const char *format, va_list argptr)
2136{
2137 int rc;
2138 xmlChar *buf;
2139
2140 if (writer == NULL)
2141 return -1;
2142
2143 buf = xmlTextWriterVSprintf(format, argptr);
2144 if (buf == 0)
2145 return 0;
2146
2147 rc = xmlTextWriterWriteElementNS(writer, prefix, name, namespaceURI,
2148 buf);
2149
2150 xmlFree(buf);
2151 return rc;
2152}
2153
2154/**
2155 * xmlTextWriterWriteElementNS:
2156 * @writer: the xmlTextWriterPtr
2157 * @prefix: namespace prefix
2158 * @name: element local name
2159 * @namespaceURI: namespace URI
2160 * @content: element content
2161 *
2162 * Write an xml element with namespace support.
2163 *
2164 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2165 */
2166int
2167xmlTextWriterWriteElementNS(xmlTextWriterPtr writer,
2168 const xmlChar * prefix, const xmlChar * name,
2169 const xmlChar * namespaceURI,
2170 const xmlChar * content)
2171{
2172 int count;
2173 int sum;
2174
2175 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
2176 return -1;
2177
2178 sum = 0;
2179 count =
2180 xmlTextWriterStartElementNS(writer, prefix, name, namespaceURI);
2181 if (count < 0)
2182 return -1;
2183 sum += count;
2184 count = xmlTextWriterWriteString(writer, content);
2185 if (count == -1)
2186 return -1;
2187 sum += count;
2188 count = xmlTextWriterEndElement(writer);
2189 if (count == -1)
2190 return -1;
2191 sum += count;
2192
2193 return sum;
2194}
2195
2196/**
2197 * xmlTextWriterStartPI:
2198 * @writer: the xmlTextWriterPtr
2199 * @target: PI target
2200 *
2201 * Start an xml PI.
2202 *
2203 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2204 */
2205int
2206xmlTextWriterStartPI(xmlTextWriterPtr writer, const xmlChar * target)
2207{
2208 int count;
2209 int sum;
2210 xmlLinkPtr lk;
2211 xmlTextWriterStackEntry *p;
2212
2213 if ((writer == NULL) || (target == NULL) || (*target == '\0'))
2214 return -1;
2215
2216 if (xmlStrcasecmp(target, (const xmlChar *) "xml") == 0) {
2217 xmlGenericError(xmlGenericErrorContext,
2218 "xmlTextWriterStartPI : target name [Xx][Mm][Ll] is reserved for xml standardization!\n");
2219 return -1;
2220 }
2221
2222 sum = 0;
2223 lk = xmlListFront(writer->nodes);
2224 if (lk != 0) {
2225 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2226 if (p != 0) {
2227 switch (p->state) {
2228 case XML_TEXTWRITER_ATTRIBUTE:
2229 count = xmlTextWriterEndAttribute(writer);
2230 if (count < 0)
2231 return -1;
2232 sum += count;
2233 /* fallthrough */
2234 case XML_TEXTWRITER_NAME:
2235 count = xmlOutputBufferWriteString(writer->out, ">");
2236 if (count < 0)
2237 return -1;
2238 sum += count;
2239 p->state = XML_TEXTWRITER_TEXT;
2240 break;
Daniel Veillardab69f362004-02-17 11:40:32 +00002241 case XML_TEXTWRITER_NONE:
2242 case XML_TEXTWRITER_TEXT:
2243 case XML_TEXTWRITER_DTD:
2244 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002245 case XML_TEXTWRITER_PI:
2246 case XML_TEXTWRITER_PI_TEXT:
2247 xmlGenericError(xmlGenericErrorContext,
2248 "xmlTextWriterStartPI : nested PI!\n");
2249 return -1;
2250 default:
2251 return -1;
2252 }
2253 }
2254 }
2255
2256 p = (xmlTextWriterStackEntry *)
2257 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2258 if (p == 0) {
2259 xmlGenericError(xmlGenericErrorContext,
2260 "xmlTextWriterStartPI : out of memory!\n");
2261 return -1;
2262 }
2263
2264 p->name = xmlStrdup(target);
2265 if (p->name == 0) {
2266 xmlGenericError(xmlGenericErrorContext,
2267 "xmlTextWriterStartPI : out of memory!\n");
2268 xmlFree(p);
2269 return -1;
2270 }
2271 p->state = XML_TEXTWRITER_PI;
2272
2273 xmlListPushFront(writer->nodes, p);
2274
2275 count = xmlOutputBufferWriteString(writer->out, "<?");
2276 if (count < 0)
2277 return -1;
2278 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002279 count =
2280 xmlOutputBufferWriteString(writer->out, (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002281 if (count < 0)
2282 return -1;
2283 sum += count;
2284
2285 return sum;
2286}
2287
2288/**
2289 * xmlTextWriterEndPI:
2290 * @writer: the xmlTextWriterPtr
2291 *
2292 * End the current xml PI.
2293 *
2294 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2295 */
2296int
2297xmlTextWriterEndPI(xmlTextWriterPtr writer)
2298{
2299 int count;
2300 int sum;
2301 xmlLinkPtr lk;
2302 xmlTextWriterStackEntry *p;
2303
2304 if (writer == NULL)
2305 return -1;
2306
2307 lk = xmlListFront(writer->nodes);
2308 if (lk == 0)
2309 return 0;
2310
2311 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2312 if (p == 0)
2313 return 0;
2314
2315 sum = 0;
2316 switch (p->state) {
2317 case XML_TEXTWRITER_PI:
2318 case XML_TEXTWRITER_PI_TEXT:
2319 count = xmlOutputBufferWriteString(writer->out, "?>");
2320 if (count < 0)
2321 return -1;
2322 sum += count;
2323 break;
2324 default:
2325 return -1;
2326 }
2327
2328 xmlListPopFront(writer->nodes);
2329 return sum;
2330}
2331
2332/**
2333 * xmlTextWriterWriteFormatPI:
2334 * @writer: the xmlTextWriterPtr
2335 * @target: PI target
2336 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002337 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002338 *
2339 * Write a formatted PI.
2340 *
2341 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2342 */
2343int
2344xmlTextWriterWriteFormatPI(xmlTextWriterPtr writer, const xmlChar * target,
2345 const char *format, ...)
2346{
2347 int rc;
2348 va_list ap;
2349
2350 va_start(ap, format);
2351
2352 rc = xmlTextWriterWriteVFormatPI(writer, target, format, ap);
2353
2354 va_end(ap);
2355 return rc;
2356}
2357
2358/**
2359 * xmlTextWriterWriteVFormatPI:
2360 * @writer: the xmlTextWriterPtr
2361 * @target: PI target
2362 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002363 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00002364 *
2365 * Write a formatted xml PI.
2366 *
2367 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2368 */
2369int
2370xmlTextWriterWriteVFormatPI(xmlTextWriterPtr writer,
2371 const xmlChar * target, const char *format,
2372 va_list argptr)
2373{
2374 int rc;
2375 xmlChar *buf;
2376
2377 if (writer == NULL)
2378 return -1;
2379
2380 buf = xmlTextWriterVSprintf(format, argptr);
2381 if (buf == 0)
2382 return 0;
2383
2384 rc = xmlTextWriterWritePI(writer, target, buf);
2385
2386 xmlFree(buf);
2387 return rc;
2388}
2389
2390/**
2391 * xmlTextWriterWritePI:
2392 * @writer: the xmlTextWriterPtr
2393 * @target: PI target
2394 * @content: PI content
2395 *
2396 * Write an xml PI.
2397 *
2398 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2399 */
2400int
2401xmlTextWriterWritePI(xmlTextWriterPtr writer, const xmlChar * target,
2402 const xmlChar * content)
2403{
2404 int count;
2405 int sum;
2406
2407 sum = 0;
2408 count = xmlTextWriterStartPI(writer, target);
2409 if (count == -1)
2410 return -1;
2411 sum += count;
2412 if (content != 0) {
2413 count = xmlTextWriterWriteString(writer, content);
2414 if (count == -1)
2415 return -1;
2416 sum += count;
2417 }
2418 count = xmlTextWriterEndPI(writer);
2419 if (count == -1)
2420 return -1;
2421 sum += count;
2422
2423 return sum;
2424}
2425
2426/**
2427 * xmlTextWriterStartCDATA:
2428 * @writer: the xmlTextWriterPtr
2429 *
2430 * Start an xml CDATA section.
2431 *
2432 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2433 */
2434int
2435xmlTextWriterStartCDATA(xmlTextWriterPtr writer)
2436{
2437 int count;
2438 int sum;
2439 xmlLinkPtr lk;
2440 xmlTextWriterStackEntry *p;
2441
2442 if (writer == NULL)
2443 return -1;
2444
2445 sum = 0;
2446 lk = xmlListFront(writer->nodes);
2447 if (lk != 0) {
2448 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2449 if (p != 0) {
2450 switch (p->state) {
2451 case XML_TEXTWRITER_NONE:
2452 case XML_TEXTWRITER_PI:
2453 case XML_TEXTWRITER_PI_TEXT:
2454 break;
2455 case XML_TEXTWRITER_ATTRIBUTE:
2456 count = xmlTextWriterEndAttribute(writer);
2457 if (count < 0)
2458 return -1;
2459 sum += count;
2460 /* fallthrough */
2461 case XML_TEXTWRITER_NAME:
2462 count = xmlOutputBufferWriteString(writer->out, ">");
2463 if (count < 0)
2464 return -1;
2465 sum += count;
2466 p->state = XML_TEXTWRITER_TEXT;
2467 break;
2468 case XML_TEXTWRITER_CDATA:
2469 xmlGenericError(xmlGenericErrorContext,
2470 "xmlTextWriterStartCDATA : CDATA not allowed in this context!\n");
2471 return -1;
2472 default:
2473 return -1;
2474 }
2475 }
2476 }
2477
2478 p = (xmlTextWriterStackEntry *)
2479 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2480 if (p == 0) {
2481 xmlGenericError(xmlGenericErrorContext,
2482 "xmlTextWriterStartCDATA : out of memory!\n");
2483 return -1;
2484 }
2485
2486 p->name = 0;
2487 p->state = XML_TEXTWRITER_CDATA;
2488
2489 xmlListPushFront(writer->nodes, p);
2490
2491 count = xmlOutputBufferWriteString(writer->out, "<![CDATA[");
2492 if (count < 0)
2493 return -1;
2494 sum += count;
2495
2496 return sum;
2497}
2498
2499/**
2500 * xmlTextWriterEndCDATA:
2501 * @writer: the xmlTextWriterPtr
2502 *
2503 * End an xml CDATA section.
2504 *
2505 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2506 */
2507int
2508xmlTextWriterEndCDATA(xmlTextWriterPtr writer)
2509{
2510 int count;
2511 int sum;
2512 xmlLinkPtr lk;
2513 xmlTextWriterStackEntry *p;
2514
2515 if (writer == NULL)
2516 return -1;
2517
2518 lk = xmlListFront(writer->nodes);
2519 if (lk == 0)
2520 return -1;
2521
2522 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2523 if (p == 0)
2524 return -1;
2525
2526 sum = 0;
2527 switch (p->state) {
2528 case XML_TEXTWRITER_CDATA:
2529 count = xmlOutputBufferWriteString(writer->out, "]]>");
2530 if (count < 0)
2531 return -1;
2532 sum += count;
2533 break;
2534 default:
2535 return -1;
2536 }
2537
2538 xmlListPopFront(writer->nodes);
2539 return sum;
2540}
2541
2542/**
2543 * xmlTextWriterWriteFormatCDATA:
2544 * @writer: the xmlTextWriterPtr
2545 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002546 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002547 *
2548 * Write a formatted xml CDATA.
2549 *
2550 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2551 */
2552int
2553xmlTextWriterWriteFormatCDATA(xmlTextWriterPtr writer, const char *format,
2554 ...)
2555{
2556 int rc;
2557 va_list ap;
2558
2559 va_start(ap, format);
2560
2561 rc = xmlTextWriterWriteVFormatCDATA(writer, format, ap);
2562
2563 va_end(ap);
2564 return rc;
2565}
2566
2567/**
2568 * xmlTextWriterWriteVFormatCDATA:
2569 * @writer: the xmlTextWriterPtr
2570 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002571 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00002572 *
2573 * Write a formatted xml CDATA.
2574 *
2575 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2576 */
2577int
2578xmlTextWriterWriteVFormatCDATA(xmlTextWriterPtr writer, const char *format,
2579 va_list argptr)
2580{
2581 int rc;
2582 xmlChar *buf;
2583
2584 if (writer == NULL)
2585 return -1;
2586
2587 buf = xmlTextWriterVSprintf(format, argptr);
2588 if (buf == 0)
2589 return 0;
2590
2591 rc = xmlTextWriterWriteCDATA(writer, buf);
2592
2593 xmlFree(buf);
2594 return rc;
2595}
2596
2597/**
2598 * xmlTextWriterWriteCDATA:
2599 * @writer: the xmlTextWriterPtr
2600 * @content: CDATA content
2601 *
2602 * Write an xml CDATA.
2603 *
2604 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2605 */
2606int
2607xmlTextWriterWriteCDATA(xmlTextWriterPtr writer, const xmlChar * content)
2608{
2609 int count;
2610 int sum;
2611
2612 sum = 0;
2613 count = xmlTextWriterStartCDATA(writer);
2614 if (count == -1)
2615 return -1;
2616 sum += count;
2617 if (content != 0) {
2618 count = xmlTextWriterWriteString(writer, content);
2619 if (count == -1)
2620 return -1;
2621 sum += count;
2622 }
2623 count = xmlTextWriterEndCDATA(writer);
2624 if (count == -1)
2625 return -1;
2626 sum += count;
2627
2628 return sum;
2629}
2630
2631/**
2632 * xmlTextWriterStartDTD:
2633 * @writer: the xmlTextWriterPtr
2634 * @name: the name of the DTD
2635 * @pubid: the public identifier, which is an alternative to the system identifier
2636 * @sysid: the system identifier, which is the URI of the DTD
2637 *
2638 * Start an xml DTD.
2639 *
2640 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2641 */
2642int
2643xmlTextWriterStartDTD(xmlTextWriterPtr writer,
2644 const xmlChar * name,
2645 const xmlChar * pubid, const xmlChar * sysid)
2646{
2647 int count;
2648 int sum;
2649 xmlLinkPtr lk;
2650 xmlTextWriterStackEntry *p;
2651
2652 if (writer == NULL || name == NULL || *name == '\0')
2653 return -1;
2654
2655 sum = 0;
2656 lk = xmlListFront(writer->nodes);
Daniel Veillardab69f362004-02-17 11:40:32 +00002657 if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) {
Daniel Veillard1d211e22003-10-20 22:32:39 +00002658 xmlGenericError(xmlGenericErrorContext,
2659 "xmlTextWriterStartDTD : DTD allowed only in prolog!\n");
2660 return -1;
2661 }
2662
2663 p = (xmlTextWriterStackEntry *)
2664 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2665 if (p == 0) {
2666 xmlGenericError(xmlGenericErrorContext,
2667 "xmlTextWriterStartDTD : out of memory!\n");
2668 return -1;
2669 }
2670
2671 p->name = xmlStrdup(name);
2672 if (p->name == 0) {
2673 xmlGenericError(xmlGenericErrorContext,
2674 "xmlTextWriterStartDTD : out of memory!\n");
2675 xmlFree(p);
2676 return -1;
2677 }
2678 p->state = XML_TEXTWRITER_DTD;
2679
2680 xmlListPushFront(writer->nodes, p);
2681
2682 count = xmlOutputBufferWriteString(writer->out, "<!DOCTYPE ");
2683 if (count < 0)
2684 return -1;
2685 sum += count;
2686 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
2687 if (count < 0)
2688 return -1;
2689 sum += count;
2690
2691 if (pubid != 0) {
2692 if (sysid == 0) {
2693 xmlGenericError(xmlGenericErrorContext,
2694 "xmlTextWriterStartDTD : system identifier needed!\n");
2695 return -1;
2696 }
2697
Daniel Veillard500a1de2004-03-22 15:22:58 +00002698 if (writer->indent)
2699 count = xmlOutputBufferWrite(writer->out, 1, "\n");
2700 else
2701 count = xmlOutputBufferWrite(writer->out, 1, " ");
2702 if (count < 0)
2703 return -1;
2704 sum += count;
2705
2706 count = xmlOutputBufferWriteString(writer->out, "PUBLIC ");
2707 if (count < 0)
2708 return -1;
2709 sum += count;
2710
2711 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002712 if (count < 0)
2713 return -1;
2714 sum += count;
2715
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002716 count =
2717 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002718 if (count < 0)
2719 return -1;
2720 sum += count;
2721
Daniel Veillard500a1de2004-03-22 15:22:58 +00002722 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002723 if (count < 0)
2724 return -1;
2725 sum += count;
2726 }
2727
2728 if (sysid != 0) {
2729 if (pubid == 0) {
Daniel Veillard500a1de2004-03-22 15:22:58 +00002730 if (writer->indent)
2731 count = xmlOutputBufferWrite(writer->out, 1, "\n");
2732 else
2733 count = xmlOutputBufferWrite(writer->out, 1, " ");
2734 if (count < 0)
2735 return -1;
2736 sum += count;
2737 count = xmlOutputBufferWriteString(writer->out, "SYSTEM ");
2738 if (count < 0)
2739 return -1;
2740 sum += count;
2741 } else if (writer->indent) {
2742 count = xmlOutputBufferWriteString(writer->out, "\n ");
Daniel Veillard1d211e22003-10-20 22:32:39 +00002743 if (count < 0)
2744 return -1;
2745 sum += count;
2746 }
2747
Daniel Veillard500a1de2004-03-22 15:22:58 +00002748 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002749 if (count < 0)
2750 return -1;
2751 sum += count;
2752
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002753 count =
2754 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002755 if (count < 0)
2756 return -1;
2757 sum += count;
2758
Daniel Veillard500a1de2004-03-22 15:22:58 +00002759 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002760 if (count < 0)
2761 return -1;
2762 sum += count;
2763 }
2764
2765 return sum;
2766}
2767
2768/**
2769 * xmlTextWriterEndDTD:
2770 * @writer: the xmlTextWriterPtr
2771 *
2772 * End an xml DTD.
2773 *
2774 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2775 */
2776int
2777xmlTextWriterEndDTD(xmlTextWriterPtr writer)
2778{
Daniel Veillard500a1de2004-03-22 15:22:58 +00002779 int loop;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002780 int count;
2781 int sum;
2782 xmlLinkPtr lk;
2783 xmlTextWriterStackEntry *p;
2784
2785 if (writer == NULL)
2786 return -1;
2787
2788 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00002789 loop = 1;
2790 while (loop) {
2791 lk = xmlListFront(writer->nodes);
2792 if (lk == NULL)
Daniel Veillard1d211e22003-10-20 22:32:39 +00002793 break;
Daniel Veillard500a1de2004-03-22 15:22:58 +00002794 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2795 if (p == 0)
2796 break;
2797 switch (p->state) {
2798 case XML_TEXTWRITER_DTD_TEXT:
2799 count = xmlOutputBufferWriteString(writer->out, "]");
2800 if (count < 0)
2801 return -1;
2802 sum += count;
2803 /* fallthrough */
2804 case XML_TEXTWRITER_DTD:
2805 count = xmlOutputBufferWriteString(writer->out, ">");
2806
2807 if (writer->indent) {
2808 if (count < 0)
2809 return -1;
2810 sum += count;
2811 count = xmlOutputBufferWriteString(writer->out, "\n");
2812 }
2813
2814 xmlListPopFront(writer->nodes);
2815 break;
2816 case XML_TEXTWRITER_DTD_ELEM:
2817 case XML_TEXTWRITER_DTD_ELEM_TEXT:
2818 count = xmlTextWriterEndDTDElement(writer);
2819 break;
2820 case XML_TEXTWRITER_DTD_ATTL:
2821 case XML_TEXTWRITER_DTD_ATTL_TEXT:
2822 count = xmlTextWriterEndDTDAttlist(writer);
2823 break;
2824 case XML_TEXTWRITER_DTD_ENTY:
2825 case XML_TEXTWRITER_DTD_PENT:
2826 case XML_TEXTWRITER_DTD_ENTY_TEXT:
2827 count = xmlTextWriterEndDTDEntity(writer);
2828 break;
2829 case XML_TEXTWRITER_COMMENT:
2830 count = xmlTextWriterEndComment(writer);
2831 break;
2832 default:
2833 loop = 0;
2834 continue;
2835 }
2836
2837 if (count < 0)
Daniel Veillard1d211e22003-10-20 22:32:39 +00002838 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00002839 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002840 }
2841
Daniel Veillard1d211e22003-10-20 22:32:39 +00002842 return sum;
2843}
2844
2845/**
2846 * xmlTextWriterWriteFormatDTD:
2847 * @writer: the xmlTextWriterPtr
2848 * @name: the name of the DTD
2849 * @pubid: the public identifier, which is an alternative to the system identifier
2850 * @sysid: the system identifier, which is the URI of the DTD
2851 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002852 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002853 *
2854 * Write a DTD with a formatted markup declarations part.
2855 *
2856 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2857 */
2858int
2859xmlTextWriterWriteFormatDTD(xmlTextWriterPtr writer,
2860 const xmlChar * name,
2861 const xmlChar * pubid,
2862 const xmlChar * sysid, const char *format, ...)
2863{
2864 int rc;
2865 va_list ap;
2866
2867 va_start(ap, format);
2868
2869 rc = xmlTextWriterWriteVFormatDTD(writer, name, pubid, sysid, format,
2870 ap);
2871
2872 va_end(ap);
2873 return rc;
2874}
2875
2876/**
2877 * xmlTextWriterWriteVFormatDTD:
2878 * @writer: the xmlTextWriterPtr
2879 * @name: the name of the DTD
2880 * @pubid: the public identifier, which is an alternative to the system identifier
2881 * @sysid: the system identifier, which is the URI of the DTD
2882 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002883 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00002884 *
2885 * Write a DTD with a formatted markup declarations part.
2886 *
2887 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2888 */
2889int
2890xmlTextWriterWriteVFormatDTD(xmlTextWriterPtr writer,
2891 const xmlChar * name,
2892 const xmlChar * pubid,
2893 const xmlChar * sysid,
2894 const char *format, va_list argptr)
2895{
2896 int rc;
2897 xmlChar *buf;
2898
2899 if (writer == NULL)
2900 return -1;
2901
2902 buf = xmlTextWriterVSprintf(format, argptr);
2903 if (buf == 0)
2904 return 0;
2905
2906 rc = xmlTextWriterWriteDTD(writer, name, pubid, sysid, buf);
2907
2908 xmlFree(buf);
2909 return rc;
2910}
2911
2912/**
2913 * xmlTextWriterWriteDTD:
2914 * @writer: the xmlTextWriterPtr
2915 * @name: the name of the DTD
2916 * @pubid: the public identifier, which is an alternative to the system identifier
2917 * @sysid: the system identifier, which is the URI of the DTD
William M. Brackb1d53162003-11-18 06:54:40 +00002918 * @subset: string content of the DTD
Daniel Veillard1d211e22003-10-20 22:32:39 +00002919 *
2920 * Write a DTD.
2921 *
2922 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2923 */
2924int
2925xmlTextWriterWriteDTD(xmlTextWriterPtr writer,
2926 const xmlChar * name,
2927 const xmlChar * pubid,
2928 const xmlChar * sysid, const xmlChar * subset)
2929{
2930 int count;
2931 int sum;
2932
2933 sum = 0;
2934 count = xmlTextWriterStartDTD(writer, name, pubid, sysid);
2935 if (count == -1)
2936 return -1;
2937 sum += count;
2938 if (subset != 0) {
2939 count = xmlTextWriterWriteString(writer, subset);
2940 if (count == -1)
2941 return -1;
2942 sum += count;
2943 }
2944 count = xmlTextWriterEndDTD(writer);
2945 if (count == -1)
2946 return -1;
2947 sum += count;
2948
2949 return sum;
2950}
2951
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002952/**
2953 * xmlTextWriterStartDTDElement:
2954 * @writer: the xmlTextWriterPtr
2955 * @name: the name of the DTD element
2956 *
2957 * Start an xml DTD element.
2958 *
2959 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2960 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00002961int
2962xmlTextWriterStartDTDElement(xmlTextWriterPtr writer, const xmlChar * name)
2963{
2964 int count;
2965 int sum;
2966 xmlLinkPtr lk;
2967 xmlTextWriterStackEntry *p;
2968
2969 if (writer == NULL || name == NULL || *name == '\0')
2970 return -1;
2971
2972 sum = 0;
2973 lk = xmlListFront(writer->nodes);
2974 if (lk == 0) {
2975 return -1;
2976 }
2977
2978 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
Daniel Veillard500a1de2004-03-22 15:22:58 +00002979 if (p != 0) {
2980 switch (p->state) {
2981 case XML_TEXTWRITER_DTD:
2982 count = xmlOutputBufferWriteString(writer->out, " [");
2983 if (count < 0)
2984 return -1;
2985 sum += count;
2986 if (writer->indent) {
2987 count = xmlOutputBufferWriteString(writer->out, "\n");
2988 if (count < 0)
2989 return -1;
2990 sum += count;
2991 }
2992 p->state = XML_TEXTWRITER_DTD_TEXT;
2993 /* fallthrough */
2994 case XML_TEXTWRITER_DTD_TEXT:
2995 case XML_TEXTWRITER_NONE:
2996 break;
2997 default:
Daniel Veillard1d211e22003-10-20 22:32:39 +00002998 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00002999 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00003000 }
3001
3002 p = (xmlTextWriterStackEntry *)
3003 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3004 if (p == 0) {
3005 xmlGenericError(xmlGenericErrorContext,
3006 "xmlTextWriterStartDTDElement : out of memory!\n");
3007 return -1;
3008 }
3009
3010 p->name = xmlStrdup(name);
3011 if (p->name == 0) {
3012 xmlGenericError(xmlGenericErrorContext,
3013 "xmlTextWriterStartDTDElement : out of memory!\n");
3014 xmlFree(p);
3015 return -1;
3016 }
3017 p->state = XML_TEXTWRITER_DTD_ELEM;
3018
3019 xmlListPushFront(writer->nodes, p);
3020
Daniel Veillard500a1de2004-03-22 15:22:58 +00003021 if (writer->indent) {
3022 count = xmlTextWriterWriteIndent(writer);
3023 if (count < 0)
3024 return -1;
3025 sum += count;
3026 }
3027
Daniel Veillard1d211e22003-10-20 22:32:39 +00003028 count = xmlOutputBufferWriteString(writer->out, "<!ELEMENT ");
3029 if (count < 0)
3030 return -1;
3031 sum += count;
3032 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
3033 if (count < 0)
3034 return -1;
3035 sum += count;
3036
3037 return sum;
3038}
3039
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003040/**
Daniel Veillard500a1de2004-03-22 15:22:58 +00003041 * xmlTextWriterEndDTDElement:
3042 * @writer: the xmlTextWriterPtr
3043 *
3044 * End an xml DTD element.
3045 *
3046 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3047 */
3048int
3049xmlTextWriterEndDTDElement(xmlTextWriterPtr writer)
3050{
3051 int count;
3052 int sum;
3053 xmlLinkPtr lk;
3054 xmlTextWriterStackEntry *p;
3055
3056 if (writer == NULL)
3057 return -1;
3058
3059 sum = 0;
3060 lk = xmlListFront(writer->nodes);
3061 if (lk == 0)
3062 return -1;
3063
3064 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3065 if (p == 0)
3066 return -1;
3067
3068 switch (p->state) {
3069 case XML_TEXTWRITER_DTD_ELEM:
3070 case XML_TEXTWRITER_DTD_ELEM_TEXT:
3071 count = xmlOutputBufferWriteString(writer->out, ">");
3072 if (count < 0)
3073 return -1;
3074 sum += count;
3075 break;
3076 default:
3077 return -1;
3078 }
3079
3080 if (writer->indent) {
3081 count = xmlOutputBufferWriteString(writer->out, "\n");
3082 if (count < 0)
3083 return -1;
3084 sum += count;
3085 }
3086
3087 xmlListPopFront(writer->nodes);
3088 return sum;
3089}
3090
3091/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003092 * xmlTextWriterWriteFormatDTDElement:
3093 * @writer: the xmlTextWriterPtr
3094 * @name: the name of the DTD element
3095 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003096 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003097 *
3098 * Write a formatted DTD element.
3099 *
3100 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3101 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003102int
3103xmlTextWriterWriteFormatDTDElement(xmlTextWriterPtr writer,
3104 const xmlChar * name,
3105 const char *format, ...)
3106{
3107 int rc;
3108 va_list ap;
3109
3110 va_start(ap, format);
3111
3112 rc = xmlTextWriterWriteVFormatDTDElement(writer, name, format, ap);
3113
3114 va_end(ap);
3115 return rc;
3116}
3117
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003118/**
3119 * xmlTextWriterWriteVFormatDTDElement:
3120 * @writer: the xmlTextWriterPtr
3121 * @name: the name of the DTD element
3122 * @format: format string (see printf)
3123 * @argptr: pointer to the first member of the variable argument list.
3124 *
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
3130xmlTextWriterWriteVFormatDTDElement(xmlTextWriterPtr writer,
3131 const xmlChar * name,
3132 const char *format, va_list argptr)
3133{
3134 int rc;
3135 xmlChar *buf;
3136
3137 if (writer == NULL)
3138 return -1;
3139
3140 buf = xmlTextWriterVSprintf(format, argptr);
3141 if (buf == 0)
3142 return 0;
3143
3144 rc = xmlTextWriterWriteDTDElement(writer, name, buf);
3145
3146 xmlFree(buf);
3147 return rc;
3148}
3149
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003150/**
3151 * xmlTextWriterWriteDTDElement:
3152 * @writer: the xmlTextWriterPtr
3153 * @name: the name of the DTD element
3154 * @content: content of the element
3155 *
3156 * Write a DTD element.
3157 *
3158 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3159 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003160int
3161xmlTextWriterWriteDTDElement(xmlTextWriterPtr writer,
3162 const xmlChar * name, const xmlChar * content)
3163{
3164 int count;
3165 int sum;
3166
3167 if (content == NULL)
3168 return -1;
3169
3170 sum = 0;
3171 count = xmlTextWriterStartDTDElement(writer, name);
3172 if (count == -1)
3173 return -1;
3174 sum += count;
3175
Daniel Veillard1d211e22003-10-20 22:32:39 +00003176 count = xmlTextWriterWriteString(writer, content);
3177 if (count == -1)
3178 return -1;
3179 sum += count;
3180
3181 count = xmlTextWriterEndDTDElement(writer);
3182 if (count == -1)
3183 return -1;
3184 sum += count;
3185
3186 return sum;
3187}
3188
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003189/**
3190 * xmlTextWriterStartDTDAttlist:
3191 * @writer: the xmlTextWriterPtr
3192 * @name: the name of the DTD ATTLIST
3193 *
3194 * Start an xml DTD ATTLIST.
3195 *
3196 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3197 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003198int
3199xmlTextWriterStartDTDAttlist(xmlTextWriterPtr writer, const xmlChar * name)
3200{
3201 int count;
3202 int sum;
3203 xmlLinkPtr lk;
3204 xmlTextWriterStackEntry *p;
3205
3206 if (writer == NULL || name == NULL || *name == '\0')
3207 return -1;
3208
3209 sum = 0;
3210 lk = xmlListFront(writer->nodes);
3211 if (lk == 0) {
3212 return -1;
3213 }
3214
3215 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
Daniel Veillard500a1de2004-03-22 15:22:58 +00003216 if (p != 0) {
3217 switch (p->state) {
3218 case XML_TEXTWRITER_DTD:
3219 count = xmlOutputBufferWriteString(writer->out, " [");
3220 if (count < 0)
3221 return -1;
3222 sum += count;
3223 if (writer->indent) {
3224 count = xmlOutputBufferWriteString(writer->out, "\n");
3225 if (count < 0)
3226 return -1;
3227 sum += count;
3228 }
3229 p->state = XML_TEXTWRITER_DTD_TEXT;
3230 /* fallthrough */
3231 case XML_TEXTWRITER_DTD_TEXT:
3232 case XML_TEXTWRITER_NONE:
3233 break;
3234 default:
Daniel Veillard1d211e22003-10-20 22:32:39 +00003235 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00003236 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00003237 }
3238
3239 p = (xmlTextWriterStackEntry *)
3240 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3241 if (p == 0) {
3242 xmlGenericError(xmlGenericErrorContext,
3243 "xmlTextWriterStartDTDAttlist : out of memory!\n");
3244 return -1;
3245 }
3246
3247 p->name = xmlStrdup(name);
3248 if (p->name == 0) {
3249 xmlGenericError(xmlGenericErrorContext,
3250 "xmlTextWriterStartDTDAttlist : out of memory!\n");
3251 xmlFree(p);
3252 return -1;
3253 }
3254 p->state = XML_TEXTWRITER_DTD_ATTL;
3255
3256 xmlListPushFront(writer->nodes, p);
3257
Daniel Veillard500a1de2004-03-22 15:22:58 +00003258 if (writer->indent) {
3259 count = xmlTextWriterWriteIndent(writer);
3260 if (count < 0)
3261 return -1;
3262 sum += count;
3263 }
3264
Daniel Veillard1d211e22003-10-20 22:32:39 +00003265 count = xmlOutputBufferWriteString(writer->out, "<!ATTLIST ");
3266 if (count < 0)
3267 return -1;
3268 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +00003269 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003270 if (count < 0)
3271 return -1;
3272 sum += count;
3273
3274 return sum;
3275}
3276
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003277/**
Daniel Veillard500a1de2004-03-22 15:22:58 +00003278 * xmlTextWriterEndDTDAttlist:
3279 * @writer: the xmlTextWriterPtr
3280 *
3281 * End an xml DTD attribute list.
3282 *
3283 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3284 */
3285int
3286xmlTextWriterEndDTDAttlist(xmlTextWriterPtr writer)
3287{
3288 int count;
3289 int sum;
3290 xmlLinkPtr lk;
3291 xmlTextWriterStackEntry *p;
3292
3293 if (writer == NULL)
3294 return -1;
3295
3296 sum = 0;
3297 lk = xmlListFront(writer->nodes);
3298 if (lk == 0)
3299 return -1;
3300
3301 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3302 if (p == 0)
3303 return -1;
3304
3305 switch (p->state) {
3306 case XML_TEXTWRITER_DTD_ATTL:
3307 case XML_TEXTWRITER_DTD_ATTL_TEXT:
3308 count = xmlOutputBufferWriteString(writer->out, ">");
3309 if (count < 0)
3310 return -1;
3311 sum += count;
3312 break;
3313 default:
3314 return -1;
3315 }
3316
3317 if (writer->indent) {
3318 count = xmlOutputBufferWriteString(writer->out, "\n");
3319 if (count < 0)
3320 return -1;
3321 sum += count;
3322 }
3323
3324 xmlListPopFront(writer->nodes);
3325 return sum;
3326}
3327
3328/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003329 * xmlTextWriterWriteFormatDTDAttlist:
3330 * @writer: the xmlTextWriterPtr
3331 * @name: the name of the DTD ATTLIST
3332 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003333 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003334 *
3335 * Write a formatted DTD ATTLIST.
3336 *
3337 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3338 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003339int
3340xmlTextWriterWriteFormatDTDAttlist(xmlTextWriterPtr writer,
3341 const xmlChar * name,
3342 const char *format, ...)
3343{
3344 int rc;
3345 va_list ap;
3346
3347 va_start(ap, format);
3348
3349 rc = xmlTextWriterWriteVFormatDTDAttlist(writer, name, format, ap);
3350
3351 va_end(ap);
3352 return rc;
3353}
3354
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003355/**
3356 * xmlTextWriterWriteVFormatDTDAttlist:
3357 * @writer: the xmlTextWriterPtr
3358 * @name: the name of the DTD ATTLIST
3359 * @format: format string (see printf)
3360 * @argptr: pointer to the first member of the variable argument list.
3361 *
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
3367xmlTextWriterWriteVFormatDTDAttlist(xmlTextWriterPtr writer,
3368 const xmlChar * name,
3369 const char *format, va_list argptr)
3370{
3371 int rc;
3372 xmlChar *buf;
3373
3374 if (writer == NULL)
3375 return -1;
3376
3377 buf = xmlTextWriterVSprintf(format, argptr);
3378 if (buf == 0)
3379 return 0;
3380
3381 rc = xmlTextWriterWriteDTDAttlist(writer, name, buf);
3382
3383 xmlFree(buf);
3384 return rc;
3385}
3386
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003387/**
3388 * xmlTextWriterWriteDTDAttlist:
3389 * @writer: the xmlTextWriterPtr
3390 * @name: the name of the DTD ATTLIST
3391 * @content: content of the ATTLIST
3392 *
3393 * Write a DTD ATTLIST.
3394 *
3395 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3396 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003397int
3398xmlTextWriterWriteDTDAttlist(xmlTextWriterPtr writer,
3399 const xmlChar * name, const xmlChar * content)
3400{
3401 int count;
3402 int sum;
3403
3404 if (content == NULL)
3405 return -1;
3406
3407 sum = 0;
3408 count = xmlTextWriterStartDTDAttlist(writer, name);
3409 if (count == -1)
3410 return -1;
3411 sum += count;
3412
Daniel Veillard1d211e22003-10-20 22:32:39 +00003413 count = xmlTextWriterWriteString(writer, content);
3414 if (count == -1)
3415 return -1;
3416 sum += count;
3417
3418 count = xmlTextWriterEndDTDAttlist(writer);
3419 if (count == -1)
3420 return -1;
3421 sum += count;
3422
3423 return sum;
3424}
3425
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003426/**
3427 * xmlTextWriterStartDTDEntity:
3428 * @writer: the xmlTextWriterPtr
3429 * @pe: TRUE if this is a parameter entity, FALSE if not
3430 * @name: the name of the DTD ATTLIST
3431 *
3432 * Start an xml DTD ATTLIST.
3433 *
3434 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3435 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003436int
3437xmlTextWriterStartDTDEntity(xmlTextWriterPtr writer,
3438 int pe, const xmlChar * name)
3439{
3440 int count;
3441 int sum;
3442 xmlLinkPtr lk;
3443 xmlTextWriterStackEntry *p;
3444
3445 if (writer == NULL || name == NULL || *name == '\0')
3446 return -1;
3447
3448 sum = 0;
3449 lk = xmlListFront(writer->nodes);
Daniel Veillard500a1de2004-03-22 15:22:58 +00003450 if (lk != 0) {
Daniel Veillard1d211e22003-10-20 22:32:39 +00003451
Daniel Veillard500a1de2004-03-22 15:22:58 +00003452 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3453 if (p != 0) {
3454 switch (p->state) {
3455 case XML_TEXTWRITER_DTD:
3456 count = xmlOutputBufferWriteString(writer->out, " [");
3457 if (count < 0)
3458 return -1;
3459 sum += count;
3460 if (writer->indent) {
3461 count =
3462 xmlOutputBufferWriteString(writer->out, "\n");
3463 if (count < 0)
3464 return -1;
3465 sum += count;
3466 }
3467 p->state = XML_TEXTWRITER_DTD_TEXT;
3468 /* fallthrough */
3469 case XML_TEXTWRITER_DTD_TEXT:
3470 case XML_TEXTWRITER_NONE:
3471 break;
3472 default:
3473 return -1;
3474 }
3475 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00003476 }
3477
3478 p = (xmlTextWriterStackEntry *)
3479 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3480 if (p == 0) {
3481 xmlGenericError(xmlGenericErrorContext,
3482 "xmlTextWriterStartDTDElement : out of memory!\n");
3483 return -1;
3484 }
3485
3486 p->name = xmlStrdup(name);
3487 if (p->name == 0) {
3488 xmlGenericError(xmlGenericErrorContext,
3489 "xmlTextWriterStartDTDElement : out of memory!\n");
3490 xmlFree(p);
3491 return -1;
3492 }
Daniel Veillard500a1de2004-03-22 15:22:58 +00003493
3494 if (pe != 0)
3495 p->state = XML_TEXTWRITER_DTD_PENT;
3496 else
3497 p->state = XML_TEXTWRITER_DTD_ENTY;
Daniel Veillard1d211e22003-10-20 22:32:39 +00003498
3499 xmlListPushFront(writer->nodes, p);
3500
Daniel Veillard500a1de2004-03-22 15:22:58 +00003501 if (writer->indent) {
3502 count = xmlTextWriterWriteIndent(writer);
3503 if (count < 0)
3504 return -1;
3505 sum += count;
3506 }
3507
Daniel Veillard1d211e22003-10-20 22:32:39 +00003508 count = xmlOutputBufferWriteString(writer->out, "<!ENTITY ");
3509 if (count < 0)
3510 return -1;
3511 sum += count;
3512
3513 if (pe != 0) {
Daniel Veillard500a1de2004-03-22 15:22:58 +00003514 count = xmlOutputBufferWriteString(writer->out, "% ");
Daniel Veillard1d211e22003-10-20 22:32:39 +00003515 if (count < 0)
3516 return -1;
3517 sum += count;
3518 }
3519
Daniel Veillardab69f362004-02-17 11:40:32 +00003520 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003521 if (count < 0)
3522 return -1;
3523 sum += count;
3524
3525 return sum;
3526}
3527
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003528/**
Daniel Veillard500a1de2004-03-22 15:22:58 +00003529 * xmlTextWriterEndDTDEntity:
3530 * @writer: the xmlTextWriterPtr
3531 *
3532 * End an xml DTD entity.
3533 *
3534 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3535 */
3536int
3537xmlTextWriterEndDTDEntity(xmlTextWriterPtr writer)
3538{
3539 int count;
3540 int sum;
3541 xmlLinkPtr lk;
3542 xmlTextWriterStackEntry *p;
3543
3544 if (writer == NULL)
3545 return -1;
3546
3547 sum = 0;
3548 lk = xmlListFront(writer->nodes);
3549 if (lk == 0)
3550 return -1;
3551
3552 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3553 if (p == 0)
3554 return -1;
3555
3556 switch (p->state) {
3557 case XML_TEXTWRITER_DTD_ENTY_TEXT:
3558 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3559 if (count < 0)
3560 return -1;
3561 sum += count;
3562 case XML_TEXTWRITER_DTD_ENTY:
3563 case XML_TEXTWRITER_DTD_PENT:
Daniel Veillard500a1de2004-03-22 15:22:58 +00003564 count = xmlOutputBufferWriteString(writer->out, ">");
3565 if (count < 0)
3566 return -1;
3567 sum += count;
3568 break;
3569 default:
3570 return -1;
3571 }
3572
3573 if (writer->indent) {
3574 count = xmlOutputBufferWriteString(writer->out, "\n");
3575 if (count < 0)
3576 return -1;
3577 sum += count;
3578 }
3579
3580 xmlListPopFront(writer->nodes);
3581 return sum;
3582}
3583
3584/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003585 * xmlTextWriterWriteFormatDTDInternalEntity:
3586 * @writer: the xmlTextWriterPtr
3587 * @pe: TRUE if this is a parameter entity, FALSE if not
3588 * @name: the name of the DTD entity
3589 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003590 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003591 *
3592 * Write a formatted DTD internal entity.
3593 *
3594 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3595 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003596int
3597xmlTextWriterWriteFormatDTDInternalEntity(xmlTextWriterPtr writer,
3598 int pe,
3599 const xmlChar * name,
3600 const char *format, ...)
3601{
3602 int rc;
3603 va_list ap;
3604
3605 va_start(ap, format);
3606
3607 rc = xmlTextWriterWriteVFormatDTDInternalEntity(writer, pe, name,
3608 format, ap);
3609
3610 va_end(ap);
3611 return rc;
3612}
3613
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003614/**
3615 * xmlTextWriterWriteVFormatDTDInternalEntity:
3616 * @writer: the xmlTextWriterPtr
3617 * @pe: TRUE if this is a parameter entity, FALSE if not
3618 * @name: the name of the DTD entity
3619 * @format: format string (see printf)
3620 * @argptr: pointer to the first member of the variable argument list.
3621 *
3622 * Write a formatted DTD internal entity.
3623 *
3624 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3625 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003626int
3627xmlTextWriterWriteVFormatDTDInternalEntity(xmlTextWriterPtr writer,
3628 int pe,
3629 const xmlChar * name,
3630 const char *format,
3631 va_list argptr)
3632{
3633 int rc;
3634 xmlChar *buf;
3635
3636 if (writer == NULL)
3637 return -1;
3638
3639 buf = xmlTextWriterVSprintf(format, argptr);
3640 if (buf == 0)
3641 return 0;
3642
3643 rc = xmlTextWriterWriteDTDInternalEntity(writer, pe, name, buf);
3644
3645 xmlFree(buf);
3646 return rc;
3647}
3648
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003649/**
3650 * xmlTextWriterWriteDTDEntity:
3651 * @writer: the xmlTextWriterPtr
3652 * @pe: TRUE if this is a parameter entity, FALSE if not
3653 * @name: the name of the DTD entity
3654 * @pubid: the public identifier, which is an alternative to the system identifier
3655 * @sysid: the system identifier, which is the URI of the DTD
3656 * @ndataid: the xml notation name.
3657 * @content: content of the entity
3658 *
3659 * Write a DTD entity.
3660 *
3661 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3662 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003663int
3664xmlTextWriterWriteDTDEntity(xmlTextWriterPtr writer,
3665 int pe,
3666 const xmlChar * name,
3667 const xmlChar * pubid,
3668 const xmlChar * sysid,
3669 const xmlChar * ndataid,
3670 const xmlChar * content)
3671{
Daniel Veillard500a1de2004-03-22 15:22:58 +00003672 if ((content == NULL) && (pubid == NULL) && (sysid == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00003673 return -1;
3674 if ((pe != 0) && (ndataid != NULL))
3675 return -1;
3676
Daniel Veillard500a1de2004-03-22 15:22:58 +00003677 if ((pubid == NULL) && (sysid == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00003678 return xmlTextWriterWriteDTDInternalEntity(writer, pe, name,
3679 content);
3680
3681 return xmlTextWriterWriteDTDExternalEntity(writer, pe, name, pubid,
3682 sysid, ndataid);
3683}
3684
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003685/**
3686 * xmlTextWriterWriteDTDInternalEntity:
3687 * @writer: the xmlTextWriterPtr
3688 * @pe: TRUE if this is a parameter entity, FALSE if not
3689 * @name: the name of the DTD entity
3690 * @content: content of the entity
3691 *
3692 * Write a DTD internal entity.
3693 *
3694 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3695 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003696int
3697xmlTextWriterWriteDTDInternalEntity(xmlTextWriterPtr writer,
3698 int pe,
3699 const xmlChar * name,
3700 const xmlChar * content)
3701{
3702 int count;
3703 int sum;
3704
3705 if ((name == NULL) || (*name == '\0') || (content == NULL))
3706 return -1;
3707
3708 sum = 0;
3709 count = xmlTextWriterStartDTDEntity(writer, pe, name);
3710 if (count == -1)
3711 return -1;
3712 sum += count;
3713
Daniel Veillard1d211e22003-10-20 22:32:39 +00003714 count = xmlTextWriterWriteString(writer, content);
3715 if (count == -1)
3716 return -1;
3717 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00003718
3719 count = xmlTextWriterEndDTDEntity(writer);
3720 if (count == -1)
3721 return -1;
3722 sum += count;
3723
3724 return sum;
3725}
3726
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003727/**
3728 * xmlTextWriterWriteDTDExternalEntity:
3729 * @writer: the xmlTextWriterPtr
3730 * @pe: TRUE if this is a parameter entity, FALSE if not
3731 * @name: the name of the DTD entity
3732 * @pubid: the public identifier, which is an alternative to the system identifier
3733 * @sysid: the system identifier, which is the URI of the DTD
3734 * @ndataid: the xml notation name.
3735 *
Daniel Veillard500a1de2004-03-22 15:22:58 +00003736 * Write a DTD external entity. The entity must have been started with xmlTextWriterStartDTDEntity
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003737 *
3738 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3739 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003740int
3741xmlTextWriterWriteDTDExternalEntity(xmlTextWriterPtr writer,
3742 int pe,
3743 const xmlChar * name,
3744 const xmlChar * pubid,
3745 const xmlChar * sysid,
3746 const xmlChar * ndataid)
3747{
3748 int count;
3749 int sum;
3750
Daniel Veillard500a1de2004-03-22 15:22:58 +00003751 if (((pubid == NULL) && (sysid == NULL)))
Daniel Veillard1d211e22003-10-20 22:32:39 +00003752 return -1;
3753 if ((pe != 0) && (ndataid != NULL))
3754 return -1;
3755
3756 sum = 0;
3757 count = xmlTextWriterStartDTDEntity(writer, pe, name);
3758 if (count == -1)
3759 return -1;
3760 sum += count;
3761
Daniel Veillard500a1de2004-03-22 15:22:58 +00003762 count =
3763 xmlTextWriterWriteDTDExternalEntityContents(writer, pubid, sysid,
3764 ndataid);
3765 if (count < 0)
3766 return -1;
3767 sum += count;
3768
3769 count = xmlTextWriterEndDTDEntity(writer);
3770 if (count == -1)
3771 return -1;
3772 sum += count;
3773
3774 return sum;
3775}
3776
3777/**
3778 * xmlTextWriterWriteDTDExternalEntityContents:
3779 * @writer: the xmlTextWriterPtr
3780 * @pubid: the public identifier, which is an alternative to the system identifier
3781 * @sysid: the system identifier, which is the URI of the DTD
3782 * @ndataid: the xml notation name.
3783 *
3784 * Write the contents of a DTD external entity.
3785 *
3786 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3787 */
3788int
3789xmlTextWriterWriteDTDExternalEntityContents(xmlTextWriterPtr writer,
3790 const xmlChar * pubid,
3791 const xmlChar * sysid,
3792 const xmlChar * ndataid)
3793{
3794 int count;
3795 int sum;
3796 xmlLinkPtr lk;
3797 xmlTextWriterStackEntry *p;
3798
3799 if (writer == NULL) {
3800 xmlGenericError(xmlGenericErrorContext,
3801 "xmlTextWriterWriteDTDExternalEntityContents: xmlTextWriterPtr invalid!\n");
3802 return -1;
3803 }
3804
3805 sum = 0;
3806 lk = xmlListFront(writer->nodes);
3807 if (lk == 0) {
3808 xmlGenericError(xmlGenericErrorContext,
3809 "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n");
3810 return -1;
3811 }
3812
3813 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3814 if (p == 0)
3815 return -1;
3816
3817 switch (p->state) {
3818 case XML_TEXTWRITER_DTD_ENTY:
3819 break;
3820 case XML_TEXTWRITER_DTD_PENT:
3821 if (ndataid != NULL) {
3822 xmlGenericError(xmlGenericErrorContext,
3823 "xmlTextWriterWriteDTDExternalEntityContents: notation not allowed with parameter entities!\n");
3824 return -1;
3825 }
3826 break;
3827 default:
3828 xmlGenericError(xmlGenericErrorContext,
3829 "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n");
3830 return -1;
3831 }
3832
Daniel Veillard1d211e22003-10-20 22:32:39 +00003833 if (pubid != 0) {
3834 if (sysid == 0) {
3835 xmlGenericError(xmlGenericErrorContext,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003836 "xmlTextWriterWriteDTDExternalEntityContents: system identifier needed!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +00003837 return -1;
3838 }
3839
3840 count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
3841 if (count < 0)
3842 return -1;
3843 sum += count;
3844
3845 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3846 if (count < 0)
3847 return -1;
3848 sum += count;
3849
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003850 count =
3851 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003852 if (count < 0)
3853 return -1;
3854 sum += count;
3855
3856 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3857 if (count < 0)
3858 return -1;
3859 sum += count;
3860 }
3861
3862 if (sysid != 0) {
3863 if (pubid == 0) {
3864 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
3865 if (count < 0)
3866 return -1;
3867 sum += count;
3868 }
3869
3870 count = xmlOutputBufferWriteString(writer->out, " ");
3871 if (count < 0)
3872 return -1;
3873 sum += count;
3874
3875 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3876 if (count < 0)
3877 return -1;
3878 sum += count;
3879
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003880 count =
3881 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003882 if (count < 0)
3883 return -1;
3884 sum += count;
3885
3886 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3887 if (count < 0)
3888 return -1;
3889 sum += count;
3890 }
3891
3892 if (ndataid != NULL) {
3893 count = xmlOutputBufferWriteString(writer->out, " NDATA ");
3894 if (count < 0)
3895 return -1;
3896 sum += count;
3897
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003898 count =
3899 xmlOutputBufferWriteString(writer->out,
3900 (const char *) ndataid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003901 if (count < 0)
3902 return -1;
3903 sum += count;
3904 }
3905
Daniel Veillard1d211e22003-10-20 22:32:39 +00003906 return sum;
3907}
3908
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003909/**
3910 * xmlTextWriterWriteDTDNotation:
3911 * @writer: the xmlTextWriterPtr
3912 * @name: the name of the xml notation
3913 * @pubid: the public identifier, which is an alternative to the system identifier
3914 * @sysid: the system identifier, which is the URI of the DTD
3915 *
3916 * Write a DTD entity.
3917 *
3918 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3919 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003920int
3921xmlTextWriterWriteDTDNotation(xmlTextWriterPtr writer,
3922 const xmlChar * name,
3923 const xmlChar * pubid, const xmlChar * sysid)
3924{
3925 int count;
3926 int sum;
3927 xmlLinkPtr lk;
3928 xmlTextWriterStackEntry *p;
3929
3930 if (writer == NULL || name == NULL || *name == '\0')
3931 return -1;
3932
3933 sum = 0;
3934 lk = xmlListFront(writer->nodes);
3935 if (lk == 0) {
3936 return -1;
3937 }
3938
3939 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
Daniel Veillard500a1de2004-03-22 15:22:58 +00003940 if (p != 0) {
3941 switch (p->state) {
3942 case XML_TEXTWRITER_DTD:
3943 count = xmlOutputBufferWriteString(writer->out, " [");
3944 if (count < 0)
3945 return -1;
3946 sum += count;
3947 if (writer->indent) {
3948 count = xmlOutputBufferWriteString(writer->out, "\n");
3949 if (count < 0)
3950 return -1;
3951 sum += count;
3952 }
3953 p->state = XML_TEXTWRITER_DTD_TEXT;
3954 /* fallthrough */
3955 case XML_TEXTWRITER_DTD_TEXT:
3956 break;
3957 default:
3958 return -1;
3959 }
3960 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00003961
Daniel Veillard500a1de2004-03-22 15:22:58 +00003962 if (writer->indent) {
3963 count = xmlTextWriterWriteIndent(writer);
3964 if (count < 0)
Daniel Veillard1d211e22003-10-20 22:32:39 +00003965 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00003966 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00003967 }
3968
3969 count = xmlOutputBufferWriteString(writer->out, "<!NOTATION ");
3970 if (count < 0)
3971 return -1;
3972 sum += count;
3973 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
3974 if (count < 0)
3975 return -1;
3976 sum += count;
3977
3978 if (pubid != 0) {
3979 count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
3980 if (count < 0)
3981 return -1;
3982 sum += count;
3983 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3984 if (count < 0)
3985 return -1;
3986 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003987 count =
3988 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003989 if (count < 0)
3990 return -1;
3991 sum += count;
3992 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3993 if (count < 0)
3994 return -1;
3995 sum += count;
3996 }
3997
3998 if (sysid != 0) {
3999 if (pubid == 0) {
4000 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
4001 if (count < 0)
4002 return -1;
4003 sum += count;
4004 }
4005 count = xmlOutputBufferWriteString(writer->out, " ");
4006 if (count < 0)
4007 return -1;
4008 sum += count;
4009 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4010 if (count < 0)
4011 return -1;
4012 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004013 count =
4014 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004015 if (count < 0)
4016 return -1;
4017 sum += count;
4018 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4019 if (count < 0)
4020 return -1;
4021 sum += count;
4022 }
4023
4024 count = xmlOutputBufferWriteString(writer->out, ">");
4025 if (count < 0)
4026 return -1;
4027 sum += count;
4028
4029 return sum;
4030}
4031
4032/**
4033 * xmlTextWriterFlush:
4034 * @writer: the xmlTextWriterPtr
4035 *
4036 * Flush the output buffer.
4037 *
4038 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
4039 */
4040int
4041xmlTextWriterFlush(xmlTextWriterPtr writer)
4042{
4043 int count;
4044
4045 if (writer == NULL)
4046 return -1;
4047
4048 if (writer->out == NULL)
4049 count = 0;
4050 else
4051 count = xmlOutputBufferFlush(writer->out);
4052
4053 return count;
4054}
4055
4056/**
4057 * misc
4058 */
4059
4060/**
4061 * xmlFreeTextWriterStackEntry:
4062 * @lk: the xmlLinkPtr
4063 *
4064 * Free callback for the xmlList.
4065 */
4066static void
4067xmlFreeTextWriterStackEntry(xmlLinkPtr lk)
4068{
4069 xmlTextWriterStackEntry *p;
4070
4071 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
4072 if (p == 0)
4073 return;
4074
4075 if (p->name != 0)
4076 xmlFree(p->name);
4077 xmlFree(p);
4078}
4079
4080/**
4081 * xmlCmpTextWriterStackEntry:
4082 * @data0: the first data
4083 * @data1: the second data
4084 *
4085 * Compare callback for the xmlList.
4086 *
4087 * Returns -1, 0, 1
4088 */
4089static int
4090xmlCmpTextWriterStackEntry(const void *data0, const void *data1)
4091{
4092 xmlTextWriterStackEntry *p0;
4093 xmlTextWriterStackEntry *p1;
4094
4095 if (data0 == data1)
4096 return 0;
4097
4098 if (data0 == 0)
4099 return -1;
4100
4101 if (data1 == 0)
4102 return 1;
4103
4104 p0 = (xmlTextWriterStackEntry *) data0;
4105 p1 = (xmlTextWriterStackEntry *) data1;
4106
4107 return xmlStrcmp(p0->name, p1->name);
4108}
4109
4110/**
4111 * misc
4112 */
4113
4114/**
4115 * xmlFreeTextWriterNsStackEntry:
4116 * @lk: the xmlLinkPtr
4117 *
4118 * Free callback for the xmlList.
4119 */
4120static void
4121xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk)
4122{
4123 xmlTextWriterNsStackEntry *p;
4124
4125 p = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
4126 if (p == 0)
4127 return;
4128
4129 if (p->prefix != 0)
4130 xmlFree(p->prefix);
4131 if (p->uri != 0)
4132 xmlFree(p->uri);
4133
4134 xmlFree(p);
4135}
4136
4137/**
4138 * xmlCmpTextWriterNsStackEntry:
4139 * @data0: the first data
4140 * @data1: the second data
4141 *
4142 * Compare callback for the xmlList.
4143 *
4144 * Returns -1, 0, 1
4145 */
4146static int
4147xmlCmpTextWriterNsStackEntry(const void *data0, const void *data1)
4148{
4149 xmlTextWriterNsStackEntry *p0;
4150 xmlTextWriterNsStackEntry *p1;
4151 int rc;
4152
4153 if (data0 == data1)
4154 return 0;
4155
4156 if (data0 == 0)
4157 return -1;
4158
4159 if (data1 == 0)
4160 return 1;
4161
4162 p0 = (xmlTextWriterNsStackEntry *) data0;
4163 p1 = (xmlTextWriterNsStackEntry *) data1;
4164
4165 rc = xmlStrcmp(p0->prefix, p1->prefix);
4166
4167 if (rc == 0)
4168 rc = p0->elem == p1->elem;
4169
4170 return rc;
4171}
4172
4173/**
4174 * xmlTextWriterWriteMemCallback:
4175 * @context: the xmlBufferPtr
4176 * @str: the data to write
4177 * @len: the length of the data
4178 *
4179 * Write callback for the xmlOutputBuffer with target xmlBuffer
4180 *
4181 * Returns -1, 0, 1
4182 */
4183static int
4184xmlTextWriterWriteMemCallback(void *context, const xmlChar * str, int len)
4185{
4186 xmlBufferPtr buf = (xmlBufferPtr) context;
4187
4188 xmlBufferAdd(buf, str, len);
4189
4190 return len;
4191}
4192
4193/**
4194 * xmlTextWriterCloseMemCallback:
4195 * @context: the xmlBufferPtr
4196 *
4197 * Close callback for the xmlOutputBuffer with target xmlBuffer
4198 *
4199 * Returns -1, 0, 1
4200 */
4201static int
4202xmlTextWriterCloseMemCallback(void *context ATTRIBUTE_UNUSED)
4203{
4204 return 0;
4205}
4206
4207/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004208 * xmlTextWriterWriteDocCallback:
4209 * @context: the xmlBufferPtr
4210 * @str: the data to write
4211 * @len: the length of the data
4212 *
4213 * Write callback for the xmlOutputBuffer with target xmlBuffer
4214 *
4215 * Returns -1, 0, 1
4216 */
4217static int
4218xmlTextWriterWriteDocCallback(void *context, const xmlChar * str, int len)
4219{
4220 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context;
4221 int rc;
4222
Daniel Veillard1d913862003-11-21 00:28:39 +00004223 if ((rc = xmlParseChunk(ctxt, (const char *) str, len, 0)) != 0) {
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004224 xmlGenericError(xmlGenericErrorContext,
4225 "xmlTextWriterWriteDocCallback : XML error %d !\n",
4226 rc);
4227 return -1;
4228 }
4229
4230 return len;
4231}
4232
4233/**
4234 * xmlTextWriterCloseDocCallback:
4235 * @context: the xmlBufferPtr
4236 *
4237 * Close callback for the xmlOutputBuffer with target xmlBuffer
4238 *
4239 * Returns -1, 0, 1
4240 */
4241static int
4242xmlTextWriterCloseDocCallback(void *context)
4243{
4244 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context;
4245 int rc;
4246
4247 if ((rc = xmlParseChunk(ctxt, NULL, 0, 1)) != 0) {
4248 xmlGenericError(xmlGenericErrorContext,
4249 "xmlTextWriterWriteDocCallback : XML error %d !\n",
4250 rc);
4251 return -1;
4252 }
4253
4254 return 0;
4255}
4256
4257/**
Daniel Veillard1d211e22003-10-20 22:32:39 +00004258 * xmlTextWriterVSprintf:
4259 * @format: see printf
4260 * @argptr: pointer to the first member of the variable argument list.
4261 *
4262 * Utility function for formatted output
4263 *
4264 * Returns a new xmlChar buffer with the data or NULL on error. This buffer must be freed.
4265 */
4266static xmlChar *
4267xmlTextWriterVSprintf(const char *format, va_list argptr)
4268{
4269 int size;
4270 int count;
4271 xmlChar *buf;
4272
4273 size = BUFSIZ;
4274 buf = (xmlChar *) xmlMalloc(size);
4275 if (buf == NULL) {
4276 xmlGenericError(xmlGenericErrorContext,
4277 "xmlTextWriterVSprintf : out of memory!\n");
4278 return NULL;
4279 }
4280
4281 while (((count = vsnprintf((char *) buf, size, format, argptr)) < 0)
4282 || (count == size - 1) || (count == size) || (count > size)) {
4283 xmlFree(buf);
4284 size += BUFSIZ;
4285 buf = (xmlChar *) xmlMalloc(size);
4286 if (buf == NULL) {
4287 xmlGenericError(xmlGenericErrorContext,
4288 "xmlTextWriterVSprintf : out of memory!\n");
4289 return NULL;
4290 }
4291 }
4292
4293 return buf;
4294}
4295
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004296/**
4297 * xmlTextWriterStartDocumentCallback:
4298 * @ctx: the user data (XML parser context)
4299 *
4300 * called at the start of document processing.
4301 */
4302static void
4303xmlTextWriterStartDocumentCallback(void *ctx)
4304{
4305 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
4306 xmlDocPtr doc;
4307
4308#ifdef DEBUG_SAX
4309 xmlGenericError(xmlGenericErrorContext, "SAX.startDocument()\n");
4310#endif
4311 if (ctxt->html) {
4312#ifdef LIBXML_HTML_ENABLED
4313 if (ctxt->myDoc == NULL)
4314 ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
4315 if (ctxt->myDoc == NULL) {
4316 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
4317 ctxt->sax->error(ctxt->userData,
4318 "SAX.startDocument(): out of memory\n");
4319 ctxt->errNo = XML_ERR_NO_MEMORY;
4320 ctxt->instate = XML_PARSER_EOF;
4321 ctxt->disableSAX = 1;
4322 return;
4323 }
4324#else
4325 xmlGenericError(xmlGenericErrorContext,
4326 "libxml2 built without HTML support\n");
4327 ctxt->errNo = XML_ERR_INTERNAL_ERROR;
4328 ctxt->instate = XML_PARSER_EOF;
4329 ctxt->disableSAX = 1;
4330 return;
4331#endif
4332 } else {
4333 doc = ctxt->myDoc;
4334 if (doc == NULL)
4335 doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
4336 if (doc != NULL) {
4337 if (doc->children == NULL) {
4338 if (ctxt->encoding != NULL)
4339 doc->encoding = xmlStrdup(ctxt->encoding);
4340 else
4341 doc->encoding = NULL;
4342 doc->standalone = ctxt->standalone;
4343 }
4344 } else {
4345 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
4346 ctxt->sax->error(ctxt->userData,
4347 "SAX.startDocument(): out of memory\n");
4348 ctxt->errNo = XML_ERR_NO_MEMORY;
4349 ctxt->instate = XML_PARSER_EOF;
4350 ctxt->disableSAX = 1;
4351 return;
4352 }
4353 }
4354 if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) &&
4355 (ctxt->input != NULL) && (ctxt->input->filename != NULL)) {
4356 ctxt->myDoc->URL =
4357 xmlCanonicPath((const xmlChar *) ctxt->input->filename);
4358 if (ctxt->myDoc->URL == NULL)
4359 ctxt->myDoc->URL =
4360 xmlStrdup((const xmlChar *) ctxt->input->filename);
4361 }
4362}
4363
Daniel Veillard2cca4462004-01-02 20:04:23 +00004364/**
4365 * xmlTextWriterSetIndent:
4366 * @writer: the xmlTextWriterPtr
4367 * @indent: do indentation?
4368 *
4369 * Set indentation output. indent = 0 do not indentation. indent > 0 do indentation.
4370 *
4371 * Returns -1 on error or 0 otherwise.
4372 */
4373int
Daniel Veillardab69f362004-02-17 11:40:32 +00004374xmlTextWriterSetIndent(xmlTextWriterPtr writer, int indent)
Daniel Veillard2cca4462004-01-02 20:04:23 +00004375{
Daniel Veillardab69f362004-02-17 11:40:32 +00004376 if (indent < 0)
4377 return -1;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004378
Daniel Veillardab69f362004-02-17 11:40:32 +00004379 writer->indent = indent;
4380 writer->doindent = 1;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004381
Daniel Veillardab69f362004-02-17 11:40:32 +00004382 return 0;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004383}
4384
4385/**
4386 * xmlTextWriterSetIndentString:
4387 * @writer: the xmlTextWriterPtr
4388 * @str: the xmlChar string
4389 *
4390 * Set string indentation.
4391 *
4392 * Returns -1 on error or 0 otherwise.
4393 */
4394int
Daniel Veillardab69f362004-02-17 11:40:32 +00004395xmlTextWriterSetIndentString(xmlTextWriterPtr writer, const xmlChar * str)
Daniel Veillard2cca4462004-01-02 20:04:23 +00004396{
Daniel Veillardab69f362004-02-17 11:40:32 +00004397 if (!str)
4398 return -1;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004399
Daniel Veillardab69f362004-02-17 11:40:32 +00004400 if (writer->ichar != NULL)
4401 xmlFree(writer->ichar);
4402 writer->ichar = xmlStrdup(str);
4403
4404 if (!writer->ichar)
4405 return -1;
4406 else
4407 return 0;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004408}
4409
4410/**
4411 * xmlTextWriterWriteIndent:
4412 * @writer: the xmlTextWriterPtr
4413 *
4414 * Write indent string.
4415 *
4416 * Returns -1 on error or the number of strings written.
Daniel Veillardab69f362004-02-17 11:40:32 +00004417 */
Daniel Veillard2cca4462004-01-02 20:04:23 +00004418static int
Daniel Veillardab69f362004-02-17 11:40:32 +00004419xmlTextWriterWriteIndent(xmlTextWriterPtr writer)
Daniel Veillard2cca4462004-01-02 20:04:23 +00004420{
Daniel Veillardab69f362004-02-17 11:40:32 +00004421 int lksize;
4422 int i;
4423 int ret;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004424
Daniel Veillardab69f362004-02-17 11:40:32 +00004425 lksize = xmlListSize(writer->nodes);
4426 if (lksize < 1)
4427 return (-1); /* list is empty */
4428 for (i = 0; i < (lksize - 1); i++) {
4429 ret = xmlOutputBufferWriteString(writer->out,
4430 (const char *) writer->ichar);
4431 if (ret == -1)
4432 return (-1);
4433 }
4434
4435 return (lksize - 1);
Daniel Veillard2cca4462004-01-02 20:04:23 +00004436}
4437
Daniel Veillard500a1de2004-03-22 15:22:58 +00004438/**
4439 * xmlTextWriterHandleStateDependencies:
4440 * @writer: the xmlTextWriterPtr
4441 * @p: the xmlTextWriterStackEntry
4442 *
4443 * Write state dependent strings.
4444 *
4445 * Returns -1 on error or the number of characters written.
4446 */
4447static int
4448xmlTextWriterHandleStateDependencies(xmlTextWriterPtr writer,
4449 xmlTextWriterStackEntry * p)
4450{
4451 int count;
4452 int sum;
4453 char extra[3];
4454
4455 if (writer == NULL)
4456 return -1;
4457
4458 if (p == NULL)
4459 return 0;
4460
4461 sum = 0;
4462 extra[0] = extra[1] = extra[2] = '\0';
4463 if (p != 0) {
4464 sum = 0;
4465 switch (p->state) {
4466 case XML_TEXTWRITER_NAME:
4467 extra[0] = '>';
4468 p->state = XML_TEXTWRITER_TEXT;
4469 break;
4470 case XML_TEXTWRITER_PI:
4471 extra[0] = ' ';
4472 p->state = XML_TEXTWRITER_PI_TEXT;
4473 break;
4474 case XML_TEXTWRITER_DTD:
4475 extra[0] = ' ';
4476 extra[1] = '[';
4477 p->state = XML_TEXTWRITER_DTD_TEXT;
4478 break;
4479 case XML_TEXTWRITER_DTD_ELEM:
4480 extra[0] = ' ';
4481 p->state = XML_TEXTWRITER_DTD_ELEM_TEXT;
4482 break;
4483 case XML_TEXTWRITER_DTD_ATTL:
4484 extra[0] = ' ';
4485 p->state = XML_TEXTWRITER_DTD_ATTL_TEXT;
4486 break;
4487 case XML_TEXTWRITER_DTD_ENTY:
4488 case XML_TEXTWRITER_DTD_PENT:
4489 extra[0] = ' ';
4490 extra[1] = writer->qchar;
4491 p->state = XML_TEXTWRITER_DTD_ENTY_TEXT;
4492 break;
4493 default:
4494 break;
4495 }
4496 }
4497
4498 if (*extra != '\0') {
4499 count = xmlOutputBufferWriteString(writer->out, extra);
4500 if (count < 0)
4501 return -1;
4502 sum += count;
4503 }
4504
4505 return sum;
4506}
4507
Daniel Veillard1d211e22003-10-20 22:32:39 +00004508#endif