blob: e5c7e5fc80d5c56953c52fdce16ee4b0da957e3e [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 */
47 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:
1329 encode:
1330 buf = xmlEncodeSpecialChars(NULL, content);
1331 break;
1332 case XML_TEXTWRITER_ATTRIBUTE:
1333 buf = NULL;
1334 xmlAttrSerializeTxtContent(writer->out->buffer, NULL,
1335 NULL, content);
1336 break;
1337 }
1338 }
1339 }
1340
1341 if (buf != NULL) {
1342 count = xmlTextWriterWriteRaw(writer, buf);
1343 if (count < 0)
Daniel Veillard1d211e22003-10-20 22:32:39 +00001344 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001345 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001346
Daniel Veillard500a1de2004-03-22 15:22:58 +00001347 if (buf != content) /* buf was allocated by us, so free it */
1348 xmlFree(buf);
William M. Bracka9c612c2004-02-01 10:04:05 +00001349 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001350
1351 return sum;
1352}
1353
1354/**
1355 * xmlOutputBufferWriteBase64:
1356 * @out: the xmlOutputBufferPtr
1357 * @data: binary data
1358 * @len: the number of bytes to encode
1359 *
1360 * Write base64 encoded data to an xmlOutputBuffer.
1361 * Adapted from John Walker's base64.c (http://www.fourmilab.ch/).
1362 *
1363 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1364 */
1365static int
1366xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len,
1367 const unsigned char *data)
1368{
1369 static unsigned char dtable[64] =
1370 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1371 int i;
1372 int linelen;
1373 int count;
1374 int sum;
1375
1376 linelen = 0;
1377 sum = 0;
1378
1379 i = 0;
1380 while (1) {
1381 unsigned char igroup[3];
1382 unsigned char ogroup[4];
1383 int c;
1384 int n;
1385
1386 igroup[0] = igroup[1] = igroup[2] = 0;
1387 for (n = 0; n < 3 && i < len; n++, i++) {
1388 c = data[i];
1389 igroup[n] = (unsigned char) c;
1390 }
1391
1392 if (n > 0) {
1393 ogroup[0] = dtable[igroup[0] >> 2];
1394 ogroup[1] = dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)];
1395 ogroup[2] =
1396 dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)];
1397 ogroup[3] = dtable[igroup[2] & 0x3F];
1398
1399 if (n < 3) {
1400 ogroup[3] = '=';
1401 if (n < 2) {
1402 ogroup[2] = '=';
1403 }
1404 }
1405
1406 if (linelen >= B64LINELEN) {
1407 count = xmlOutputBufferWrite(out, 2, B64CRLF);
1408 if (count == -1)
1409 return -1;
1410 sum += count;
1411 linelen = 0;
1412 }
1413 count = xmlOutputBufferWrite(out, 4, (const char *) ogroup);
1414 if (count == -1)
1415 return -1;
1416 sum += count;
1417
1418 linelen += 4;
1419 }
Daniel Veillard929714b2003-10-22 12:34:36 +00001420
1421 if (i >= len)
1422 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001423 }
1424
Daniel Veillard1d211e22003-10-20 22:32:39 +00001425 return sum;
1426}
1427
1428/**
1429 * xmlTextWriterWriteBase64:
1430 * @writer: the xmlTextWriterPtr
1431 * @data: binary data
1432 * @start: the position within the data of the first byte to encode
1433 * @len: the number of bytes to encode
1434 *
1435 * Write an base64 encoded xml text.
1436 *
1437 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1438 */
1439int
Daniel Veillardab69f362004-02-17 11:40:32 +00001440xmlTextWriterWriteBase64(xmlTextWriterPtr writer, const char *data,
Daniel Veillard1d211e22003-10-20 22:32:39 +00001441 int start, int len)
1442{
1443 int count;
1444 int sum;
1445 xmlLinkPtr lk;
1446 xmlTextWriterStackEntry *p;
1447
1448 if (writer == NULL)
1449 return -1;
1450
Daniel Veillard1d211e22003-10-20 22:32:39 +00001451 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001452 lk = xmlListFront(writer->nodes);
1453 if (lk != 0) {
1454 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1455 if (p != 0) {
1456 count = xmlTextWriterHandleStateDependencies(writer, p);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001457 if (count < 0)
1458 return -1;
1459 sum += count;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001460 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001461 }
1462
Daniel Veillardab69f362004-02-17 11:40:32 +00001463 if (writer->indent)
1464 writer->doindent = 0;
1465
Daniel Veillard1d211e22003-10-20 22:32:39 +00001466 count =
1467 xmlOutputBufferWriteBase64(writer->out, len,
1468 (unsigned char *) data + start);
1469 if (count < 0)
1470 return -1;
1471 sum += count;
1472
1473 return sum;
1474}
1475
1476/**
1477 * xmlOutputBufferWriteBinHex:
1478 * @out: the xmlOutputBufferPtr
1479 * @data: binary data
1480 * @len: the number of bytes to encode
1481 *
1482 * Write hqx encoded data to an xmlOutputBuffer.
1483 * ::todo
1484 *
1485 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1486 */
1487static int
Daniel Veillardab69f362004-02-17 11:40:32 +00001488xmlOutputBufferWriteBinHex(xmlOutputBufferPtr out,
1489 int len, const unsigned char *data)
Daniel Veillard1d211e22003-10-20 22:32:39 +00001490{
Daniel Veillardab69f362004-02-17 11:40:32 +00001491 int count;
1492 int sum;
1493 static char hex[] = "0123456789ABCDEF";
1494 int i;
1495
1496 if ((out == NULL) || ((data == 0) && (len != 0))) {
1497 return -1;
1498 }
1499
1500 sum = 0;
1501 for (i = 0; i < len; i++) {
1502 count =
1503 xmlOutputBufferWrite(out, 1,
1504 (const char *) &hex[data[i] >> 4]);
1505 if (count == -1)
1506 return -1;
1507 sum += count;
1508 count =
1509 xmlOutputBufferWrite(out, 1,
1510 (const char *) &hex[data[i] & 0xF]);
1511 if (count == -1)
1512 return -1;
1513 sum += count;
1514 }
1515
1516 return sum;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001517}
1518
1519/**
1520 * xmlTextWriterWriteBinHex:
1521 * @writer: the xmlTextWriterPtr
1522 * @data: binary data
1523 * @start: the position within the data of the first byte to encode
1524 * @len: the number of bytes to encode
1525 *
1526 * Write a BinHex encoded xml text.
1527 *
1528 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1529 */
1530int
Daniel Veillardab69f362004-02-17 11:40:32 +00001531xmlTextWriterWriteBinHex(xmlTextWriterPtr writer, const char *data,
Daniel Veillard1d211e22003-10-20 22:32:39 +00001532 int start, int len)
1533{
1534 int count;
1535 int sum;
1536 xmlLinkPtr lk;
1537 xmlTextWriterStackEntry *p;
1538
1539 if (writer == NULL)
1540 return -1;
1541
Daniel Veillard1d211e22003-10-20 22:32:39 +00001542 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001543 lk = xmlListFront(writer->nodes);
1544 if (lk != 0) {
1545 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1546 if (p != 0) {
1547 count = xmlTextWriterHandleStateDependencies(writer, p);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001548 if (count < 0)
1549 return -1;
1550 sum += count;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001551 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001552 }
1553
Daniel Veillardab69f362004-02-17 11:40:32 +00001554 if (writer->indent)
1555 writer->doindent = 0;
1556
Daniel Veillard1d211e22003-10-20 22:32:39 +00001557 count =
1558 xmlOutputBufferWriteBinHex(writer->out, len,
1559 (unsigned char *) data + start);
1560 if (count < 0)
1561 return -1;
1562 sum += count;
1563
1564 return sum;
1565}
1566
1567/**
1568 * xmlTextWriterStartAttribute:
1569 * @writer: the xmlTextWriterPtr
1570 * @name: element name
1571 *
1572 * Start an xml attribute.
1573 *
1574 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1575 */
1576int
1577xmlTextWriterStartAttribute(xmlTextWriterPtr writer, const xmlChar * name)
1578{
1579 int count;
1580 int sum;
1581 xmlLinkPtr lk;
1582 xmlTextWriterStackEntry *p;
1583
1584 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1585 return -1;
1586
1587 sum = 0;
1588 lk = xmlListFront(writer->nodes);
1589 if (lk == 0)
1590 return -1;
1591
1592 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1593 if (p == 0)
1594 return -1;
1595
1596 switch (p->state) {
1597 case XML_TEXTWRITER_ATTRIBUTE:
1598 count = xmlTextWriterEndAttribute(writer);
1599 if (count < 0)
1600 return -1;
1601 sum += count;
1602 /* fallthrough */
1603 case XML_TEXTWRITER_NAME:
1604 count = xmlOutputBufferWriteString(writer->out, " ");
1605 if (count < 0)
1606 return -1;
1607 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00001608 count =
1609 xmlOutputBufferWriteString(writer->out,
1610 (const char *) name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001611 if (count < 0)
1612 return -1;
1613 sum += count;
1614 count = xmlOutputBufferWriteString(writer->out, "=");
1615 if (count < 0)
1616 return -1;
1617 sum += count;
1618 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
1619 if (count < 0)
1620 return -1;
1621 sum += count;
1622 p->state = XML_TEXTWRITER_ATTRIBUTE;
1623 break;
1624 default:
1625 return -1;
1626 }
1627
1628 return sum;
1629}
1630
1631/**
1632 * xmlTextWriterStartAttributeNS:
1633 * @writer: the xmlTextWriterPtr
1634 * @prefix: namespace prefix or NULL
1635 * @name: element local name
1636 * @namespaceURI: namespace URI or NULL
1637 *
1638 * Start an xml attribute with namespace support.
1639 *
1640 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1641 */
1642int
1643xmlTextWriterStartAttributeNS(xmlTextWriterPtr writer,
1644 const xmlChar * prefix, const xmlChar * name,
1645 const xmlChar * namespaceURI)
1646{
1647 int count;
1648 int sum;
1649 xmlChar *buf;
1650 xmlTextWriterNsStackEntry *p;
1651
1652 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1653 return -1;
1654
1655 buf = 0;
1656 if (prefix != 0) {
1657 buf = xmlStrdup(prefix);
1658 buf = xmlStrcat(buf, BAD_CAST ":");
1659 }
1660 buf = xmlStrcat(buf, name);
1661
1662 sum = 0;
1663 count = xmlTextWriterStartAttribute(writer, buf);
1664 xmlFree(buf);
1665 if (count < 0)
1666 return -1;
1667 sum += count;
1668
1669 if (namespaceURI != 0) {
1670 buf = xmlStrdup(BAD_CAST "xmlns");
1671 if (prefix != 0) {
1672 buf = xmlStrcat(buf, BAD_CAST ":");
1673 buf = xmlStrcat(buf, prefix);
1674 }
1675
1676 p = (xmlTextWriterNsStackEntry *)
1677 xmlMalloc(sizeof(xmlTextWriterNsStackEntry));
1678 if (p == 0) {
1679 xmlGenericError(xmlGenericErrorContext,
1680 "xmlTextWriterStartAttributeNS : out of memory!\n");
1681 return -1;
1682 }
1683
1684 p->prefix = buf;
1685 p->uri = xmlStrdup(namespaceURI);
1686 if (p->uri == 0) {
1687 xmlGenericError(xmlGenericErrorContext,
1688 "xmlTextWriterStartAttributeNS : out of memory!\n");
1689 xmlFree(p);
1690 return -1;
1691 }
1692 p->elem = xmlListFront(writer->nodes);
1693
1694 xmlListPushFront(writer->nsstack, p);
1695 }
1696
1697 return sum;
1698}
1699
1700/**
1701 * xmlTextWriterEndAttribute:
1702 * @writer: the xmlTextWriterPtr
1703 *
1704 * End the current xml element.
1705 *
1706 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1707 */
1708int
1709xmlTextWriterEndAttribute(xmlTextWriterPtr writer)
1710{
1711 int count;
1712 int sum;
1713 xmlLinkPtr lk;
1714 xmlTextWriterStackEntry *p;
1715 xmlTextWriterNsStackEntry *np;
1716
1717 if (writer == NULL)
1718 return -1;
1719
1720 lk = xmlListFront(writer->nodes);
1721 if (lk == 0) {
1722 xmlListDelete(writer->nsstack);
1723 return -1;
1724 }
1725
1726 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1727 if (p == 0) {
1728 xmlListDelete(writer->nsstack);
1729 return -1;
1730 }
1731
1732 sum = 0;
1733 switch (p->state) {
1734 case XML_TEXTWRITER_ATTRIBUTE:
1735 p->state = XML_TEXTWRITER_NAME;
1736
1737 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
1738 if (count < 0) {
1739 xmlListDelete(writer->nsstack);
1740 return -1;
1741 }
1742 sum += count;
1743
1744 while (!xmlListEmpty(writer->nsstack)) {
1745 lk = xmlListFront(writer->nsstack);
1746 np = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
1747 if (np != 0) {
1748 count =
1749 xmlTextWriterWriteAttribute(writer, np->prefix,
1750 np->uri);
1751 if (count < 0) {
1752 xmlListDelete(writer->nsstack);
1753 return -1;
1754 }
1755 sum += count;
1756 }
1757
1758 xmlListPopFront(writer->nsstack);
1759 }
1760 break;
1761
1762 default:
1763 xmlListClear(writer->nsstack);
1764 return -1;
1765 }
1766
1767 return sum;
1768}
1769
1770/**
1771 * xmlTextWriterWriteFormatAttribute:
1772 * @writer: the xmlTextWriterPtr
1773 * @name: attribute name
1774 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001775 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001776 *
1777 * Write a formatted xml attribute.
1778 *
1779 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1780 */
1781int
1782xmlTextWriterWriteFormatAttribute(xmlTextWriterPtr writer,
1783 const xmlChar * name, const char *format,
1784 ...)
1785{
1786 int rc;
1787 va_list ap;
1788
1789 va_start(ap, format);
1790
1791 rc = xmlTextWriterWriteVFormatAttribute(writer, name, format, ap);
1792
1793 va_end(ap);
1794 return rc;
1795}
1796
1797/**
1798 * xmlTextWriterWriteVFormatAttribute:
1799 * @writer: the xmlTextWriterPtr
1800 * @name: attribute name
1801 * @format: format string (see printf)
1802 * @argptr: pointer to the first member of the variable argument list.
1803 *
1804 * Write a formatted xml attribute.
1805 *
1806 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1807 */
1808int
1809xmlTextWriterWriteVFormatAttribute(xmlTextWriterPtr writer,
1810 const xmlChar * name,
1811 const char *format, va_list argptr)
1812{
1813 int rc;
1814 xmlChar *buf;
1815
1816 if (writer == NULL)
1817 return -1;
1818
1819 buf = xmlTextWriterVSprintf(format, argptr);
1820 if (buf == 0)
1821 return 0;
1822
1823 rc = xmlTextWriterWriteAttribute(writer, name, buf);
1824
1825 xmlFree(buf);
1826 return rc;
1827}
1828
1829/**
1830 * xmlTextWriterWriteAttribute:
1831 * @writer: the xmlTextWriterPtr
1832 * @name: attribute name
1833 * @content: attribute content
1834 *
1835 * Write an xml attribute.
1836 *
1837 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1838 */
1839int
1840xmlTextWriterWriteAttribute(xmlTextWriterPtr writer, const xmlChar * name,
1841 const xmlChar * content)
1842{
1843 int count;
1844 int sum;
1845
1846 sum = 0;
1847 count = xmlTextWriterStartAttribute(writer, name);
1848 if (count < 0)
1849 return -1;
1850 sum += count;
1851 count = xmlTextWriterWriteString(writer, content);
1852 if (count < 0)
1853 return -1;
1854 sum += count;
1855 count = xmlTextWriterEndAttribute(writer);
1856 if (count < 0)
1857 return -1;
1858 sum += count;
1859
1860 return sum;
1861}
1862
1863/**
1864 * xmlTextWriterWriteFormatAttributeNS:
1865 * @writer: the xmlTextWriterPtr
1866 * @prefix: namespace prefix
1867 * @name: attribute local name
1868 * @namespaceURI: namespace URI
1869 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001870 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001871 *
1872 * Write a formatted xml attribute.with namespace support
1873 *
1874 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1875 */
1876int
1877xmlTextWriterWriteFormatAttributeNS(xmlTextWriterPtr writer,
1878 const xmlChar * prefix,
1879 const xmlChar * name,
1880 const xmlChar * namespaceURI,
1881 const char *format, ...)
1882{
1883 int rc;
1884 va_list ap;
1885
1886 va_start(ap, format);
1887
1888 rc = xmlTextWriterWriteVFormatAttributeNS(writer, prefix, name,
1889 namespaceURI, format, ap);
1890
1891 va_end(ap);
1892 return rc;
1893}
1894
1895/**
1896 * xmlTextWriterWriteVFormatAttributeNS:
1897 * @writer: the xmlTextWriterPtr
1898 * @prefix: namespace prefix
1899 * @name: attribute local name
1900 * @namespaceURI: namespace URI
1901 * @format: format string (see printf)
1902 * @argptr: pointer to the first member of the variable argument list.
1903 *
1904 * Write a formatted xml attribute.with namespace support
1905 *
1906 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1907 */
1908int
1909xmlTextWriterWriteVFormatAttributeNS(xmlTextWriterPtr writer,
1910 const xmlChar * prefix,
1911 const xmlChar * name,
1912 const xmlChar * namespaceURI,
1913 const char *format, va_list argptr)
1914{
1915 int rc;
1916 xmlChar *buf;
1917
1918 if (writer == NULL)
1919 return -1;
1920
1921 buf = xmlTextWriterVSprintf(format, argptr);
1922 if (buf == 0)
1923 return 0;
1924
1925 rc = xmlTextWriterWriteAttributeNS(writer, prefix, name, namespaceURI,
1926 buf);
1927
1928 xmlFree(buf);
1929 return rc;
1930}
1931
1932/**
1933 * xmlTextWriterWriteAttributeNS:
1934 * @writer: the xmlTextWriterPtr
1935 * @prefix: namespace prefix
1936 * @name: attribute local name
1937 * @namespaceURI: namespace URI
1938 * @content: attribute content
1939 *
1940 * Write an xml attribute.
1941 *
1942 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1943 */
1944int
1945xmlTextWriterWriteAttributeNS(xmlTextWriterPtr writer,
1946 const xmlChar * prefix, const xmlChar * name,
1947 const xmlChar * namespaceURI,
1948 const xmlChar * content)
1949{
1950 int count;
1951 int sum;
1952 xmlChar *buf;
1953
1954 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1955 return -1;
1956
1957 buf = 0;
1958 if (prefix != NULL) {
1959 buf = xmlStrdup(prefix);
1960 buf = xmlStrcat(buf, BAD_CAST ":");
1961 }
1962 buf = xmlStrcat(buf, name);
1963
1964 sum = 0;
1965 count = xmlTextWriterWriteAttribute(writer, buf, content);
1966 xmlFree(buf);
1967 if (count < 0)
1968 return -1;
1969 sum += count;
1970
1971 if (namespaceURI != NULL) {
1972 buf = 0;
1973 buf = xmlStrdup(BAD_CAST "xmlns");
1974 if (prefix != NULL) {
1975 buf = xmlStrcat(buf, BAD_CAST ":");
1976 buf = xmlStrcat(buf, prefix);
1977 }
1978 count = xmlTextWriterWriteAttribute(writer, buf, namespaceURI);
1979 xmlFree(buf);
1980 if (count < 0)
1981 return -1;
1982 sum += count;
1983 }
1984 return sum;
1985}
1986
1987/**
1988 * xmlTextWriterWriteFormatElement:
1989 * @writer: the xmlTextWriterPtr
1990 * @name: element name
1991 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001992 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001993 *
1994 * Write a formatted xml element.
1995 *
1996 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1997 */
1998int
1999xmlTextWriterWriteFormatElement(xmlTextWriterPtr writer,
2000 const xmlChar * name, const char *format,
2001 ...)
2002{
2003 int rc;
2004 va_list ap;
2005
2006 va_start(ap, format);
2007
2008 rc = xmlTextWriterWriteVFormatElement(writer, name, format, ap);
2009
2010 va_end(ap);
2011 return rc;
2012}
2013
2014/**
2015 * xmlTextWriterWriteVFormatElement:
2016 * @writer: the xmlTextWriterPtr
2017 * @name: element name
2018 * @format: format string (see printf)
2019 * @argptr: pointer to the first member of the variable argument list.
2020 *
2021 * Write a formatted xml element.
2022 *
2023 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2024 */
2025int
2026xmlTextWriterWriteVFormatElement(xmlTextWriterPtr writer,
2027 const xmlChar * name, const char *format,
2028 va_list argptr)
2029{
2030 int rc;
2031 xmlChar *buf;
2032
2033 if (writer == NULL)
2034 return -1;
2035
2036 buf = xmlTextWriterVSprintf(format, argptr);
2037 if (buf == 0)
2038 return 0;
2039
2040 rc = xmlTextWriterWriteElement(writer, name, buf);
2041
2042 xmlFree(buf);
2043 return rc;
2044}
2045
2046/**
2047 * xmlTextWriterWriteElement:
2048 * @writer: the xmlTextWriterPtr
2049 * @name: element name
2050 * @content: element content
2051 *
2052 * Write an xml element.
2053 *
2054 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2055 */
2056int
2057xmlTextWriterWriteElement(xmlTextWriterPtr writer, const xmlChar * name,
2058 const xmlChar * content)
2059{
2060 int count;
2061 int sum;
2062
2063 sum = 0;
2064 count = xmlTextWriterStartElement(writer, name);
2065 if (count == -1)
2066 return -1;
2067 sum += count;
2068 count = xmlTextWriterWriteString(writer, content);
2069 if (count == -1)
2070 return -1;
2071 sum += count;
2072 count = xmlTextWriterEndElement(writer);
2073 if (count == -1)
2074 return -1;
2075 sum += count;
2076
2077 return sum;
2078}
2079
2080/**
2081 * xmlTextWriterWriteFormatElementNS:
2082 * @writer: the xmlTextWriterPtr
2083 * @prefix: namespace prefix
2084 * @name: element local name
2085 * @namespaceURI: namespace URI
2086 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002087 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002088 *
2089 * Write a formatted xml element with namespace support.
2090 *
2091 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2092 */
2093int
2094xmlTextWriterWriteFormatElementNS(xmlTextWriterPtr writer,
2095 const xmlChar * prefix,
2096 const xmlChar * name,
2097 const xmlChar * namespaceURI,
2098 const char *format, ...)
2099{
2100 int rc;
2101 va_list ap;
2102
2103 va_start(ap, format);
2104
2105 rc = xmlTextWriterWriteVFormatElementNS(writer, prefix, name,
2106 namespaceURI, format, ap);
2107
2108 va_end(ap);
2109 return rc;
2110}
2111
2112/**
2113 * xmlTextWriterWriteVFormatElementNS:
2114 * @writer: the xmlTextWriterPtr
2115 * @prefix: namespace prefix
2116 * @name: element local name
2117 * @namespaceURI: namespace URI
2118 * @format: format string (see printf)
2119 * @argptr: pointer to the first member of the variable argument list.
2120 *
2121 * Write a formatted xml element with namespace support.
2122 *
2123 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2124 */
2125int
2126xmlTextWriterWriteVFormatElementNS(xmlTextWriterPtr writer,
2127 const xmlChar * prefix,
2128 const xmlChar * name,
2129 const xmlChar * namespaceURI,
2130 const char *format, va_list argptr)
2131{
2132 int rc;
2133 xmlChar *buf;
2134
2135 if (writer == NULL)
2136 return -1;
2137
2138 buf = xmlTextWriterVSprintf(format, argptr);
2139 if (buf == 0)
2140 return 0;
2141
2142 rc = xmlTextWriterWriteElementNS(writer, prefix, name, namespaceURI,
2143 buf);
2144
2145 xmlFree(buf);
2146 return rc;
2147}
2148
2149/**
2150 * xmlTextWriterWriteElementNS:
2151 * @writer: the xmlTextWriterPtr
2152 * @prefix: namespace prefix
2153 * @name: element local name
2154 * @namespaceURI: namespace URI
2155 * @content: element content
2156 *
2157 * Write an xml element with namespace support.
2158 *
2159 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2160 */
2161int
2162xmlTextWriterWriteElementNS(xmlTextWriterPtr writer,
2163 const xmlChar * prefix, const xmlChar * name,
2164 const xmlChar * namespaceURI,
2165 const xmlChar * content)
2166{
2167 int count;
2168 int sum;
2169
2170 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
2171 return -1;
2172
2173 sum = 0;
2174 count =
2175 xmlTextWriterStartElementNS(writer, prefix, name, namespaceURI);
2176 if (count < 0)
2177 return -1;
2178 sum += count;
2179 count = xmlTextWriterWriteString(writer, content);
2180 if (count == -1)
2181 return -1;
2182 sum += count;
2183 count = xmlTextWriterEndElement(writer);
2184 if (count == -1)
2185 return -1;
2186 sum += count;
2187
2188 return sum;
2189}
2190
2191/**
2192 * xmlTextWriterStartPI:
2193 * @writer: the xmlTextWriterPtr
2194 * @target: PI target
2195 *
2196 * Start an xml PI.
2197 *
2198 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2199 */
2200int
2201xmlTextWriterStartPI(xmlTextWriterPtr writer, const xmlChar * target)
2202{
2203 int count;
2204 int sum;
2205 xmlLinkPtr lk;
2206 xmlTextWriterStackEntry *p;
2207
2208 if ((writer == NULL) || (target == NULL) || (*target == '\0'))
2209 return -1;
2210
2211 if (xmlStrcasecmp(target, (const xmlChar *) "xml") == 0) {
2212 xmlGenericError(xmlGenericErrorContext,
2213 "xmlTextWriterStartPI : target name [Xx][Mm][Ll] is reserved for xml standardization!\n");
2214 return -1;
2215 }
2216
2217 sum = 0;
2218 lk = xmlListFront(writer->nodes);
2219 if (lk != 0) {
2220 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2221 if (p != 0) {
2222 switch (p->state) {
2223 case XML_TEXTWRITER_ATTRIBUTE:
2224 count = xmlTextWriterEndAttribute(writer);
2225 if (count < 0)
2226 return -1;
2227 sum += count;
2228 /* fallthrough */
2229 case XML_TEXTWRITER_NAME:
2230 count = xmlOutputBufferWriteString(writer->out, ">");
2231 if (count < 0)
2232 return -1;
2233 sum += count;
2234 p->state = XML_TEXTWRITER_TEXT;
2235 break;
Daniel Veillardab69f362004-02-17 11:40:32 +00002236 case XML_TEXTWRITER_NONE:
2237 case XML_TEXTWRITER_TEXT:
2238 case XML_TEXTWRITER_DTD:
2239 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002240 case XML_TEXTWRITER_PI:
2241 case XML_TEXTWRITER_PI_TEXT:
2242 xmlGenericError(xmlGenericErrorContext,
2243 "xmlTextWriterStartPI : nested PI!\n");
2244 return -1;
2245 default:
2246 return -1;
2247 }
2248 }
2249 }
2250
2251 p = (xmlTextWriterStackEntry *)
2252 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2253 if (p == 0) {
2254 xmlGenericError(xmlGenericErrorContext,
2255 "xmlTextWriterStartPI : out of memory!\n");
2256 return -1;
2257 }
2258
2259 p->name = xmlStrdup(target);
2260 if (p->name == 0) {
2261 xmlGenericError(xmlGenericErrorContext,
2262 "xmlTextWriterStartPI : out of memory!\n");
2263 xmlFree(p);
2264 return -1;
2265 }
2266 p->state = XML_TEXTWRITER_PI;
2267
2268 xmlListPushFront(writer->nodes, p);
2269
2270 count = xmlOutputBufferWriteString(writer->out, "<?");
2271 if (count < 0)
2272 return -1;
2273 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002274 count =
2275 xmlOutputBufferWriteString(writer->out, (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002276 if (count < 0)
2277 return -1;
2278 sum += count;
2279
2280 return sum;
2281}
2282
2283/**
2284 * xmlTextWriterEndPI:
2285 * @writer: the xmlTextWriterPtr
2286 *
2287 * End the current xml PI.
2288 *
2289 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2290 */
2291int
2292xmlTextWriterEndPI(xmlTextWriterPtr writer)
2293{
2294 int count;
2295 int sum;
2296 xmlLinkPtr lk;
2297 xmlTextWriterStackEntry *p;
2298
2299 if (writer == NULL)
2300 return -1;
2301
2302 lk = xmlListFront(writer->nodes);
2303 if (lk == 0)
2304 return 0;
2305
2306 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2307 if (p == 0)
2308 return 0;
2309
2310 sum = 0;
2311 switch (p->state) {
2312 case XML_TEXTWRITER_PI:
2313 case XML_TEXTWRITER_PI_TEXT:
2314 count = xmlOutputBufferWriteString(writer->out, "?>");
2315 if (count < 0)
2316 return -1;
2317 sum += count;
2318 break;
2319 default:
2320 return -1;
2321 }
2322
2323 xmlListPopFront(writer->nodes);
2324 return sum;
2325}
2326
2327/**
2328 * xmlTextWriterWriteFormatPI:
2329 * @writer: the xmlTextWriterPtr
2330 * @target: PI target
2331 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002332 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002333 *
2334 * Write a formatted PI.
2335 *
2336 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2337 */
2338int
2339xmlTextWriterWriteFormatPI(xmlTextWriterPtr writer, const xmlChar * target,
2340 const char *format, ...)
2341{
2342 int rc;
2343 va_list ap;
2344
2345 va_start(ap, format);
2346
2347 rc = xmlTextWriterWriteVFormatPI(writer, target, format, ap);
2348
2349 va_end(ap);
2350 return rc;
2351}
2352
2353/**
2354 * xmlTextWriterWriteVFormatPI:
2355 * @writer: the xmlTextWriterPtr
2356 * @target: PI target
2357 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002358 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00002359 *
2360 * Write a formatted xml PI.
2361 *
2362 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2363 */
2364int
2365xmlTextWriterWriteVFormatPI(xmlTextWriterPtr writer,
2366 const xmlChar * target, const char *format,
2367 va_list argptr)
2368{
2369 int rc;
2370 xmlChar *buf;
2371
2372 if (writer == NULL)
2373 return -1;
2374
2375 buf = xmlTextWriterVSprintf(format, argptr);
2376 if (buf == 0)
2377 return 0;
2378
2379 rc = xmlTextWriterWritePI(writer, target, buf);
2380
2381 xmlFree(buf);
2382 return rc;
2383}
2384
2385/**
2386 * xmlTextWriterWritePI:
2387 * @writer: the xmlTextWriterPtr
2388 * @target: PI target
2389 * @content: PI content
2390 *
2391 * Write an xml PI.
2392 *
2393 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2394 */
2395int
2396xmlTextWriterWritePI(xmlTextWriterPtr writer, const xmlChar * target,
2397 const xmlChar * content)
2398{
2399 int count;
2400 int sum;
2401
2402 sum = 0;
2403 count = xmlTextWriterStartPI(writer, target);
2404 if (count == -1)
2405 return -1;
2406 sum += count;
2407 if (content != 0) {
2408 count = xmlTextWriterWriteString(writer, content);
2409 if (count == -1)
2410 return -1;
2411 sum += count;
2412 }
2413 count = xmlTextWriterEndPI(writer);
2414 if (count == -1)
2415 return -1;
2416 sum += count;
2417
2418 return sum;
2419}
2420
2421/**
2422 * xmlTextWriterStartCDATA:
2423 * @writer: the xmlTextWriterPtr
2424 *
2425 * Start an xml CDATA section.
2426 *
2427 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2428 */
2429int
2430xmlTextWriterStartCDATA(xmlTextWriterPtr writer)
2431{
2432 int count;
2433 int sum;
2434 xmlLinkPtr lk;
2435 xmlTextWriterStackEntry *p;
2436
2437 if (writer == NULL)
2438 return -1;
2439
2440 sum = 0;
2441 lk = xmlListFront(writer->nodes);
2442 if (lk != 0) {
2443 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2444 if (p != 0) {
2445 switch (p->state) {
2446 case XML_TEXTWRITER_NONE:
2447 case XML_TEXTWRITER_PI:
2448 case XML_TEXTWRITER_PI_TEXT:
2449 break;
2450 case XML_TEXTWRITER_ATTRIBUTE:
2451 count = xmlTextWriterEndAttribute(writer);
2452 if (count < 0)
2453 return -1;
2454 sum += count;
2455 /* fallthrough */
2456 case XML_TEXTWRITER_NAME:
2457 count = xmlOutputBufferWriteString(writer->out, ">");
2458 if (count < 0)
2459 return -1;
2460 sum += count;
2461 p->state = XML_TEXTWRITER_TEXT;
2462 break;
2463 case XML_TEXTWRITER_CDATA:
2464 xmlGenericError(xmlGenericErrorContext,
2465 "xmlTextWriterStartCDATA : CDATA not allowed in this context!\n");
2466 return -1;
2467 default:
2468 return -1;
2469 }
2470 }
2471 }
2472
2473 p = (xmlTextWriterStackEntry *)
2474 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2475 if (p == 0) {
2476 xmlGenericError(xmlGenericErrorContext,
2477 "xmlTextWriterStartCDATA : out of memory!\n");
2478 return -1;
2479 }
2480
2481 p->name = 0;
2482 p->state = XML_TEXTWRITER_CDATA;
2483
2484 xmlListPushFront(writer->nodes, p);
2485
2486 count = xmlOutputBufferWriteString(writer->out, "<![CDATA[");
2487 if (count < 0)
2488 return -1;
2489 sum += count;
2490
2491 return sum;
2492}
2493
2494/**
2495 * xmlTextWriterEndCDATA:
2496 * @writer: the xmlTextWriterPtr
2497 *
2498 * End an xml CDATA section.
2499 *
2500 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2501 */
2502int
2503xmlTextWriterEndCDATA(xmlTextWriterPtr writer)
2504{
2505 int count;
2506 int sum;
2507 xmlLinkPtr lk;
2508 xmlTextWriterStackEntry *p;
2509
2510 if (writer == NULL)
2511 return -1;
2512
2513 lk = xmlListFront(writer->nodes);
2514 if (lk == 0)
2515 return -1;
2516
2517 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2518 if (p == 0)
2519 return -1;
2520
2521 sum = 0;
2522 switch (p->state) {
2523 case XML_TEXTWRITER_CDATA:
2524 count = xmlOutputBufferWriteString(writer->out, "]]>");
2525 if (count < 0)
2526 return -1;
2527 sum += count;
2528 break;
2529 default:
2530 return -1;
2531 }
2532
2533 xmlListPopFront(writer->nodes);
2534 return sum;
2535}
2536
2537/**
2538 * xmlTextWriterWriteFormatCDATA:
2539 * @writer: the xmlTextWriterPtr
2540 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002541 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002542 *
2543 * Write a formatted xml CDATA.
2544 *
2545 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2546 */
2547int
2548xmlTextWriterWriteFormatCDATA(xmlTextWriterPtr writer, const char *format,
2549 ...)
2550{
2551 int rc;
2552 va_list ap;
2553
2554 va_start(ap, format);
2555
2556 rc = xmlTextWriterWriteVFormatCDATA(writer, format, ap);
2557
2558 va_end(ap);
2559 return rc;
2560}
2561
2562/**
2563 * xmlTextWriterWriteVFormatCDATA:
2564 * @writer: the xmlTextWriterPtr
2565 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002566 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00002567 *
2568 * Write a formatted xml CDATA.
2569 *
2570 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2571 */
2572int
2573xmlTextWriterWriteVFormatCDATA(xmlTextWriterPtr writer, const char *format,
2574 va_list argptr)
2575{
2576 int rc;
2577 xmlChar *buf;
2578
2579 if (writer == NULL)
2580 return -1;
2581
2582 buf = xmlTextWriterVSprintf(format, argptr);
2583 if (buf == 0)
2584 return 0;
2585
2586 rc = xmlTextWriterWriteCDATA(writer, buf);
2587
2588 xmlFree(buf);
2589 return rc;
2590}
2591
2592/**
2593 * xmlTextWriterWriteCDATA:
2594 * @writer: the xmlTextWriterPtr
2595 * @content: CDATA content
2596 *
2597 * Write an xml CDATA.
2598 *
2599 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2600 */
2601int
2602xmlTextWriterWriteCDATA(xmlTextWriterPtr writer, const xmlChar * content)
2603{
2604 int count;
2605 int sum;
2606
2607 sum = 0;
2608 count = xmlTextWriterStartCDATA(writer);
2609 if (count == -1)
2610 return -1;
2611 sum += count;
2612 if (content != 0) {
2613 count = xmlTextWriterWriteString(writer, content);
2614 if (count == -1)
2615 return -1;
2616 sum += count;
2617 }
2618 count = xmlTextWriterEndCDATA(writer);
2619 if (count == -1)
2620 return -1;
2621 sum += count;
2622
2623 return sum;
2624}
2625
2626/**
2627 * xmlTextWriterStartDTD:
2628 * @writer: the xmlTextWriterPtr
2629 * @name: the name of the DTD
2630 * @pubid: the public identifier, which is an alternative to the system identifier
2631 * @sysid: the system identifier, which is the URI of the DTD
2632 *
2633 * Start an xml DTD.
2634 *
2635 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2636 */
2637int
2638xmlTextWriterStartDTD(xmlTextWriterPtr writer,
2639 const xmlChar * name,
2640 const xmlChar * pubid, const xmlChar * sysid)
2641{
2642 int count;
2643 int sum;
2644 xmlLinkPtr lk;
2645 xmlTextWriterStackEntry *p;
2646
2647 if (writer == NULL || name == NULL || *name == '\0')
2648 return -1;
2649
2650 sum = 0;
2651 lk = xmlListFront(writer->nodes);
Daniel Veillardab69f362004-02-17 11:40:32 +00002652 if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) {
Daniel Veillard1d211e22003-10-20 22:32:39 +00002653 xmlGenericError(xmlGenericErrorContext,
2654 "xmlTextWriterStartDTD : DTD allowed only in prolog!\n");
2655 return -1;
2656 }
2657
2658 p = (xmlTextWriterStackEntry *)
2659 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2660 if (p == 0) {
2661 xmlGenericError(xmlGenericErrorContext,
2662 "xmlTextWriterStartDTD : out of memory!\n");
2663 return -1;
2664 }
2665
2666 p->name = xmlStrdup(name);
2667 if (p->name == 0) {
2668 xmlGenericError(xmlGenericErrorContext,
2669 "xmlTextWriterStartDTD : out of memory!\n");
2670 xmlFree(p);
2671 return -1;
2672 }
2673 p->state = XML_TEXTWRITER_DTD;
2674
2675 xmlListPushFront(writer->nodes, p);
2676
2677 count = xmlOutputBufferWriteString(writer->out, "<!DOCTYPE ");
2678 if (count < 0)
2679 return -1;
2680 sum += count;
2681 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
2682 if (count < 0)
2683 return -1;
2684 sum += count;
2685
2686 if (pubid != 0) {
2687 if (sysid == 0) {
2688 xmlGenericError(xmlGenericErrorContext,
2689 "xmlTextWriterStartDTD : system identifier needed!\n");
2690 return -1;
2691 }
2692
Daniel Veillard500a1de2004-03-22 15:22:58 +00002693 if (writer->indent)
2694 count = xmlOutputBufferWrite(writer->out, 1, "\n");
2695 else
2696 count = xmlOutputBufferWrite(writer->out, 1, " ");
2697 if (count < 0)
2698 return -1;
2699 sum += count;
2700
2701 count = xmlOutputBufferWriteString(writer->out, "PUBLIC ");
2702 if (count < 0)
2703 return -1;
2704 sum += count;
2705
2706 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002707 if (count < 0)
2708 return -1;
2709 sum += count;
2710
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002711 count =
2712 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002713 if (count < 0)
2714 return -1;
2715 sum += count;
2716
Daniel Veillard500a1de2004-03-22 15:22:58 +00002717 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002718 if (count < 0)
2719 return -1;
2720 sum += count;
2721 }
2722
2723 if (sysid != 0) {
2724 if (pubid == 0) {
Daniel Veillard500a1de2004-03-22 15:22:58 +00002725 if (writer->indent)
2726 count = xmlOutputBufferWrite(writer->out, 1, "\n");
2727 else
2728 count = xmlOutputBufferWrite(writer->out, 1, " ");
2729 if (count < 0)
2730 return -1;
2731 sum += count;
2732 count = xmlOutputBufferWriteString(writer->out, "SYSTEM ");
2733 if (count < 0)
2734 return -1;
2735 sum += count;
2736 } else if (writer->indent) {
2737 count = xmlOutputBufferWriteString(writer->out, "\n ");
Daniel Veillard1d211e22003-10-20 22:32:39 +00002738 if (count < 0)
2739 return -1;
2740 sum += count;
2741 }
2742
Daniel Veillard500a1de2004-03-22 15:22:58 +00002743 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002744 if (count < 0)
2745 return -1;
2746 sum += count;
2747
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002748 count =
2749 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002750 if (count < 0)
2751 return -1;
2752 sum += count;
2753
Daniel Veillard500a1de2004-03-22 15:22:58 +00002754 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002755 if (count < 0)
2756 return -1;
2757 sum += count;
2758 }
2759
2760 return sum;
2761}
2762
2763/**
2764 * xmlTextWriterEndDTD:
2765 * @writer: the xmlTextWriterPtr
2766 *
2767 * End an xml DTD.
2768 *
2769 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2770 */
2771int
2772xmlTextWriterEndDTD(xmlTextWriterPtr writer)
2773{
Daniel Veillard500a1de2004-03-22 15:22:58 +00002774 int loop;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002775 int count;
2776 int sum;
2777 xmlLinkPtr lk;
2778 xmlTextWriterStackEntry *p;
2779
2780 if (writer == NULL)
2781 return -1;
2782
2783 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00002784 loop = 1;
2785 while (loop) {
2786 lk = xmlListFront(writer->nodes);
2787 if (lk == NULL)
Daniel Veillard1d211e22003-10-20 22:32:39 +00002788 break;
Daniel Veillard500a1de2004-03-22 15:22:58 +00002789 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2790 if (p == 0)
2791 break;
2792 switch (p->state) {
2793 case XML_TEXTWRITER_DTD_TEXT:
2794 count = xmlOutputBufferWriteString(writer->out, "]");
2795 if (count < 0)
2796 return -1;
2797 sum += count;
2798 /* fallthrough */
2799 case XML_TEXTWRITER_DTD:
2800 count = xmlOutputBufferWriteString(writer->out, ">");
2801
2802 if (writer->indent) {
2803 if (count < 0)
2804 return -1;
2805 sum += count;
2806 count = xmlOutputBufferWriteString(writer->out, "\n");
2807 }
2808
2809 xmlListPopFront(writer->nodes);
2810 break;
2811 case XML_TEXTWRITER_DTD_ELEM:
2812 case XML_TEXTWRITER_DTD_ELEM_TEXT:
2813 count = xmlTextWriterEndDTDElement(writer);
2814 break;
2815 case XML_TEXTWRITER_DTD_ATTL:
2816 case XML_TEXTWRITER_DTD_ATTL_TEXT:
2817 count = xmlTextWriterEndDTDAttlist(writer);
2818 break;
2819 case XML_TEXTWRITER_DTD_ENTY:
2820 case XML_TEXTWRITER_DTD_PENT:
2821 case XML_TEXTWRITER_DTD_ENTY_TEXT:
2822 count = xmlTextWriterEndDTDEntity(writer);
2823 break;
2824 case XML_TEXTWRITER_COMMENT:
2825 count = xmlTextWriterEndComment(writer);
2826 break;
2827 default:
2828 loop = 0;
2829 continue;
2830 }
2831
2832 if (count < 0)
Daniel Veillard1d211e22003-10-20 22:32:39 +00002833 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00002834 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002835 }
2836
Daniel Veillard1d211e22003-10-20 22:32:39 +00002837 return sum;
2838}
2839
2840/**
2841 * xmlTextWriterWriteFormatDTD:
2842 * @writer: the xmlTextWriterPtr
2843 * @name: the name of the DTD
2844 * @pubid: the public identifier, which is an alternative to the system identifier
2845 * @sysid: the system identifier, which is the URI of the DTD
2846 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002847 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002848 *
2849 * Write a DTD with a formatted markup declarations part.
2850 *
2851 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2852 */
2853int
2854xmlTextWriterWriteFormatDTD(xmlTextWriterPtr writer,
2855 const xmlChar * name,
2856 const xmlChar * pubid,
2857 const xmlChar * sysid, const char *format, ...)
2858{
2859 int rc;
2860 va_list ap;
2861
2862 va_start(ap, format);
2863
2864 rc = xmlTextWriterWriteVFormatDTD(writer, name, pubid, sysid, format,
2865 ap);
2866
2867 va_end(ap);
2868 return rc;
2869}
2870
2871/**
2872 * xmlTextWriterWriteVFormatDTD:
2873 * @writer: the xmlTextWriterPtr
2874 * @name: the name of the DTD
2875 * @pubid: the public identifier, which is an alternative to the system identifier
2876 * @sysid: the system identifier, which is the URI of the DTD
2877 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002878 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00002879 *
2880 * Write a DTD with a formatted markup declarations part.
2881 *
2882 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2883 */
2884int
2885xmlTextWriterWriteVFormatDTD(xmlTextWriterPtr writer,
2886 const xmlChar * name,
2887 const xmlChar * pubid,
2888 const xmlChar * sysid,
2889 const char *format, va_list argptr)
2890{
2891 int rc;
2892 xmlChar *buf;
2893
2894 if (writer == NULL)
2895 return -1;
2896
2897 buf = xmlTextWriterVSprintf(format, argptr);
2898 if (buf == 0)
2899 return 0;
2900
2901 rc = xmlTextWriterWriteDTD(writer, name, pubid, sysid, buf);
2902
2903 xmlFree(buf);
2904 return rc;
2905}
2906
2907/**
2908 * xmlTextWriterWriteDTD:
2909 * @writer: the xmlTextWriterPtr
2910 * @name: the name of the DTD
2911 * @pubid: the public identifier, which is an alternative to the system identifier
2912 * @sysid: the system identifier, which is the URI of the DTD
William M. Brackb1d53162003-11-18 06:54:40 +00002913 * @subset: string content of the DTD
Daniel Veillard1d211e22003-10-20 22:32:39 +00002914 *
2915 * Write a DTD.
2916 *
2917 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2918 */
2919int
2920xmlTextWriterWriteDTD(xmlTextWriterPtr writer,
2921 const xmlChar * name,
2922 const xmlChar * pubid,
2923 const xmlChar * sysid, const xmlChar * subset)
2924{
2925 int count;
2926 int sum;
2927
2928 sum = 0;
2929 count = xmlTextWriterStartDTD(writer, name, pubid, sysid);
2930 if (count == -1)
2931 return -1;
2932 sum += count;
2933 if (subset != 0) {
2934 count = xmlTextWriterWriteString(writer, subset);
2935 if (count == -1)
2936 return -1;
2937 sum += count;
2938 }
2939 count = xmlTextWriterEndDTD(writer);
2940 if (count == -1)
2941 return -1;
2942 sum += count;
2943
2944 return sum;
2945}
2946
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002947/**
2948 * xmlTextWriterStartDTDElement:
2949 * @writer: the xmlTextWriterPtr
2950 * @name: the name of the DTD element
2951 *
2952 * Start an xml DTD element.
2953 *
2954 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2955 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00002956int
2957xmlTextWriterStartDTDElement(xmlTextWriterPtr writer, const xmlChar * name)
2958{
2959 int count;
2960 int sum;
2961 xmlLinkPtr lk;
2962 xmlTextWriterStackEntry *p;
2963
2964 if (writer == NULL || name == NULL || *name == '\0')
2965 return -1;
2966
2967 sum = 0;
2968 lk = xmlListFront(writer->nodes);
2969 if (lk == 0) {
2970 return -1;
2971 }
2972
2973 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
Daniel Veillard500a1de2004-03-22 15:22:58 +00002974 if (p != 0) {
2975 switch (p->state) {
2976 case XML_TEXTWRITER_DTD:
2977 count = xmlOutputBufferWriteString(writer->out, " [");
2978 if (count < 0)
2979 return -1;
2980 sum += count;
2981 if (writer->indent) {
2982 count = xmlOutputBufferWriteString(writer->out, "\n");
2983 if (count < 0)
2984 return -1;
2985 sum += count;
2986 }
2987 p->state = XML_TEXTWRITER_DTD_TEXT;
2988 /* fallthrough */
2989 case XML_TEXTWRITER_DTD_TEXT:
2990 case XML_TEXTWRITER_NONE:
2991 break;
2992 default:
Daniel Veillard1d211e22003-10-20 22:32:39 +00002993 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00002994 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00002995 }
2996
2997 p = (xmlTextWriterStackEntry *)
2998 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2999 if (p == 0) {
3000 xmlGenericError(xmlGenericErrorContext,
3001 "xmlTextWriterStartDTDElement : out of memory!\n");
3002 return -1;
3003 }
3004
3005 p->name = xmlStrdup(name);
3006 if (p->name == 0) {
3007 xmlGenericError(xmlGenericErrorContext,
3008 "xmlTextWriterStartDTDElement : out of memory!\n");
3009 xmlFree(p);
3010 return -1;
3011 }
3012 p->state = XML_TEXTWRITER_DTD_ELEM;
3013
3014 xmlListPushFront(writer->nodes, p);
3015
Daniel Veillard500a1de2004-03-22 15:22:58 +00003016 if (writer->indent) {
3017 count = xmlTextWriterWriteIndent(writer);
3018 if (count < 0)
3019 return -1;
3020 sum += count;
3021 }
3022
Daniel Veillard1d211e22003-10-20 22:32:39 +00003023 count = xmlOutputBufferWriteString(writer->out, "<!ELEMENT ");
3024 if (count < 0)
3025 return -1;
3026 sum += count;
3027 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
3028 if (count < 0)
3029 return -1;
3030 sum += count;
3031
3032 return sum;
3033}
3034
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003035/**
Daniel Veillard500a1de2004-03-22 15:22:58 +00003036 * xmlTextWriterEndDTDElement:
3037 * @writer: the xmlTextWriterPtr
3038 *
3039 * End an xml DTD element.
3040 *
3041 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3042 */
3043int
3044xmlTextWriterEndDTDElement(xmlTextWriterPtr writer)
3045{
3046 int count;
3047 int sum;
3048 xmlLinkPtr lk;
3049 xmlTextWriterStackEntry *p;
3050
3051 if (writer == NULL)
3052 return -1;
3053
3054 sum = 0;
3055 lk = xmlListFront(writer->nodes);
3056 if (lk == 0)
3057 return -1;
3058
3059 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3060 if (p == 0)
3061 return -1;
3062
3063 switch (p->state) {
3064 case XML_TEXTWRITER_DTD_ELEM:
3065 case XML_TEXTWRITER_DTD_ELEM_TEXT:
3066 count = xmlOutputBufferWriteString(writer->out, ">");
3067 if (count < 0)
3068 return -1;
3069 sum += count;
3070 break;
3071 default:
3072 return -1;
3073 }
3074
3075 if (writer->indent) {
3076 count = xmlOutputBufferWriteString(writer->out, "\n");
3077 if (count < 0)
3078 return -1;
3079 sum += count;
3080 }
3081
3082 xmlListPopFront(writer->nodes);
3083 return sum;
3084}
3085
3086/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003087 * xmlTextWriterWriteFormatDTDElement:
3088 * @writer: the xmlTextWriterPtr
3089 * @name: the name of the DTD element
3090 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003091 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003092 *
3093 * Write a formatted DTD element.
3094 *
3095 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3096 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003097int
3098xmlTextWriterWriteFormatDTDElement(xmlTextWriterPtr writer,
3099 const xmlChar * name,
3100 const char *format, ...)
3101{
3102 int rc;
3103 va_list ap;
3104
3105 va_start(ap, format);
3106
3107 rc = xmlTextWriterWriteVFormatDTDElement(writer, name, format, ap);
3108
3109 va_end(ap);
3110 return rc;
3111}
3112
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003113/**
3114 * xmlTextWriterWriteVFormatDTDElement:
3115 * @writer: the xmlTextWriterPtr
3116 * @name: the name of the DTD element
3117 * @format: format string (see printf)
3118 * @argptr: pointer to the first member of the variable argument list.
3119 *
3120 * Write a formatted DTD element.
3121 *
3122 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3123 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003124int
3125xmlTextWriterWriteVFormatDTDElement(xmlTextWriterPtr writer,
3126 const xmlChar * name,
3127 const char *format, va_list argptr)
3128{
3129 int rc;
3130 xmlChar *buf;
3131
3132 if (writer == NULL)
3133 return -1;
3134
3135 buf = xmlTextWriterVSprintf(format, argptr);
3136 if (buf == 0)
3137 return 0;
3138
3139 rc = xmlTextWriterWriteDTDElement(writer, name, buf);
3140
3141 xmlFree(buf);
3142 return rc;
3143}
3144
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003145/**
3146 * xmlTextWriterWriteDTDElement:
3147 * @writer: the xmlTextWriterPtr
3148 * @name: the name of the DTD element
3149 * @content: content of the element
3150 *
3151 * Write a DTD element.
3152 *
3153 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3154 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003155int
3156xmlTextWriterWriteDTDElement(xmlTextWriterPtr writer,
3157 const xmlChar * name, const xmlChar * content)
3158{
3159 int count;
3160 int sum;
3161
3162 if (content == NULL)
3163 return -1;
3164
3165 sum = 0;
3166 count = xmlTextWriterStartDTDElement(writer, name);
3167 if (count == -1)
3168 return -1;
3169 sum += count;
3170
Daniel Veillard1d211e22003-10-20 22:32:39 +00003171 count = xmlTextWriterWriteString(writer, content);
3172 if (count == -1)
3173 return -1;
3174 sum += count;
3175
3176 count = xmlTextWriterEndDTDElement(writer);
3177 if (count == -1)
3178 return -1;
3179 sum += count;
3180
3181 return sum;
3182}
3183
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003184/**
3185 * xmlTextWriterStartDTDAttlist:
3186 * @writer: the xmlTextWriterPtr
3187 * @name: the name of the DTD ATTLIST
3188 *
3189 * Start an xml DTD ATTLIST.
3190 *
3191 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3192 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003193int
3194xmlTextWriterStartDTDAttlist(xmlTextWriterPtr writer, const xmlChar * name)
3195{
3196 int count;
3197 int sum;
3198 xmlLinkPtr lk;
3199 xmlTextWriterStackEntry *p;
3200
3201 if (writer == NULL || name == NULL || *name == '\0')
3202 return -1;
3203
3204 sum = 0;
3205 lk = xmlListFront(writer->nodes);
3206 if (lk == 0) {
3207 return -1;
3208 }
3209
3210 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
Daniel Veillard500a1de2004-03-22 15:22:58 +00003211 if (p != 0) {
3212 switch (p->state) {
3213 case XML_TEXTWRITER_DTD:
3214 count = xmlOutputBufferWriteString(writer->out, " [");
3215 if (count < 0)
3216 return -1;
3217 sum += count;
3218 if (writer->indent) {
3219 count = xmlOutputBufferWriteString(writer->out, "\n");
3220 if (count < 0)
3221 return -1;
3222 sum += count;
3223 }
3224 p->state = XML_TEXTWRITER_DTD_TEXT;
3225 /* fallthrough */
3226 case XML_TEXTWRITER_DTD_TEXT:
3227 case XML_TEXTWRITER_NONE:
3228 break;
3229 default:
Daniel Veillard1d211e22003-10-20 22:32:39 +00003230 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00003231 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00003232 }
3233
3234 p = (xmlTextWriterStackEntry *)
3235 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3236 if (p == 0) {
3237 xmlGenericError(xmlGenericErrorContext,
3238 "xmlTextWriterStartDTDAttlist : out of memory!\n");
3239 return -1;
3240 }
3241
3242 p->name = xmlStrdup(name);
3243 if (p->name == 0) {
3244 xmlGenericError(xmlGenericErrorContext,
3245 "xmlTextWriterStartDTDAttlist : out of memory!\n");
3246 xmlFree(p);
3247 return -1;
3248 }
3249 p->state = XML_TEXTWRITER_DTD_ATTL;
3250
3251 xmlListPushFront(writer->nodes, p);
3252
Daniel Veillard500a1de2004-03-22 15:22:58 +00003253 if (writer->indent) {
3254 count = xmlTextWriterWriteIndent(writer);
3255 if (count < 0)
3256 return -1;
3257 sum += count;
3258 }
3259
Daniel Veillard1d211e22003-10-20 22:32:39 +00003260 count = xmlOutputBufferWriteString(writer->out, "<!ATTLIST ");
3261 if (count < 0)
3262 return -1;
3263 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +00003264 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003265 if (count < 0)
3266 return -1;
3267 sum += count;
3268
3269 return sum;
3270}
3271
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003272/**
Daniel Veillard500a1de2004-03-22 15:22:58 +00003273 * xmlTextWriterEndDTDAttlist:
3274 * @writer: the xmlTextWriterPtr
3275 *
3276 * End an xml DTD attribute list.
3277 *
3278 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3279 */
3280int
3281xmlTextWriterEndDTDAttlist(xmlTextWriterPtr writer)
3282{
3283 int count;
3284 int sum;
3285 xmlLinkPtr lk;
3286 xmlTextWriterStackEntry *p;
3287
3288 if (writer == NULL)
3289 return -1;
3290
3291 sum = 0;
3292 lk = xmlListFront(writer->nodes);
3293 if (lk == 0)
3294 return -1;
3295
3296 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3297 if (p == 0)
3298 return -1;
3299
3300 switch (p->state) {
3301 case XML_TEXTWRITER_DTD_ATTL:
3302 case XML_TEXTWRITER_DTD_ATTL_TEXT:
3303 count = xmlOutputBufferWriteString(writer->out, ">");
3304 if (count < 0)
3305 return -1;
3306 sum += count;
3307 break;
3308 default:
3309 return -1;
3310 }
3311
3312 if (writer->indent) {
3313 count = xmlOutputBufferWriteString(writer->out, "\n");
3314 if (count < 0)
3315 return -1;
3316 sum += count;
3317 }
3318
3319 xmlListPopFront(writer->nodes);
3320 return sum;
3321}
3322
3323/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003324 * xmlTextWriterWriteFormatDTDAttlist:
3325 * @writer: the xmlTextWriterPtr
3326 * @name: the name of the DTD ATTLIST
3327 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003328 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003329 *
3330 * Write a formatted DTD ATTLIST.
3331 *
3332 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3333 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003334int
3335xmlTextWriterWriteFormatDTDAttlist(xmlTextWriterPtr writer,
3336 const xmlChar * name,
3337 const char *format, ...)
3338{
3339 int rc;
3340 va_list ap;
3341
3342 va_start(ap, format);
3343
3344 rc = xmlTextWriterWriteVFormatDTDAttlist(writer, name, format, ap);
3345
3346 va_end(ap);
3347 return rc;
3348}
3349
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003350/**
3351 * xmlTextWriterWriteVFormatDTDAttlist:
3352 * @writer: the xmlTextWriterPtr
3353 * @name: the name of the DTD ATTLIST
3354 * @format: format string (see printf)
3355 * @argptr: pointer to the first member of the variable argument list.
3356 *
3357 * Write a formatted DTD ATTLIST.
3358 *
3359 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3360 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003361int
3362xmlTextWriterWriteVFormatDTDAttlist(xmlTextWriterPtr writer,
3363 const xmlChar * name,
3364 const char *format, va_list argptr)
3365{
3366 int rc;
3367 xmlChar *buf;
3368
3369 if (writer == NULL)
3370 return -1;
3371
3372 buf = xmlTextWriterVSprintf(format, argptr);
3373 if (buf == 0)
3374 return 0;
3375
3376 rc = xmlTextWriterWriteDTDAttlist(writer, name, buf);
3377
3378 xmlFree(buf);
3379 return rc;
3380}
3381
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003382/**
3383 * xmlTextWriterWriteDTDAttlist:
3384 * @writer: the xmlTextWriterPtr
3385 * @name: the name of the DTD ATTLIST
3386 * @content: content of the ATTLIST
3387 *
3388 * Write a DTD ATTLIST.
3389 *
3390 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3391 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003392int
3393xmlTextWriterWriteDTDAttlist(xmlTextWriterPtr writer,
3394 const xmlChar * name, const xmlChar * content)
3395{
3396 int count;
3397 int sum;
3398
3399 if (content == NULL)
3400 return -1;
3401
3402 sum = 0;
3403 count = xmlTextWriterStartDTDAttlist(writer, name);
3404 if (count == -1)
3405 return -1;
3406 sum += count;
3407
Daniel Veillard1d211e22003-10-20 22:32:39 +00003408 count = xmlTextWriterWriteString(writer, content);
3409 if (count == -1)
3410 return -1;
3411 sum += count;
3412
3413 count = xmlTextWriterEndDTDAttlist(writer);
3414 if (count == -1)
3415 return -1;
3416 sum += count;
3417
3418 return sum;
3419}
3420
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003421/**
3422 * xmlTextWriterStartDTDEntity:
3423 * @writer: the xmlTextWriterPtr
3424 * @pe: TRUE if this is a parameter entity, FALSE if not
3425 * @name: the name of the DTD ATTLIST
3426 *
3427 * Start an xml DTD ATTLIST.
3428 *
3429 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3430 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003431int
3432xmlTextWriterStartDTDEntity(xmlTextWriterPtr writer,
3433 int pe, const xmlChar * name)
3434{
3435 int count;
3436 int sum;
3437 xmlLinkPtr lk;
3438 xmlTextWriterStackEntry *p;
3439
3440 if (writer == NULL || name == NULL || *name == '\0')
3441 return -1;
3442
3443 sum = 0;
3444 lk = xmlListFront(writer->nodes);
Daniel Veillard500a1de2004-03-22 15:22:58 +00003445 if (lk != 0) {
Daniel Veillard1d211e22003-10-20 22:32:39 +00003446
Daniel Veillard500a1de2004-03-22 15:22:58 +00003447 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3448 if (p != 0) {
3449 switch (p->state) {
3450 case XML_TEXTWRITER_DTD:
3451 count = xmlOutputBufferWriteString(writer->out, " [");
3452 if (count < 0)
3453 return -1;
3454 sum += count;
3455 if (writer->indent) {
3456 count =
3457 xmlOutputBufferWriteString(writer->out, "\n");
3458 if (count < 0)
3459 return -1;
3460 sum += count;
3461 }
3462 p->state = XML_TEXTWRITER_DTD_TEXT;
3463 /* fallthrough */
3464 case XML_TEXTWRITER_DTD_TEXT:
3465 case XML_TEXTWRITER_NONE:
3466 break;
3467 default:
3468 return -1;
3469 }
3470 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00003471 }
3472
3473 p = (xmlTextWriterStackEntry *)
3474 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3475 if (p == 0) {
3476 xmlGenericError(xmlGenericErrorContext,
3477 "xmlTextWriterStartDTDElement : out of memory!\n");
3478 return -1;
3479 }
3480
3481 p->name = xmlStrdup(name);
3482 if (p->name == 0) {
3483 xmlGenericError(xmlGenericErrorContext,
3484 "xmlTextWriterStartDTDElement : out of memory!\n");
3485 xmlFree(p);
3486 return -1;
3487 }
Daniel Veillard500a1de2004-03-22 15:22:58 +00003488
3489 if (pe != 0)
3490 p->state = XML_TEXTWRITER_DTD_PENT;
3491 else
3492 p->state = XML_TEXTWRITER_DTD_ENTY;
Daniel Veillard1d211e22003-10-20 22:32:39 +00003493
3494 xmlListPushFront(writer->nodes, p);
3495
Daniel Veillard500a1de2004-03-22 15:22:58 +00003496 if (writer->indent) {
3497 count = xmlTextWriterWriteIndent(writer);
3498 if (count < 0)
3499 return -1;
3500 sum += count;
3501 }
3502
Daniel Veillard1d211e22003-10-20 22:32:39 +00003503 count = xmlOutputBufferWriteString(writer->out, "<!ENTITY ");
3504 if (count < 0)
3505 return -1;
3506 sum += count;
3507
3508 if (pe != 0) {
Daniel Veillard500a1de2004-03-22 15:22:58 +00003509 count = xmlOutputBufferWriteString(writer->out, "% ");
Daniel Veillard1d211e22003-10-20 22:32:39 +00003510 if (count < 0)
3511 return -1;
3512 sum += count;
3513 }
3514
Daniel Veillardab69f362004-02-17 11:40:32 +00003515 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003516 if (count < 0)
3517 return -1;
3518 sum += count;
3519
3520 return sum;
3521}
3522
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003523/**
Daniel Veillard500a1de2004-03-22 15:22:58 +00003524 * xmlTextWriterEndDTDEntity:
3525 * @writer: the xmlTextWriterPtr
3526 *
3527 * End an xml DTD entity.
3528 *
3529 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3530 */
3531int
3532xmlTextWriterEndDTDEntity(xmlTextWriterPtr writer)
3533{
3534 int count;
3535 int sum;
3536 xmlLinkPtr lk;
3537 xmlTextWriterStackEntry *p;
3538
3539 if (writer == NULL)
3540 return -1;
3541
3542 sum = 0;
3543 lk = xmlListFront(writer->nodes);
3544 if (lk == 0)
3545 return -1;
3546
3547 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3548 if (p == 0)
3549 return -1;
3550
3551 switch (p->state) {
3552 case XML_TEXTWRITER_DTD_ENTY_TEXT:
3553 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3554 if (count < 0)
3555 return -1;
3556 sum += count;
3557 case XML_TEXTWRITER_DTD_ENTY:
3558 case XML_TEXTWRITER_DTD_PENT:
3559 enddtd:
3560 count = xmlOutputBufferWriteString(writer->out, ">");
3561 if (count < 0)
3562 return -1;
3563 sum += count;
3564 break;
3565 default:
3566 return -1;
3567 }
3568
3569 if (writer->indent) {
3570 count = xmlOutputBufferWriteString(writer->out, "\n");
3571 if (count < 0)
3572 return -1;
3573 sum += count;
3574 }
3575
3576 xmlListPopFront(writer->nodes);
3577 return sum;
3578}
3579
3580/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003581 * xmlTextWriterWriteFormatDTDInternalEntity:
3582 * @writer: the xmlTextWriterPtr
3583 * @pe: TRUE if this is a parameter entity, FALSE if not
3584 * @name: the name of the DTD entity
3585 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003586 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003587 *
3588 * Write a formatted DTD internal entity.
3589 *
3590 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3591 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003592int
3593xmlTextWriterWriteFormatDTDInternalEntity(xmlTextWriterPtr writer,
3594 int pe,
3595 const xmlChar * name,
3596 const char *format, ...)
3597{
3598 int rc;
3599 va_list ap;
3600
3601 va_start(ap, format);
3602
3603 rc = xmlTextWriterWriteVFormatDTDInternalEntity(writer, pe, name,
3604 format, ap);
3605
3606 va_end(ap);
3607 return rc;
3608}
3609
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003610/**
3611 * xmlTextWriterWriteVFormatDTDInternalEntity:
3612 * @writer: the xmlTextWriterPtr
3613 * @pe: TRUE if this is a parameter entity, FALSE if not
3614 * @name: the name of the DTD entity
3615 * @format: format string (see printf)
3616 * @argptr: pointer to the first member of the variable argument list.
3617 *
3618 * Write a formatted DTD internal entity.
3619 *
3620 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3621 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003622int
3623xmlTextWriterWriteVFormatDTDInternalEntity(xmlTextWriterPtr writer,
3624 int pe,
3625 const xmlChar * name,
3626 const char *format,
3627 va_list argptr)
3628{
3629 int rc;
3630 xmlChar *buf;
3631
3632 if (writer == NULL)
3633 return -1;
3634
3635 buf = xmlTextWriterVSprintf(format, argptr);
3636 if (buf == 0)
3637 return 0;
3638
3639 rc = xmlTextWriterWriteDTDInternalEntity(writer, pe, name, buf);
3640
3641 xmlFree(buf);
3642 return rc;
3643}
3644
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003645/**
3646 * xmlTextWriterWriteDTDEntity:
3647 * @writer: the xmlTextWriterPtr
3648 * @pe: TRUE if this is a parameter entity, FALSE if not
3649 * @name: the name of the DTD entity
3650 * @pubid: the public identifier, which is an alternative to the system identifier
3651 * @sysid: the system identifier, which is the URI of the DTD
3652 * @ndataid: the xml notation name.
3653 * @content: content of the entity
3654 *
3655 * Write a DTD entity.
3656 *
3657 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3658 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003659int
3660xmlTextWriterWriteDTDEntity(xmlTextWriterPtr writer,
3661 int pe,
3662 const xmlChar * name,
3663 const xmlChar * pubid,
3664 const xmlChar * sysid,
3665 const xmlChar * ndataid,
3666 const xmlChar * content)
3667{
Daniel Veillard500a1de2004-03-22 15:22:58 +00003668 if ((content == NULL) && (pubid == NULL) && (sysid == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00003669 return -1;
3670 if ((pe != 0) && (ndataid != NULL))
3671 return -1;
3672
Daniel Veillard500a1de2004-03-22 15:22:58 +00003673 if ((pubid == NULL) && (sysid == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00003674 return xmlTextWriterWriteDTDInternalEntity(writer, pe, name,
3675 content);
3676
3677 return xmlTextWriterWriteDTDExternalEntity(writer, pe, name, pubid,
3678 sysid, ndataid);
3679}
3680
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003681/**
3682 * xmlTextWriterWriteDTDInternalEntity:
3683 * @writer: the xmlTextWriterPtr
3684 * @pe: TRUE if this is a parameter entity, FALSE if not
3685 * @name: the name of the DTD entity
3686 * @content: content of the entity
3687 *
3688 * Write a DTD internal entity.
3689 *
3690 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3691 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003692int
3693xmlTextWriterWriteDTDInternalEntity(xmlTextWriterPtr writer,
3694 int pe,
3695 const xmlChar * name,
3696 const xmlChar * content)
3697{
3698 int count;
3699 int sum;
3700
3701 if ((name == NULL) || (*name == '\0') || (content == NULL))
3702 return -1;
3703
3704 sum = 0;
3705 count = xmlTextWriterStartDTDEntity(writer, pe, name);
3706 if (count == -1)
3707 return -1;
3708 sum += count;
3709
Daniel Veillard1d211e22003-10-20 22:32:39 +00003710 count = xmlTextWriterWriteString(writer, content);
3711 if (count == -1)
3712 return -1;
3713 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00003714
3715 count = xmlTextWriterEndDTDEntity(writer);
3716 if (count == -1)
3717 return -1;
3718 sum += count;
3719
3720 return sum;
3721}
3722
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003723/**
3724 * xmlTextWriterWriteDTDExternalEntity:
3725 * @writer: the xmlTextWriterPtr
3726 * @pe: TRUE if this is a parameter entity, FALSE if not
3727 * @name: the name of the DTD entity
3728 * @pubid: the public identifier, which is an alternative to the system identifier
3729 * @sysid: the system identifier, which is the URI of the DTD
3730 * @ndataid: the xml notation name.
3731 *
Daniel Veillard500a1de2004-03-22 15:22:58 +00003732 * Write a DTD external entity. The entity must have been started with xmlTextWriterStartDTDEntity
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003733 *
3734 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3735 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003736int
3737xmlTextWriterWriteDTDExternalEntity(xmlTextWriterPtr writer,
3738 int pe,
3739 const xmlChar * name,
3740 const xmlChar * pubid,
3741 const xmlChar * sysid,
3742 const xmlChar * ndataid)
3743{
3744 int count;
3745 int sum;
3746
Daniel Veillard500a1de2004-03-22 15:22:58 +00003747 if (((pubid == NULL) && (sysid == NULL)))
Daniel Veillard1d211e22003-10-20 22:32:39 +00003748 return -1;
3749 if ((pe != 0) && (ndataid != NULL))
3750 return -1;
3751
3752 sum = 0;
3753 count = xmlTextWriterStartDTDEntity(writer, pe, name);
3754 if (count == -1)
3755 return -1;
3756 sum += count;
3757
Daniel Veillard500a1de2004-03-22 15:22:58 +00003758 count =
3759 xmlTextWriterWriteDTDExternalEntityContents(writer, pubid, sysid,
3760 ndataid);
3761 if (count < 0)
3762 return -1;
3763 sum += count;
3764
3765 count = xmlTextWriterEndDTDEntity(writer);
3766 if (count == -1)
3767 return -1;
3768 sum += count;
3769
3770 return sum;
3771}
3772
3773/**
3774 * xmlTextWriterWriteDTDExternalEntityContents:
3775 * @writer: the xmlTextWriterPtr
3776 * @pubid: the public identifier, which is an alternative to the system identifier
3777 * @sysid: the system identifier, which is the URI of the DTD
3778 * @ndataid: the xml notation name.
3779 *
3780 * Write the contents of a DTD external entity.
3781 *
3782 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3783 */
3784int
3785xmlTextWriterWriteDTDExternalEntityContents(xmlTextWriterPtr writer,
3786 const xmlChar * pubid,
3787 const xmlChar * sysid,
3788 const xmlChar * ndataid)
3789{
3790 int count;
3791 int sum;
3792 xmlLinkPtr lk;
3793 xmlTextWriterStackEntry *p;
3794
3795 if (writer == NULL) {
3796 xmlGenericError(xmlGenericErrorContext,
3797 "xmlTextWriterWriteDTDExternalEntityContents: xmlTextWriterPtr invalid!\n");
3798 return -1;
3799 }
3800
3801 sum = 0;
3802 lk = xmlListFront(writer->nodes);
3803 if (lk == 0) {
3804 xmlGenericError(xmlGenericErrorContext,
3805 "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n");
3806 return -1;
3807 }
3808
3809 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3810 if (p == 0)
3811 return -1;
3812
3813 switch (p->state) {
3814 case XML_TEXTWRITER_DTD_ENTY:
3815 break;
3816 case XML_TEXTWRITER_DTD_PENT:
3817 if (ndataid != NULL) {
3818 xmlGenericError(xmlGenericErrorContext,
3819 "xmlTextWriterWriteDTDExternalEntityContents: notation not allowed with parameter entities!\n");
3820 return -1;
3821 }
3822 break;
3823 default:
3824 xmlGenericError(xmlGenericErrorContext,
3825 "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n");
3826 return -1;
3827 }
3828
Daniel Veillard1d211e22003-10-20 22:32:39 +00003829 if (pubid != 0) {
3830 if (sysid == 0) {
3831 xmlGenericError(xmlGenericErrorContext,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003832 "xmlTextWriterWriteDTDExternalEntityContents: system identifier needed!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +00003833 return -1;
3834 }
3835
3836 count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
3837 if (count < 0)
3838 return -1;
3839 sum += count;
3840
3841 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3842 if (count < 0)
3843 return -1;
3844 sum += count;
3845
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003846 count =
3847 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003848 if (count < 0)
3849 return -1;
3850 sum += count;
3851
3852 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3853 if (count < 0)
3854 return -1;
3855 sum += count;
3856 }
3857
3858 if (sysid != 0) {
3859 if (pubid == 0) {
3860 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
3861 if (count < 0)
3862 return -1;
3863 sum += count;
3864 }
3865
3866 count = xmlOutputBufferWriteString(writer->out, " ");
3867 if (count < 0)
3868 return -1;
3869 sum += count;
3870
3871 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3872 if (count < 0)
3873 return -1;
3874 sum += count;
3875
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003876 count =
3877 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003878 if (count < 0)
3879 return -1;
3880 sum += count;
3881
3882 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3883 if (count < 0)
3884 return -1;
3885 sum += count;
3886 }
3887
3888 if (ndataid != NULL) {
3889 count = xmlOutputBufferWriteString(writer->out, " NDATA ");
3890 if (count < 0)
3891 return -1;
3892 sum += count;
3893
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003894 count =
3895 xmlOutputBufferWriteString(writer->out,
3896 (const char *) ndataid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003897 if (count < 0)
3898 return -1;
3899 sum += count;
3900 }
3901
Daniel Veillard1d211e22003-10-20 22:32:39 +00003902 return sum;
3903}
3904
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003905/**
3906 * xmlTextWriterWriteDTDNotation:
3907 * @writer: the xmlTextWriterPtr
3908 * @name: the name of the xml notation
3909 * @pubid: the public identifier, which is an alternative to the system identifier
3910 * @sysid: the system identifier, which is the URI of the DTD
3911 *
3912 * Write a DTD entity.
3913 *
3914 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3915 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003916int
3917xmlTextWriterWriteDTDNotation(xmlTextWriterPtr writer,
3918 const xmlChar * name,
3919 const xmlChar * pubid, const xmlChar * sysid)
3920{
3921 int count;
3922 int sum;
3923 xmlLinkPtr lk;
3924 xmlTextWriterStackEntry *p;
3925
3926 if (writer == NULL || name == NULL || *name == '\0')
3927 return -1;
3928
3929 sum = 0;
3930 lk = xmlListFront(writer->nodes);
3931 if (lk == 0) {
3932 return -1;
3933 }
3934
3935 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
Daniel Veillard500a1de2004-03-22 15:22:58 +00003936 if (p != 0) {
3937 switch (p->state) {
3938 case XML_TEXTWRITER_DTD:
3939 count = xmlOutputBufferWriteString(writer->out, " [");
3940 if (count < 0)
3941 return -1;
3942 sum += count;
3943 if (writer->indent) {
3944 count = xmlOutputBufferWriteString(writer->out, "\n");
3945 if (count < 0)
3946 return -1;
3947 sum += count;
3948 }
3949 p->state = XML_TEXTWRITER_DTD_TEXT;
3950 /* fallthrough */
3951 case XML_TEXTWRITER_DTD_TEXT:
3952 break;
3953 default:
3954 return -1;
3955 }
3956 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00003957
Daniel Veillard500a1de2004-03-22 15:22:58 +00003958 if (writer->indent) {
3959 count = xmlTextWriterWriteIndent(writer);
3960 if (count < 0)
Daniel Veillard1d211e22003-10-20 22:32:39 +00003961 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00003962 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00003963 }
3964
3965 count = xmlOutputBufferWriteString(writer->out, "<!NOTATION ");
3966 if (count < 0)
3967 return -1;
3968 sum += count;
3969 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
3970 if (count < 0)
3971 return -1;
3972 sum += count;
3973
3974 if (pubid != 0) {
3975 count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
3976 if (count < 0)
3977 return -1;
3978 sum += count;
3979 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3980 if (count < 0)
3981 return -1;
3982 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003983 count =
3984 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003985 if (count < 0)
3986 return -1;
3987 sum += count;
3988 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3989 if (count < 0)
3990 return -1;
3991 sum += count;
3992 }
3993
3994 if (sysid != 0) {
3995 if (pubid == 0) {
3996 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
3997 if (count < 0)
3998 return -1;
3999 sum += count;
4000 }
4001 count = xmlOutputBufferWriteString(writer->out, " ");
4002 if (count < 0)
4003 return -1;
4004 sum += count;
4005 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4006 if (count < 0)
4007 return -1;
4008 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004009 count =
4010 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004011 if (count < 0)
4012 return -1;
4013 sum += count;
4014 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4015 if (count < 0)
4016 return -1;
4017 sum += count;
4018 }
4019
4020 count = xmlOutputBufferWriteString(writer->out, ">");
4021 if (count < 0)
4022 return -1;
4023 sum += count;
4024
4025 return sum;
4026}
4027
4028/**
4029 * xmlTextWriterFlush:
4030 * @writer: the xmlTextWriterPtr
4031 *
4032 * Flush the output buffer.
4033 *
4034 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
4035 */
4036int
4037xmlTextWriterFlush(xmlTextWriterPtr writer)
4038{
4039 int count;
4040
4041 if (writer == NULL)
4042 return -1;
4043
4044 if (writer->out == NULL)
4045 count = 0;
4046 else
4047 count = xmlOutputBufferFlush(writer->out);
4048
4049 return count;
4050}
4051
4052/**
4053 * misc
4054 */
4055
4056/**
4057 * xmlFreeTextWriterStackEntry:
4058 * @lk: the xmlLinkPtr
4059 *
4060 * Free callback for the xmlList.
4061 */
4062static void
4063xmlFreeTextWriterStackEntry(xmlLinkPtr lk)
4064{
4065 xmlTextWriterStackEntry *p;
4066
4067 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
4068 if (p == 0)
4069 return;
4070
4071 if (p->name != 0)
4072 xmlFree(p->name);
4073 xmlFree(p);
4074}
4075
4076/**
4077 * xmlCmpTextWriterStackEntry:
4078 * @data0: the first data
4079 * @data1: the second data
4080 *
4081 * Compare callback for the xmlList.
4082 *
4083 * Returns -1, 0, 1
4084 */
4085static int
4086xmlCmpTextWriterStackEntry(const void *data0, const void *data1)
4087{
4088 xmlTextWriterStackEntry *p0;
4089 xmlTextWriterStackEntry *p1;
4090
4091 if (data0 == data1)
4092 return 0;
4093
4094 if (data0 == 0)
4095 return -1;
4096
4097 if (data1 == 0)
4098 return 1;
4099
4100 p0 = (xmlTextWriterStackEntry *) data0;
4101 p1 = (xmlTextWriterStackEntry *) data1;
4102
4103 return xmlStrcmp(p0->name, p1->name);
4104}
4105
4106/**
4107 * misc
4108 */
4109
4110/**
4111 * xmlFreeTextWriterNsStackEntry:
4112 * @lk: the xmlLinkPtr
4113 *
4114 * Free callback for the xmlList.
4115 */
4116static void
4117xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk)
4118{
4119 xmlTextWriterNsStackEntry *p;
4120
4121 p = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
4122 if (p == 0)
4123 return;
4124
4125 if (p->prefix != 0)
4126 xmlFree(p->prefix);
4127 if (p->uri != 0)
4128 xmlFree(p->uri);
4129
4130 xmlFree(p);
4131}
4132
4133/**
4134 * xmlCmpTextWriterNsStackEntry:
4135 * @data0: the first data
4136 * @data1: the second data
4137 *
4138 * Compare callback for the xmlList.
4139 *
4140 * Returns -1, 0, 1
4141 */
4142static int
4143xmlCmpTextWriterNsStackEntry(const void *data0, const void *data1)
4144{
4145 xmlTextWriterNsStackEntry *p0;
4146 xmlTextWriterNsStackEntry *p1;
4147 int rc;
4148
4149 if (data0 == data1)
4150 return 0;
4151
4152 if (data0 == 0)
4153 return -1;
4154
4155 if (data1 == 0)
4156 return 1;
4157
4158 p0 = (xmlTextWriterNsStackEntry *) data0;
4159 p1 = (xmlTextWriterNsStackEntry *) data1;
4160
4161 rc = xmlStrcmp(p0->prefix, p1->prefix);
4162
4163 if (rc == 0)
4164 rc = p0->elem == p1->elem;
4165
4166 return rc;
4167}
4168
4169/**
4170 * xmlTextWriterWriteMemCallback:
4171 * @context: the xmlBufferPtr
4172 * @str: the data to write
4173 * @len: the length of the data
4174 *
4175 * Write callback for the xmlOutputBuffer with target xmlBuffer
4176 *
4177 * Returns -1, 0, 1
4178 */
4179static int
4180xmlTextWriterWriteMemCallback(void *context, const xmlChar * str, int len)
4181{
4182 xmlBufferPtr buf = (xmlBufferPtr) context;
4183
4184 xmlBufferAdd(buf, str, len);
4185
4186 return len;
4187}
4188
4189/**
4190 * xmlTextWriterCloseMemCallback:
4191 * @context: the xmlBufferPtr
4192 *
4193 * Close callback for the xmlOutputBuffer with target xmlBuffer
4194 *
4195 * Returns -1, 0, 1
4196 */
4197static int
4198xmlTextWriterCloseMemCallback(void *context ATTRIBUTE_UNUSED)
4199{
4200 return 0;
4201}
4202
4203/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004204 * xmlTextWriterWriteDocCallback:
4205 * @context: the xmlBufferPtr
4206 * @str: the data to write
4207 * @len: the length of the data
4208 *
4209 * Write callback for the xmlOutputBuffer with target xmlBuffer
4210 *
4211 * Returns -1, 0, 1
4212 */
4213static int
4214xmlTextWriterWriteDocCallback(void *context, const xmlChar * str, int len)
4215{
4216 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context;
4217 int rc;
4218
Daniel Veillard1d913862003-11-21 00:28:39 +00004219 if ((rc = xmlParseChunk(ctxt, (const char *) str, len, 0)) != 0) {
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004220 xmlGenericError(xmlGenericErrorContext,
4221 "xmlTextWriterWriteDocCallback : XML error %d !\n",
4222 rc);
4223 return -1;
4224 }
4225
4226 return len;
4227}
4228
4229/**
4230 * xmlTextWriterCloseDocCallback:
4231 * @context: the xmlBufferPtr
4232 *
4233 * Close callback for the xmlOutputBuffer with target xmlBuffer
4234 *
4235 * Returns -1, 0, 1
4236 */
4237static int
4238xmlTextWriterCloseDocCallback(void *context)
4239{
4240 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context;
4241 int rc;
4242
4243 if ((rc = xmlParseChunk(ctxt, NULL, 0, 1)) != 0) {
4244 xmlGenericError(xmlGenericErrorContext,
4245 "xmlTextWriterWriteDocCallback : XML error %d !\n",
4246 rc);
4247 return -1;
4248 }
4249
4250 return 0;
4251}
4252
4253/**
Daniel Veillard1d211e22003-10-20 22:32:39 +00004254 * xmlTextWriterVSprintf:
4255 * @format: see printf
4256 * @argptr: pointer to the first member of the variable argument list.
4257 *
4258 * Utility function for formatted output
4259 *
4260 * Returns a new xmlChar buffer with the data or NULL on error. This buffer must be freed.
4261 */
4262static xmlChar *
4263xmlTextWriterVSprintf(const char *format, va_list argptr)
4264{
4265 int size;
4266 int count;
4267 xmlChar *buf;
4268
4269 size = BUFSIZ;
4270 buf = (xmlChar *) xmlMalloc(size);
4271 if (buf == NULL) {
4272 xmlGenericError(xmlGenericErrorContext,
4273 "xmlTextWriterVSprintf : out of memory!\n");
4274 return NULL;
4275 }
4276
4277 while (((count = vsnprintf((char *) buf, size, format, argptr)) < 0)
4278 || (count == size - 1) || (count == size) || (count > size)) {
4279 xmlFree(buf);
4280 size += BUFSIZ;
4281 buf = (xmlChar *) xmlMalloc(size);
4282 if (buf == NULL) {
4283 xmlGenericError(xmlGenericErrorContext,
4284 "xmlTextWriterVSprintf : out of memory!\n");
4285 return NULL;
4286 }
4287 }
4288
4289 return buf;
4290}
4291
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004292/**
4293 * xmlTextWriterStartDocumentCallback:
4294 * @ctx: the user data (XML parser context)
4295 *
4296 * called at the start of document processing.
4297 */
4298static void
4299xmlTextWriterStartDocumentCallback(void *ctx)
4300{
4301 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
4302 xmlDocPtr doc;
4303
4304#ifdef DEBUG_SAX
4305 xmlGenericError(xmlGenericErrorContext, "SAX.startDocument()\n");
4306#endif
4307 if (ctxt->html) {
4308#ifdef LIBXML_HTML_ENABLED
4309 if (ctxt->myDoc == NULL)
4310 ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
4311 if (ctxt->myDoc == NULL) {
4312 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
4313 ctxt->sax->error(ctxt->userData,
4314 "SAX.startDocument(): out of memory\n");
4315 ctxt->errNo = XML_ERR_NO_MEMORY;
4316 ctxt->instate = XML_PARSER_EOF;
4317 ctxt->disableSAX = 1;
4318 return;
4319 }
4320#else
4321 xmlGenericError(xmlGenericErrorContext,
4322 "libxml2 built without HTML support\n");
4323 ctxt->errNo = XML_ERR_INTERNAL_ERROR;
4324 ctxt->instate = XML_PARSER_EOF;
4325 ctxt->disableSAX = 1;
4326 return;
4327#endif
4328 } else {
4329 doc = ctxt->myDoc;
4330 if (doc == NULL)
4331 doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
4332 if (doc != NULL) {
4333 if (doc->children == NULL) {
4334 if (ctxt->encoding != NULL)
4335 doc->encoding = xmlStrdup(ctxt->encoding);
4336 else
4337 doc->encoding = NULL;
4338 doc->standalone = ctxt->standalone;
4339 }
4340 } else {
4341 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
4342 ctxt->sax->error(ctxt->userData,
4343 "SAX.startDocument(): out of memory\n");
4344 ctxt->errNo = XML_ERR_NO_MEMORY;
4345 ctxt->instate = XML_PARSER_EOF;
4346 ctxt->disableSAX = 1;
4347 return;
4348 }
4349 }
4350 if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) &&
4351 (ctxt->input != NULL) && (ctxt->input->filename != NULL)) {
4352 ctxt->myDoc->URL =
4353 xmlCanonicPath((const xmlChar *) ctxt->input->filename);
4354 if (ctxt->myDoc->URL == NULL)
4355 ctxt->myDoc->URL =
4356 xmlStrdup((const xmlChar *) ctxt->input->filename);
4357 }
4358}
4359
Daniel Veillard2cca4462004-01-02 20:04:23 +00004360/**
4361 * xmlTextWriterSetIndent:
4362 * @writer: the xmlTextWriterPtr
4363 * @indent: do indentation?
4364 *
4365 * Set indentation output. indent = 0 do not indentation. indent > 0 do indentation.
4366 *
4367 * Returns -1 on error or 0 otherwise.
4368 */
4369int
Daniel Veillardab69f362004-02-17 11:40:32 +00004370xmlTextWriterSetIndent(xmlTextWriterPtr writer, int indent)
Daniel Veillard2cca4462004-01-02 20:04:23 +00004371{
Daniel Veillardab69f362004-02-17 11:40:32 +00004372 if (indent < 0)
4373 return -1;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004374
Daniel Veillardab69f362004-02-17 11:40:32 +00004375 writer->indent = indent;
4376 writer->doindent = 1;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004377
Daniel Veillardab69f362004-02-17 11:40:32 +00004378 return 0;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004379}
4380
4381/**
4382 * xmlTextWriterSetIndentString:
4383 * @writer: the xmlTextWriterPtr
4384 * @str: the xmlChar string
4385 *
4386 * Set string indentation.
4387 *
4388 * Returns -1 on error or 0 otherwise.
4389 */
4390int
Daniel Veillardab69f362004-02-17 11:40:32 +00004391xmlTextWriterSetIndentString(xmlTextWriterPtr writer, const xmlChar * str)
Daniel Veillard2cca4462004-01-02 20:04:23 +00004392{
Daniel Veillardab69f362004-02-17 11:40:32 +00004393 if (!str)
4394 return -1;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004395
Daniel Veillardab69f362004-02-17 11:40:32 +00004396 if (writer->ichar != NULL)
4397 xmlFree(writer->ichar);
4398 writer->ichar = xmlStrdup(str);
4399
4400 if (!writer->ichar)
4401 return -1;
4402 else
4403 return 0;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004404}
4405
4406/**
4407 * xmlTextWriterWriteIndent:
4408 * @writer: the xmlTextWriterPtr
4409 *
4410 * Write indent string.
4411 *
4412 * Returns -1 on error or the number of strings written.
Daniel Veillardab69f362004-02-17 11:40:32 +00004413 */
Daniel Veillard2cca4462004-01-02 20:04:23 +00004414static int
Daniel Veillardab69f362004-02-17 11:40:32 +00004415xmlTextWriterWriteIndent(xmlTextWriterPtr writer)
Daniel Veillard2cca4462004-01-02 20:04:23 +00004416{
Daniel Veillardab69f362004-02-17 11:40:32 +00004417 int lksize;
4418 int i;
4419 int ret;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004420
Daniel Veillardab69f362004-02-17 11:40:32 +00004421 lksize = xmlListSize(writer->nodes);
4422 if (lksize < 1)
4423 return (-1); /* list is empty */
4424 for (i = 0; i < (lksize - 1); i++) {
4425 ret = xmlOutputBufferWriteString(writer->out,
4426 (const char *) writer->ichar);
4427 if (ret == -1)
4428 return (-1);
4429 }
4430
4431 return (lksize - 1);
Daniel Veillard2cca4462004-01-02 20:04:23 +00004432}
4433
Daniel Veillard500a1de2004-03-22 15:22:58 +00004434/**
4435 * xmlTextWriterHandleStateDependencies:
4436 * @writer: the xmlTextWriterPtr
4437 * @p: the xmlTextWriterStackEntry
4438 *
4439 * Write state dependent strings.
4440 *
4441 * Returns -1 on error or the number of characters written.
4442 */
4443static int
4444xmlTextWriterHandleStateDependencies(xmlTextWriterPtr writer,
4445 xmlTextWriterStackEntry * p)
4446{
4447 int count;
4448 int sum;
4449 char extra[3];
4450
4451 if (writer == NULL)
4452 return -1;
4453
4454 if (p == NULL)
4455 return 0;
4456
4457 sum = 0;
4458 extra[0] = extra[1] = extra[2] = '\0';
4459 if (p != 0) {
4460 sum = 0;
4461 switch (p->state) {
4462 case XML_TEXTWRITER_NAME:
4463 extra[0] = '>';
4464 p->state = XML_TEXTWRITER_TEXT;
4465 break;
4466 case XML_TEXTWRITER_PI:
4467 extra[0] = ' ';
4468 p->state = XML_TEXTWRITER_PI_TEXT;
4469 break;
4470 case XML_TEXTWRITER_DTD:
4471 extra[0] = ' ';
4472 extra[1] = '[';
4473 p->state = XML_TEXTWRITER_DTD_TEXT;
4474 break;
4475 case XML_TEXTWRITER_DTD_ELEM:
4476 extra[0] = ' ';
4477 p->state = XML_TEXTWRITER_DTD_ELEM_TEXT;
4478 break;
4479 case XML_TEXTWRITER_DTD_ATTL:
4480 extra[0] = ' ';
4481 p->state = XML_TEXTWRITER_DTD_ATTL_TEXT;
4482 break;
4483 case XML_TEXTWRITER_DTD_ENTY:
4484 case XML_TEXTWRITER_DTD_PENT:
4485 extra[0] = ' ';
4486 extra[1] = writer->qchar;
4487 p->state = XML_TEXTWRITER_DTD_ENTY_TEXT;
4488 break;
4489 default:
4490 break;
4491 }
4492 }
4493
4494 if (*extra != '\0') {
4495 count = xmlOutputBufferWriteString(writer->out, extra);
4496 if (count < 0)
4497 return -1;
4498 sum += count;
4499 }
4500
4501 return sum;
4502}
4503
Daniel Veillard1d211e22003-10-20 22:32:39 +00004504#endif