blob: 25e45fa7af2b917d9a9a7745a52c7368aa118964 [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/*
William M. Brackf4caa5e2005-10-20 09:04:05 +000028 * The following VA_COPY was coded following an example in
29 * the Samba project. It may not be sufficient for some
30 * esoteric implementations of va_list (i.e. it may need
31 * something involving a memcpy) but (hopefully) will be
32 * sufficient for libxml2.
33 */
34#ifndef VA_COPY
35 #ifdef HAVE_VA_COPY
36 #define VA_COPY(dest, src) va_copy(dest, src)
37 #else
38 #ifdef HAVE___VA_COPY
39 #define VA_COPY(dest,src) __va_copy(dest, src)
40 #else
41 #define VA_COPY(dest,src) (dest) = (src)
42 #endif
43 #endif
44#endif
45
46/*
Daniel Veillard1d211e22003-10-20 22:32:39 +000047 * Types are kept private
48 */
49typedef enum {
50 XML_TEXTWRITER_NONE = 0,
51 XML_TEXTWRITER_NAME,
52 XML_TEXTWRITER_ATTRIBUTE,
53 XML_TEXTWRITER_TEXT,
54 XML_TEXTWRITER_PI,
55 XML_TEXTWRITER_PI_TEXT,
56 XML_TEXTWRITER_CDATA,
57 XML_TEXTWRITER_DTD,
58 XML_TEXTWRITER_DTD_TEXT,
59 XML_TEXTWRITER_DTD_ELEM,
Daniel Veillard500a1de2004-03-22 15:22:58 +000060 XML_TEXTWRITER_DTD_ELEM_TEXT,
Daniel Veillard1d211e22003-10-20 22:32:39 +000061 XML_TEXTWRITER_DTD_ATTL,
Daniel Veillard500a1de2004-03-22 15:22:58 +000062 XML_TEXTWRITER_DTD_ATTL_TEXT,
63 XML_TEXTWRITER_DTD_ENTY, /* entity */
64 XML_TEXTWRITER_DTD_ENTY_TEXT,
65 XML_TEXTWRITER_DTD_PENT, /* parameter entity */
William M. Brack87640d52004-04-17 14:58:15 +000066 XML_TEXTWRITER_COMMENT
Daniel Veillard1d211e22003-10-20 22:32:39 +000067} xmlTextWriterState;
68
69typedef struct _xmlTextWriterStackEntry xmlTextWriterStackEntry;
70
71struct _xmlTextWriterStackEntry {
72 xmlChar *name;
73 xmlTextWriterState state;
74};
75
76typedef struct _xmlTextWriterNsStackEntry xmlTextWriterNsStackEntry;
77struct _xmlTextWriterNsStackEntry {
78 xmlChar *prefix;
79 xmlChar *uri;
80 xmlLinkPtr elem;
81};
82
83struct _xmlTextWriter {
Daniel Veillardab69f362004-02-17 11:40:32 +000084 xmlOutputBufferPtr out; /* output buffer */
85 xmlListPtr nodes; /* element name stack */
86 xmlListPtr nsstack; /* name spaces stack */
Daniel Veillard1d211e22003-10-20 22:32:39 +000087 int level;
Daniel Veillardab69f362004-02-17 11:40:32 +000088 int indent; /* enable indent */
89 int doindent; /* internal indent flag */
90 xmlChar *ichar; /* indent character */
91 char qchar; /* character used for quoting attribute values */
Daniel Veillard20c5e782004-01-21 09:57:31 +000092 xmlParserCtxtPtr ctxt;
Daniel Veillarda521d282004-11-09 14:59:59 +000093 int no_doc_free;
Daniel Veillard1d211e22003-10-20 22:32:39 +000094};
95
96static void xmlFreeTextWriterStackEntry(xmlLinkPtr lk);
97static int xmlCmpTextWriterStackEntry(const void *data0,
98 const void *data1);
99static void xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk);
100static int xmlCmpTextWriterNsStackEntry(const void *data0,
101 const void *data1);
102static int xmlTextWriterWriteMemCallback(void *context,
103 const xmlChar * str, int len);
104static int xmlTextWriterCloseMemCallback(void *context);
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000105static int xmlTextWriterWriteDocCallback(void *context,
106 const xmlChar * str, int len);
107static int xmlTextWriterCloseDocCallback(void *context);
108
Daniel Veillard1d211e22003-10-20 22:32:39 +0000109static xmlChar *xmlTextWriterVSprintf(const char *format, va_list argptr);
110static int xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len,
111 const unsigned char *data);
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000112static void xmlTextWriterStartDocumentCallback(void *ctx);
Daniel Veillardab69f362004-02-17 11:40:32 +0000113static int xmlTextWriterWriteIndent(xmlTextWriterPtr writer);
Daniel Veillard500a1de2004-03-22 15:22:58 +0000114static int
115 xmlTextWriterHandleStateDependencies(xmlTextWriterPtr writer,
116 xmlTextWriterStackEntry * p);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000117
118/**
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000119 * xmlWriterErrMsg:
120 * @ctxt: a writer context
121 * @error: the error number
122 * @msg: the error message
123 *
124 * Handle a writer error
125 */
126static void
127xmlWriterErrMsg(xmlTextWriterPtr ctxt, xmlParserErrors error,
128 const char *msg)
129{
130 if (ctxt != NULL) {
131 __xmlRaiseError(NULL, NULL, NULL, ctxt->ctxt,
132 NULL, XML_FROM_WRITER, error, XML_ERR_FATAL,
133 NULL, 0, NULL, NULL, NULL, 0, 0, msg);
134 } else {
135 __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_WRITER, error,
136 XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, 0, 0, msg);
137 }
138}
139
140/**
141 * xmlWriterErrMsgInt:
142 * @ctxt: a writer context
143 * @error: the error number
144 * @msg: the error message
145 * @val: an int
146 *
147 * Handle a writer error
148 */
149static void
150xmlWriterErrMsgInt(xmlTextWriterPtr ctxt, xmlParserErrors error,
151 const char *msg, int val)
152{
153 if (ctxt != NULL) {
154 __xmlRaiseError(NULL, NULL, NULL, ctxt->ctxt,
155 NULL, XML_FROM_WRITER, error, XML_ERR_FATAL,
156 NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
157 } else {
158 __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_WRITER, error,
159 XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
160 }
161}
162
163/**
Daniel Veillard1d211e22003-10-20 22:32:39 +0000164 * xmlNewTextWriter:
165 * @out: an xmlOutputBufferPtr
166 *
167 * Create a new xmlNewTextWriter structure using an xmlOutputBufferPtr
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000168 * NOTE: the @out parameter will be deallocated when the writer is closed
169 * (if the call succeed.)
Daniel Veillard1d211e22003-10-20 22:32:39 +0000170 *
171 * Returns the new xmlTextWriterPtr or NULL in case of error
172 */
173xmlTextWriterPtr
174xmlNewTextWriter(xmlOutputBufferPtr out)
175{
176 xmlTextWriterPtr ret;
177
178 ret = (xmlTextWriterPtr) xmlMalloc(sizeof(xmlTextWriter));
179 if (ret == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000180 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000181 "xmlNewTextWriter : out of memory!\n");
182 return NULL;
183 }
184 memset(ret, 0, (size_t) sizeof(xmlTextWriter));
185
186 ret->nodes = xmlListCreate((xmlListDeallocator)
187 xmlFreeTextWriterStackEntry,
188 (xmlListDataCompare)
189 xmlCmpTextWriterStackEntry);
190 if (ret->nodes == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000191 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000192 "xmlNewTextWriter : out of memory!\n");
193 xmlFree(ret);
194 return NULL;
195 }
196
197 ret->nsstack = xmlListCreate((xmlListDeallocator)
198 xmlFreeTextWriterNsStackEntry,
199 (xmlListDataCompare)
200 xmlCmpTextWriterNsStackEntry);
201 if (ret->nsstack == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000202 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000203 "xmlNewTextWriter : out of memory!\n");
Daniel Veillard500a1de2004-03-22 15:22:58 +0000204 xmlListDelete(ret->nodes);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000205 xmlFree(ret);
206 return NULL;
207 }
208
209 ret->out = out;
Daniel Veillardab69f362004-02-17 11:40:32 +0000210 ret->ichar = xmlStrdup(BAD_CAST " ");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000211 ret->qchar = '"';
212
Daniel Veillard500a1de2004-03-22 15:22:58 +0000213 if (!ret->ichar) {
214 xmlListDelete(ret->nodes);
215 xmlListDelete(ret->nsstack);
216 xmlFree(ret);
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000217 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000218 "xmlNewTextWriter : out of memory!\n");
Daniel Veillardab69f362004-02-17 11:40:32 +0000219 return NULL;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000220 }
Daniel Veillarda521d282004-11-09 14:59:59 +0000221 ret->no_doc_free = 0;
Daniel Veillardab69f362004-02-17 11:40:32 +0000222
Daniel Veillard1d211e22003-10-20 22:32:39 +0000223 return ret;
224}
225
226/**
227 * xmlNewTextWriterFilename:
228 * @uri: the URI of the resource for the output
229 * @compression: compress the output?
230 *
231 * Create a new xmlNewTextWriter structure with @uri as output
232 *
233 * Returns the new xmlTextWriterPtr or NULL in case of error
234 */
235xmlTextWriterPtr
236xmlNewTextWriterFilename(const char *uri, int compression)
237{
238 xmlTextWriterPtr ret;
239 xmlOutputBufferPtr out;
240
241 out = xmlOutputBufferCreateFilename(uri, NULL, compression);
242 if (out == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000243 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000244 "xmlNewTextWriterFilename : out of memory!\n");
245 return NULL;
246 }
247
248 ret = xmlNewTextWriter(out);
249 if (ret == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000250 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000251 "xmlNewTextWriterFilename : out of memory!\n");
252 xmlOutputBufferClose(out);
253 return NULL;
254 }
255
Daniel Veillard2cca4462004-01-02 20:04:23 +0000256 ret->indent = 0;
257 ret->doindent = 0;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000258 return ret;
259}
260
261/**
262 * xmlNewTextWriterMemory:
263 * @buf: xmlBufferPtr
264 * @compression: compress the output?
265 *
266 * Create a new xmlNewTextWriter structure with @buf as output
267 * TODO: handle compression
268 *
269 * Returns the new xmlTextWriterPtr or NULL in case of error
270 */
271xmlTextWriterPtr
272xmlNewTextWriterMemory(xmlBufferPtr buf, int compression ATTRIBUTE_UNUSED)
273{
274 xmlTextWriterPtr ret;
275 xmlOutputBufferPtr out;
276
277/*::todo handle compression */
278 out = xmlOutputBufferCreateIO((xmlOutputWriteCallback)
279 xmlTextWriterWriteMemCallback,
280 (xmlOutputCloseCallback)
281 xmlTextWriterCloseMemCallback,
282 (void *) buf, NULL);
283 if (out == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000284 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000285 "xmlNewTextWriterMemory : out of memory!\n");
286 return NULL;
287 }
288
289 ret = xmlNewTextWriter(out);
290 if (ret == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000291 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000292 "xmlNewTextWriterMemory : out of memory!\n");
293 xmlOutputBufferClose(out);
294 return NULL;
295 }
296
297 return ret;
298}
299
300/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000301 * xmlNewTextWriterPushParser:
302 * @ctxt: xmlParserCtxtPtr to hold the new XML document tree
303 * @compression: compress the output?
304 *
305 * Create a new xmlNewTextWriter structure with @ctxt as output
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000306 * NOTE: the @ctxt context will be freed with the resulting writer
307 * (if the call succeeds).
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000308 * TODO: handle compression
309 *
310 * Returns the new xmlTextWriterPtr or NULL in case of error
311 */
312xmlTextWriterPtr
Daniel Veillard1d913862003-11-21 00:28:39 +0000313xmlNewTextWriterPushParser(xmlParserCtxtPtr ctxt,
314 int compression ATTRIBUTE_UNUSED)
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000315{
316 xmlTextWriterPtr ret;
317 xmlOutputBufferPtr out;
318
Daniel Veillard500a1de2004-03-22 15:22:58 +0000319 if (ctxt == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000320 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000321 "xmlNewTextWriterPushParser : invalid context!\n");
322 return NULL;
323 }
324
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000325 out = xmlOutputBufferCreateIO((xmlOutputWriteCallback)
326 xmlTextWriterWriteDocCallback,
327 (xmlOutputCloseCallback)
328 xmlTextWriterCloseDocCallback,
329 (void *) ctxt, NULL);
330 if (out == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000331 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000332 "xmlNewTextWriterPushParser : error at xmlOutputBufferCreateIO!\n");
333 return NULL;
334 }
335
336 ret = xmlNewTextWriter(out);
337 if (ret == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000338 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000339 "xmlNewTextWriterPushParser : error at xmlNewTextWriter!\n");
340 xmlOutputBufferClose(out);
341 return NULL;
342 }
343
Daniel Veillard20c5e782004-01-21 09:57:31 +0000344 ret->ctxt = ctxt;
345
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000346 return ret;
347}
348
349/**
350 * xmlNewTextWriterDoc:
351 * @doc: address of a xmlDocPtr to hold the new XML document tree
352 * @compression: compress the output?
353 *
354 * Create a new xmlNewTextWriter structure with @*doc as output
355 *
356 * Returns the new xmlTextWriterPtr or NULL in case of error
357 */
358xmlTextWriterPtr
359xmlNewTextWriterDoc(xmlDocPtr * doc, int compression)
360{
361 xmlTextWriterPtr ret;
362 xmlSAXHandler saxHandler;
363 xmlParserCtxtPtr ctxt;
364
365 memset(&saxHandler, '\0', sizeof(saxHandler));
366 xmlSAX2InitDefaultSAXHandler(&saxHandler, 1);
367 saxHandler.startDocument = xmlTextWriterStartDocumentCallback;
368 saxHandler.startElement = xmlSAX2StartElement;
369 saxHandler.endElement = xmlSAX2EndElement;
370
371 ctxt = xmlCreatePushParserCtxt(&saxHandler, NULL, NULL, 0, NULL);
372 if (ctxt == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000373 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000374 "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\n");
375 return NULL;
376 }
Daniel Veillard03a53c32004-10-26 16:06:51 +0000377 /*
378 * For some reason this seems to completely break if node names
379 * are interned.
380 */
381 ctxt->dictNames = 0;
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000382
Daniel Veillard1d913862003-11-21 00:28:39 +0000383 ctxt->myDoc = xmlNewDoc(BAD_CAST XML_DEFAULT_VERSION);
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000384 if (ctxt->myDoc == NULL) {
385 xmlFreeParserCtxt(ctxt);
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000386 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000387 "xmlNewTextWriterDoc : error at xmlNewDoc!\n");
388 return NULL;
389 }
390
391 ret = xmlNewTextWriterPushParser(ctxt, compression);
392 if (ret == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000393 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000394 "xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n");
395 return NULL;
396 }
397
Daniel Veillard500a1de2004-03-22 15:22:58 +0000398 xmlSetDocCompressMode(ctxt->myDoc, compression);
399
Daniel Veillarda521d282004-11-09 14:59:59 +0000400 if (doc != NULL) {
Daniel Veillard500a1de2004-03-22 15:22:58 +0000401 *doc = ctxt->myDoc;
Daniel Veillarda521d282004-11-09 14:59:59 +0000402 ret->no_doc_free = 1;
403 }
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000404
405 return ret;
406}
407
408/**
409 * xmlNewTextWriterTree:
410 * @doc: xmlDocPtr
411 * @node: xmlNodePtr or NULL for doc->children
412 * @compression: compress the output?
413 *
414 * Create a new xmlNewTextWriter structure with @doc as output
415 * starting at @node
416 *
417 * Returns the new xmlTextWriterPtr or NULL in case of error
418 */
419xmlTextWriterPtr
420xmlNewTextWriterTree(xmlDocPtr doc, xmlNodePtr node, int compression)
421{
422 xmlTextWriterPtr ret;
423 xmlSAXHandler saxHandler;
424 xmlParserCtxtPtr ctxt;
425
426 if (doc == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000427 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000428 "xmlNewTextWriterTree : invalid document tree!\n");
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000429 return NULL;
430 }
431
432 memset(&saxHandler, '\0', sizeof(saxHandler));
433 xmlSAX2InitDefaultSAXHandler(&saxHandler, 1);
434 saxHandler.startDocument = xmlTextWriterStartDocumentCallback;
435 saxHandler.startElement = xmlSAX2StartElement;
436 saxHandler.endElement = xmlSAX2EndElement;
437
438 ctxt = xmlCreatePushParserCtxt(&saxHandler, NULL, NULL, 0, NULL);
439 if (ctxt == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000440 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000441 "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\n");
442 return NULL;
443 }
Daniel Veillard03a53c32004-10-26 16:06:51 +0000444 /*
445 * For some reason this seems to completely break if node names
446 * are interned.
447 */
448 ctxt->dictNames = 0;
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000449
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000450 ret = xmlNewTextWriterPushParser(ctxt, compression);
451 if (ret == NULL) {
Daniel Veillard500a1de2004-03-22 15:22:58 +0000452 xmlFreeParserCtxt(ctxt);
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000453 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000454 "xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n");
455 return NULL;
456 }
457
Daniel Veillard500a1de2004-03-22 15:22:58 +0000458 ctxt->myDoc = doc;
459 ctxt->node = node;
Daniel Veillarda521d282004-11-09 14:59:59 +0000460 ret->no_doc_free = 1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000461
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000462 xmlSetDocCompressMode(doc, compression);
463
464 return ret;
465}
466
467/**
Daniel Veillard1d211e22003-10-20 22:32:39 +0000468 * xmlFreeTextWriter:
469 * @writer: the xmlTextWriterPtr
470 *
471 * Deallocate all the resources associated to the writer
472 */
473void
474xmlFreeTextWriter(xmlTextWriterPtr writer)
475{
476 if (writer == NULL)
477 return;
478
479 if (writer->out != NULL)
480 xmlOutputBufferClose(writer->out);
481
482 if (writer->nodes != NULL)
483 xmlListDelete(writer->nodes);
484
485 if (writer->nsstack != NULL)
486 xmlListDelete(writer->nsstack);
487
Daniel Veillarda521d282004-11-09 14:59:59 +0000488 if (writer->ctxt != NULL) {
489 if ((writer->ctxt->myDoc != NULL) && (writer->no_doc_free == 0)) {
490 xmlFreeDoc(writer->ctxt->myDoc);
491 writer->ctxt->myDoc = NULL;
492 }
Daniel Veillard20c5e782004-01-21 09:57:31 +0000493 xmlFreeParserCtxt(writer->ctxt);
Daniel Veillarda521d282004-11-09 14:59:59 +0000494 }
Daniel Veillard20c5e782004-01-21 09:57:31 +0000495
Daniel Veillard4773df22004-01-23 13:15:13 +0000496 if (writer->ichar != NULL)
497 xmlFree(writer->ichar);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000498 xmlFree(writer);
499}
500
501/**
502 * xmlTextWriterStartDocument:
503 * @writer: the xmlTextWriterPtr
504 * @version: the xml version ("1.0") or NULL for default ("1.0")
505 * @encoding: the encoding or NULL for default
506 * @standalone: "yes" or "no" or NULL for default
507 *
508 * Start a new xml document
509 *
510 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
511 */
512int
513xmlTextWriterStartDocument(xmlTextWriterPtr writer, const char *version,
514 const char *encoding, const char *standalone)
515{
516 int count;
517 int sum;
518 xmlLinkPtr lk;
519 xmlCharEncodingHandlerPtr encoder;
520
Daniel Veillard500a1de2004-03-22 15:22:58 +0000521 if ((writer == NULL) || (writer->out == NULL)) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000522 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000523 "xmlTextWriterStartDocument : invalid writer!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000524 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000525 }
Daniel Veillard1d211e22003-10-20 22:32:39 +0000526
527 lk = xmlListFront(writer->nodes);
528 if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000529 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000530 "xmlTextWriterStartDocument : not allowed in this context!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000531 return -1;
532 }
533
534 encoder = NULL;
535 if (encoding != NULL) {
536 encoder = xmlFindCharEncodingHandler(encoding);
537 if (encoder == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000538 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000539 "xmlTextWriterStartDocument : out of memory!\n");
540 return -1;
541 }
542 }
543
544 writer->out->encoder = encoder;
545 if (encoder != NULL) {
546 writer->out->conv = xmlBufferCreateSize(4000);
547 xmlCharEncOutFunc(encoder, writer->out->conv, NULL);
548 } else
549 writer->out->conv = NULL;
550
551 sum = 0;
552 count = xmlOutputBufferWriteString(writer->out, "<?xml version=");
553 if (count < 0)
554 return -1;
555 sum += count;
556 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
557 if (count < 0)
558 return -1;
559 sum += count;
560 if (version != 0)
561 count = xmlOutputBufferWriteString(writer->out, version);
562 else
563 count = xmlOutputBufferWriteString(writer->out, "1.0");
564 if (count < 0)
565 return -1;
566 sum += count;
567 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
568 if (count < 0)
569 return -1;
570 sum += count;
571 if (writer->out->encoder != 0) {
572 count = xmlOutputBufferWriteString(writer->out, " encoding=");
573 if (count < 0)
574 return -1;
575 sum += count;
576 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
577 if (count < 0)
578 return -1;
579 sum += count;
580 count =
581 xmlOutputBufferWriteString(writer->out,
582 writer->out->encoder->name);
583 if (count < 0)
584 return -1;
585 sum += count;
586 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
587 if (count < 0)
588 return -1;
589 sum += count;
590 }
591
592 if (standalone != 0) {
593 count = xmlOutputBufferWriteString(writer->out, " standalone=");
594 if (count < 0)
595 return -1;
596 sum += count;
597 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
598 if (count < 0)
599 return -1;
600 sum += count;
601 count = xmlOutputBufferWriteString(writer->out, standalone);
602 if (count < 0)
603 return -1;
604 sum += count;
605 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
606 if (count < 0)
607 return -1;
608 sum += count;
609 }
610
611 count = xmlOutputBufferWriteString(writer->out, "?>\n");
612 if (count < 0)
613 return -1;
614 sum += count;
615
616 return sum;
617}
618
619/**
620 * xmlTextWriterEndDocument:
621 * @writer: the xmlTextWriterPtr
622 *
623 * End an xml document. All open elements are closed
624 *
625 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
626 */
627int
628xmlTextWriterEndDocument(xmlTextWriterPtr writer)
629{
630 int count;
631 int sum;
632 xmlLinkPtr lk;
633 xmlTextWriterStackEntry *p;
634
Daniel Veillard500a1de2004-03-22 15:22:58 +0000635 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000636 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000637 "xmlTextWriterEndDocument : invalid writer!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000638 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000639 }
Daniel Veillard1d211e22003-10-20 22:32:39 +0000640
641 sum = 0;
642 while ((lk = xmlListFront(writer->nodes)) != NULL) {
643 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
644 if (p == 0)
645 break;
646 switch (p->state) {
647 case XML_TEXTWRITER_NAME:
648 case XML_TEXTWRITER_ATTRIBUTE:
649 case XML_TEXTWRITER_TEXT:
650 count = xmlTextWriterEndElement(writer);
651 if (count < 0)
652 return -1;
653 sum += count;
654 break;
655 case XML_TEXTWRITER_PI:
656 case XML_TEXTWRITER_PI_TEXT:
657 count = xmlTextWriterEndPI(writer);
658 if (count < 0)
659 return -1;
660 sum += count;
661 break;
662 case XML_TEXTWRITER_CDATA:
663 count = xmlTextWriterEndCDATA(writer);
664 if (count < 0)
665 return -1;
666 sum += count;
667 break;
668 case XML_TEXTWRITER_DTD:
Daniel Veillard500a1de2004-03-22 15:22:58 +0000669 case XML_TEXTWRITER_DTD_TEXT:
670 case XML_TEXTWRITER_DTD_ELEM:
671 case XML_TEXTWRITER_DTD_ELEM_TEXT:
672 case XML_TEXTWRITER_DTD_ATTL:
673 case XML_TEXTWRITER_DTD_ATTL_TEXT:
674 case XML_TEXTWRITER_DTD_ENTY:
675 case XML_TEXTWRITER_DTD_ENTY_TEXT:
676 case XML_TEXTWRITER_DTD_PENT:
Daniel Veillard1d211e22003-10-20 22:32:39 +0000677 count = xmlTextWriterEndDTD(writer);
678 if (count < 0)
679 return -1;
680 sum += count;
681 break;
Daniel Veillardab69f362004-02-17 11:40:32 +0000682 case XML_TEXTWRITER_COMMENT:
683 count = xmlTextWriterEndComment(writer);
684 if (count < 0)
685 return -1;
686 sum += count;
687 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000688 default:
Daniel Veillardab69f362004-02-17 11:40:32 +0000689 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000690 }
691 }
692
Daniel Veillard2cca4462004-01-02 20:04:23 +0000693 if (!writer->indent) {
Daniel Veillardab69f362004-02-17 11:40:32 +0000694 count = xmlOutputBufferWriteString(writer->out, "\n");
695 if (count < 0)
696 return -1;
697 sum += count;
698 }
699 return sum;
700}
701
Daniel Veillardab69f362004-02-17 11:40:32 +0000702/**
703 * xmlTextWriterStartComment:
704 * @writer: the xmlTextWriterPtr
705 *
706 * Start an xml comment.
707 *
708 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
709 */
710int
711xmlTextWriterStartComment(xmlTextWriterPtr writer)
712{
713 int count;
714 int sum;
715 xmlLinkPtr lk;
716 xmlTextWriterStackEntry *p;
717
Daniel Veillard500a1de2004-03-22 15:22:58 +0000718 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000719 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000720 "xmlTextWriterStartComment : invalid writer!\n");
Daniel Veillardab69f362004-02-17 11:40:32 +0000721 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000722 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000723
724 sum = 0;
725 lk = xmlListFront(writer->nodes);
726 if (lk != 0) {
727 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
728 if (p != 0) {
729 switch (p->state) {
730 case XML_TEXTWRITER_TEXT:
731 case XML_TEXTWRITER_NONE:
732 break;
733 case XML_TEXTWRITER_NAME:
734 count = xmlOutputBufferWriteString(writer->out, ">");
735 if (count < 0)
736 return -1;
737 sum += count;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000738 if (writer->indent) {
739 count =
740 xmlOutputBufferWriteString(writer->out, "\n");
741 if (count < 0)
742 return -1;
743 sum += count;
744 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000745 p->state = XML_TEXTWRITER_TEXT;
746 break;
747 default:
748 return -1;
749 }
750 }
751 }
752
753 p = (xmlTextWriterStackEntry *)
754 xmlMalloc(sizeof(xmlTextWriterStackEntry));
755 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000756 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillardab69f362004-02-17 11:40:32 +0000757 "xmlTextWriterStartElement : out of memory!\n");
758 return -1;
759 }
760
Daniel Veillard75e389d2005-07-29 22:02:24 +0000761 p->name = NULL;
Daniel Veillardab69f362004-02-17 11:40:32 +0000762 p->state = XML_TEXTWRITER_COMMENT;
763
764 xmlListPushFront(writer->nodes, p);
765
766 if (writer->indent) {
Daniel Veillardab69f362004-02-17 11:40:32 +0000767 count = xmlTextWriterWriteIndent(writer);
768 if (count < 0)
769 return -1;
770 sum += count;
771 }
772
773 count = xmlOutputBufferWriteString(writer->out, "<!--");
774 if (count < 0)
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000775 return -1;
776 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +0000777
778 return sum;
779}
780
781/**
782 * xmlTextWriterEndComment:
783 * @writer: the xmlTextWriterPtr
784 *
785 * End the current xml coment.
786 *
787 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
788 */
789int
790xmlTextWriterEndComment(xmlTextWriterPtr writer)
791{
792 int count;
793 int sum;
794 xmlLinkPtr lk;
795 xmlTextWriterStackEntry *p;
796
Daniel Veillard500a1de2004-03-22 15:22:58 +0000797 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000798 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000799 "xmlTextWriterEndComment : invalid writer!\n");
Daniel Veillardab69f362004-02-17 11:40:32 +0000800 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000801 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000802
803 lk = xmlListFront(writer->nodes);
Daniel Veillard500a1de2004-03-22 15:22:58 +0000804 if (lk == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000805 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000806 "xmlTextWriterEndComment : not allowed in this context!\n");
Daniel Veillardab69f362004-02-17 11:40:32 +0000807 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000808 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000809
810 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
811 if (p == 0)
812 return -1;
813
814 sum = 0;
815 switch (p->state) {
816 case XML_TEXTWRITER_COMMENT:
817 count = xmlOutputBufferWriteString(writer->out, "-->");
818 if (count < 0)
819 return -1;
820 sum += count;
821 break;
822 default:
823 return -1;
Daniel Veillard2cca4462004-01-02 20:04:23 +0000824 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000825
826 if (writer->indent) {
827 count = xmlOutputBufferWriteString(writer->out, "\n");
828 if (count < 0)
829 return -1;
830 sum += count;
831 }
832
833 xmlListPopFront(writer->nodes);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000834 return sum;
835}
836
837/**
838 * xmlTextWriterWriteFormatComment:
839 * @writer: the xmlTextWriterPtr
840 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +0000841 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +0000842 *
843 * Write an xml comment.
844 *
845 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
846 */
Daniel Veillardffa3c742005-07-21 13:24:09 +0000847int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +0000848xmlTextWriterWriteFormatComment(xmlTextWriterPtr writer,
849 const char *format, ...)
850{
851 int rc;
852 va_list ap;
853
854 va_start(ap, format);
855
856 rc = xmlTextWriterWriteVFormatComment(writer, format, ap);
857
858 va_end(ap);
859 return rc;
860}
861
862/**
863 * xmlTextWriterWriteVFormatComment:
864 * @writer: the xmlTextWriterPtr
865 * @format: format string (see printf)
866 * @argptr: pointer to the first member of the variable argument list.
867 *
868 * Write an xml comment.
869 *
870 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
871 */
872int
873xmlTextWriterWriteVFormatComment(xmlTextWriterPtr writer,
874 const char *format, va_list argptr)
875{
876 int rc;
877 xmlChar *buf;
878
Daniel Veillard500a1de2004-03-22 15:22:58 +0000879 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000880 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000881 "xmlTextWriterWriteVFormatComment : invalid writer!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000882 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000883 }
Daniel Veillard1d211e22003-10-20 22:32:39 +0000884
885 buf = xmlTextWriterVSprintf(format, argptr);
886 if (buf == 0)
887 return 0;
888
889 rc = xmlTextWriterWriteComment(writer, buf);
890
891 xmlFree(buf);
892 return rc;
893}
894
895/**
896 * xmlTextWriterWriteComment:
897 * @writer: the xmlTextWriterPtr
898 * @content: comment string
899 *
900 * Write an xml comment.
901 *
902 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
903 */
904int
905xmlTextWriterWriteComment(xmlTextWriterPtr writer, const xmlChar * content)
906{
907 int count;
908 int sum;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000909
910 sum = 0;
Daniel Veillardab69f362004-02-17 11:40:32 +0000911 count = xmlTextWriterStartComment(writer);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000912 if (count < 0)
913 return -1;
914 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +0000915 count = xmlTextWriterWriteString(writer, content);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000916 if (count < 0)
917 return -1;
918 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +0000919 count = xmlTextWriterEndComment(writer);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000920 if (count < 0)
921 return -1;
922 sum += count;
923
924 return sum;
925}
926
927/**
928 * xmlTextWriterStartElement:
929 * @writer: the xmlTextWriterPtr
930 * @name: element name
931 *
932 * Start an xml element.
933 *
934 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
935 */
936int
937xmlTextWriterStartElement(xmlTextWriterPtr writer, const xmlChar * name)
938{
939 int count;
940 int sum;
941 xmlLinkPtr lk;
942 xmlTextWriterStackEntry *p;
943
944 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
945 return -1;
946
947 sum = 0;
948 lk = xmlListFront(writer->nodes);
949 if (lk != 0) {
950 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
951 if (p != 0) {
952 switch (p->state) {
953 case XML_TEXTWRITER_PI:
954 case XML_TEXTWRITER_PI_TEXT:
955 return -1;
956 case XML_TEXTWRITER_NONE:
957 break;
Daniel Veillard614fdc12005-02-23 14:05:37 +0000958 case XML_TEXTWRITER_ATTRIBUTE:
959 count = xmlTextWriterEndAttribute(writer);
960 if (count < 0)
961 return -1;
962 sum += count;
963 /* fallthrough */
Daniel Veillard1d211e22003-10-20 22:32:39 +0000964 case XML_TEXTWRITER_NAME:
965 count = xmlOutputBufferWriteString(writer->out, ">");
966 if (count < 0)
967 return -1;
968 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +0000969 if (writer->indent)
970 count =
971 xmlOutputBufferWriteString(writer->out, "\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000972 p->state = XML_TEXTWRITER_TEXT;
973 break;
Daniel Veillardab69f362004-02-17 11:40:32 +0000974 default:
975 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000976 }
977 }
978 }
979
980 p = (xmlTextWriterStackEntry *)
981 xmlMalloc(sizeof(xmlTextWriterStackEntry));
982 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000983 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000984 "xmlTextWriterStartElement : out of memory!\n");
985 return -1;
986 }
987
988 p->name = xmlStrdup(name);
989 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000990 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000991 "xmlTextWriterStartElement : out of memory!\n");
992 xmlFree(p);
993 return -1;
994 }
995 p->state = XML_TEXTWRITER_NAME;
996
997 xmlListPushFront(writer->nodes, p);
998
Daniel Veillardab69f362004-02-17 11:40:32 +0000999 if (writer->indent) {
1000 count = xmlTextWriterWriteIndent(writer);
1001 sum += count;
Daniel Veillard2cca4462004-01-02 20:04:23 +00001002 }
1003
Daniel Veillard1d211e22003-10-20 22:32:39 +00001004 count = xmlOutputBufferWriteString(writer->out, "<");
1005 if (count < 0)
1006 return -1;
1007 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00001008 count =
1009 xmlOutputBufferWriteString(writer->out, (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001010 if (count < 0)
1011 return -1;
1012 sum += count;
1013
1014 return sum;
1015}
1016
1017/**
1018 * xmlTextWriterStartElementNS:
1019 * @writer: the xmlTextWriterPtr
1020 * @prefix: namespace prefix or NULL
1021 * @name: element local name
1022 * @namespaceURI: namespace URI or NULL
1023 *
1024 * Start an xml element with namespace support.
1025 *
1026 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1027 */
1028int
1029xmlTextWriterStartElementNS(xmlTextWriterPtr writer,
1030 const xmlChar * prefix, const xmlChar * name,
1031 const xmlChar * namespaceURI)
1032{
1033 int count;
1034 int sum;
1035 xmlChar *buf;
1036
1037 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1038 return -1;
1039
Daniel Veillard75e389d2005-07-29 22:02:24 +00001040 buf = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001041 if (prefix != 0) {
1042 buf = xmlStrdup(prefix);
1043 buf = xmlStrcat(buf, BAD_CAST ":");
1044 }
1045 buf = xmlStrcat(buf, name);
1046
1047 sum = 0;
1048 count = xmlTextWriterStartElement(writer, buf);
1049 xmlFree(buf);
1050 if (count < 0)
1051 return -1;
1052 sum += count;
1053
1054 if (namespaceURI != 0) {
1055 buf = xmlStrdup(BAD_CAST "xmlns");
1056 if (prefix != 0) {
1057 buf = xmlStrcat(buf, BAD_CAST ":");
1058 buf = xmlStrcat(buf, prefix);
1059 }
1060
1061 count = xmlTextWriterWriteAttribute(writer, buf, namespaceURI);
1062 xmlFree(buf);
1063 if (count < 0)
1064 return -1;
1065 sum += count;
1066 }
1067
1068 return sum;
1069}
1070
1071/**
1072 * xmlTextWriterEndElement:
1073 * @writer: the xmlTextWriterPtr
1074 *
1075 * End the current xml element.
1076 *
1077 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1078 */
1079int
1080xmlTextWriterEndElement(xmlTextWriterPtr writer)
1081{
1082 int count;
1083 int sum;
1084 xmlLinkPtr lk;
1085 xmlTextWriterStackEntry *p;
1086
1087 if (writer == NULL)
1088 return -1;
1089
1090 lk = xmlListFront(writer->nodes);
1091 if (lk == 0)
1092 return -1;
1093
1094 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1095 if (p == 0)
1096 return -1;
1097
1098 sum = 0;
1099 switch (p->state) {
1100 case XML_TEXTWRITER_ATTRIBUTE:
1101 count = xmlTextWriterEndAttribute(writer);
1102 if (count < 0)
1103 return -1;
1104 sum += count;
1105 /* fallthrough */
1106 case XML_TEXTWRITER_NAME:
Daniel Veillardab69f362004-02-17 11:40:32 +00001107 if (writer->indent) /* next element needs indent */
1108 writer->doindent = 1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001109 count = xmlOutputBufferWriteString(writer->out, "/>");
1110 if (count < 0)
1111 return -1;
1112 sum += count;
1113 break;
1114 case XML_TEXTWRITER_TEXT:
Daniel Veillardab69f362004-02-17 11:40:32 +00001115 if ((writer->indent) && (writer->doindent)) {
1116 count = xmlTextWriterWriteIndent(writer);
1117 sum += count;
1118 writer->doindent = 1;
1119 } else
1120 writer->doindent = 1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001121 count = xmlOutputBufferWriteString(writer->out, "</");
1122 if (count < 0)
1123 return -1;
1124 sum += count;
1125 count = xmlOutputBufferWriteString(writer->out,
Daniel Veillardab69f362004-02-17 11:40:32 +00001126 (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001127 if (count < 0)
1128 return -1;
1129 sum += count;
1130 count = xmlOutputBufferWriteString(writer->out, ">");
1131 if (count < 0)
1132 return -1;
1133 sum += count;
1134 break;
1135 default:
1136 return -1;
1137 }
1138
Daniel Veillard2cca4462004-01-02 20:04:23 +00001139 if (writer->indent) {
Daniel Veillardab69f362004-02-17 11:40:32 +00001140 count = xmlOutputBufferWriteString(writer->out, "\n");
1141 sum += count;
Daniel Veillard2cca4462004-01-02 20:04:23 +00001142 }
1143
Daniel Veillard1d211e22003-10-20 22:32:39 +00001144 xmlListPopFront(writer->nodes);
1145 return sum;
1146}
1147
1148/**
1149 * xmlTextWriterFullEndElement:
1150 * @writer: the xmlTextWriterPtr
1151 *
1152 * End the current xml element. Writes an end tag even if the element is empty
1153 *
1154 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1155 */
1156int
1157xmlTextWriterFullEndElement(xmlTextWriterPtr writer)
1158{
1159 int count;
1160 int sum;
1161 xmlLinkPtr lk;
1162 xmlTextWriterStackEntry *p;
1163
1164 if (writer == NULL)
1165 return -1;
1166
1167 lk = xmlListFront(writer->nodes);
1168 if (lk == 0)
1169 return -1;
1170
1171 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1172 if (p == 0)
1173 return -1;
1174
1175 sum = 0;
1176 switch (p->state) {
1177 case XML_TEXTWRITER_ATTRIBUTE:
1178 count = xmlTextWriterEndAttribute(writer);
1179 if (count < 0)
1180 return -1;
1181 sum += count;
1182 /* fallthrough */
1183 case XML_TEXTWRITER_NAME:
1184 count = xmlOutputBufferWriteString(writer->out, ">");
1185 if (count < 0)
1186 return -1;
1187 sum += count;
1188 /* fallthrough */
1189 case XML_TEXTWRITER_TEXT:
1190 count = xmlOutputBufferWriteString(writer->out, "</");
1191 if (count < 0)
1192 return -1;
1193 sum += count;
1194 count = xmlOutputBufferWriteString(writer->out,
Daniel Veillardab69f362004-02-17 11:40:32 +00001195 (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001196 if (count < 0)
1197 return -1;
1198 sum += count;
1199 count = xmlOutputBufferWriteString(writer->out, ">");
1200 if (count < 0)
1201 return -1;
1202 sum += count;
1203 break;
1204 default:
1205 return -1;
1206 }
1207
1208 xmlListPopFront(writer->nodes);
1209 return sum;
1210}
1211
1212/**
1213 * xmlTextWriterWriteFormatRaw:
1214 * @writer: the xmlTextWriterPtr
1215 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001216 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001217 *
1218 * Write a formatted raw xml text.
1219 *
1220 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1221 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00001222int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00001223xmlTextWriterWriteFormatRaw(xmlTextWriterPtr writer, const char *format,
1224 ...)
1225{
1226 int rc;
1227 va_list ap;
1228
1229 va_start(ap, format);
1230
1231 rc = xmlTextWriterWriteVFormatRaw(writer, format, ap);
1232
1233 va_end(ap);
1234 return rc;
1235}
1236
1237/**
1238 * xmlTextWriterWriteVFormatRaw:
1239 * @writer: the xmlTextWriterPtr
1240 * @format: format string (see printf)
1241 * @argptr: pointer to the first member of the variable argument list.
1242 *
1243 * Write a formatted raw xml text.
1244 *
1245 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1246 */
1247int
1248xmlTextWriterWriteVFormatRaw(xmlTextWriterPtr writer, const char *format,
1249 va_list argptr)
1250{
1251 int rc;
1252 xmlChar *buf;
1253
1254 if (writer == NULL)
1255 return -1;
1256
1257 buf = xmlTextWriterVSprintf(format, argptr);
1258 if (buf == 0)
1259 return 0;
1260
1261 rc = xmlTextWriterWriteRaw(writer, buf);
1262
1263 xmlFree(buf);
1264 return rc;
1265}
1266
1267/**
Daniel Veillard1e906612003-12-05 14:57:46 +00001268 * xmlTextWriterWriteRawLen:
Daniel Veillard1d211e22003-10-20 22:32:39 +00001269 * @writer: the xmlTextWriterPtr
1270 * @content: text string
1271 * @len: length of the text string
1272 *
1273 * Write an xml text.
1274 * TODO: what about entities and special chars??
1275 *
1276 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1277 */
1278int
1279xmlTextWriterWriteRawLen(xmlTextWriterPtr writer, const xmlChar * content,
1280 int len)
1281{
1282 int count;
1283 int sum;
1284 xmlLinkPtr lk;
1285 xmlTextWriterStackEntry *p;
1286
Daniel Veillard500a1de2004-03-22 15:22:58 +00001287 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00001288 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00001289 "xmlTextWriterWriteRawLen : invalid writer!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +00001290 return -1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001291 }
1292
Daniel Veillarde43cc572004-11-03 11:50:29 +00001293 if ((content == NULL) || (len < 0)) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00001294 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00001295 "xmlTextWriterWriteRawLen : invalid content!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +00001296 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001297 }
1298
1299 sum = 0;
1300 lk = xmlListFront(writer->nodes);
1301 if (lk != 0) {
1302 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1303 count = xmlTextWriterHandleStateDependencies(writer, p);
1304 if (count < 0)
1305 return -1;
1306 sum += count;
1307 }
1308
1309 if (writer->indent)
1310 writer->doindent = 0;
1311
1312 if (content != NULL) {
1313 count =
1314 xmlOutputBufferWrite(writer->out, len, (const char *) content);
1315 if (count < 0)
1316 return -1;
1317 sum += count;
1318 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001319
1320 return sum;
1321}
1322
1323/**
1324 * xmlTextWriterWriteRaw:
1325 * @writer: the xmlTextWriterPtr
1326 * @content: text string
1327 *
1328 * Write a raw xml text.
1329 *
1330 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1331 */
1332int
1333xmlTextWriterWriteRaw(xmlTextWriterPtr writer, const xmlChar * content)
1334{
1335 return xmlTextWriterWriteRawLen(writer, content, xmlStrlen(content));
1336}
1337
1338/**
1339 * xmlTextWriterWriteFormatString:
1340 * @writer: the xmlTextWriterPtr
1341 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001342 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001343 *
1344 * Write a formatted xml text.
1345 *
1346 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1347 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00001348int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00001349xmlTextWriterWriteFormatString(xmlTextWriterPtr writer, const char *format,
1350 ...)
1351{
1352 int rc;
1353 va_list ap;
1354
Daniel Veillarde43cc572004-11-03 11:50:29 +00001355 if ((writer == NULL) || (format == NULL))
1356 return -1;
1357
Daniel Veillard1d211e22003-10-20 22:32:39 +00001358 va_start(ap, format);
1359
1360 rc = xmlTextWriterWriteVFormatString(writer, format, ap);
1361
1362 va_end(ap);
1363 return rc;
1364}
1365
1366/**
1367 * xmlTextWriterWriteVFormatString:
1368 * @writer: the xmlTextWriterPtr
1369 * @format: format string (see printf)
1370 * @argptr: pointer to the first member of the variable argument list.
1371 *
1372 * Write a formatted xml text.
1373 *
1374 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1375 */
1376int
1377xmlTextWriterWriteVFormatString(xmlTextWriterPtr writer,
1378 const char *format, va_list argptr)
1379{
1380 int rc;
1381 xmlChar *buf;
1382
Daniel Veillarde43cc572004-11-03 11:50:29 +00001383 if ((writer == NULL) || (format == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00001384 return -1;
1385
1386 buf = xmlTextWriterVSprintf(format, argptr);
1387 if (buf == 0)
1388 return 0;
1389
1390 rc = xmlTextWriterWriteString(writer, buf);
1391
1392 xmlFree(buf);
1393 return rc;
1394}
1395
1396/**
1397 * xmlTextWriterWriteString:
1398 * @writer: the xmlTextWriterPtr
1399 * @content: text string
1400 *
1401 * Write an xml text.
1402 *
1403 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1404 */
1405int
1406xmlTextWriterWriteString(xmlTextWriterPtr writer, const xmlChar * content)
1407{
Daniel Veillard500a1de2004-03-22 15:22:58 +00001408 int count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001409 int sum;
1410 xmlLinkPtr lk;
1411 xmlTextWriterStackEntry *p;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001412 xmlChar *buf;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001413
Daniel Veillarde43cc572004-11-03 11:50:29 +00001414 if ((writer == NULL) || (content == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00001415 return -1;
1416
Daniel Veillard1d211e22003-10-20 22:32:39 +00001417 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001418 buf = (xmlChar *) content;
1419 lk = xmlListFront(writer->nodes);
1420 if (lk != 0) {
1421 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1422 if (p != 0) {
1423 switch (p->state) {
1424 case XML_TEXTWRITER_NAME:
1425 case XML_TEXTWRITER_TEXT:
Daniel Veillard62040be2004-05-17 03:17:26 +00001426#if 0
1427 buf = NULL;
1428 xmlOutputBufferWriteEscape(writer->out, content, NULL);
1429#endif
Daniel Veillard500a1de2004-03-22 15:22:58 +00001430 buf = xmlEncodeSpecialChars(NULL, content);
1431 break;
1432 case XML_TEXTWRITER_ATTRIBUTE:
1433 buf = NULL;
1434 xmlAttrSerializeTxtContent(writer->out->buffer, NULL,
1435 NULL, content);
1436 break;
William M. Brack87640d52004-04-17 14:58:15 +00001437 default:
1438 break;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001439 }
1440 }
1441 }
1442
1443 if (buf != NULL) {
1444 count = xmlTextWriterWriteRaw(writer, buf);
1445 if (count < 0)
Daniel Veillard1d211e22003-10-20 22:32:39 +00001446 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001447 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001448
Daniel Veillard500a1de2004-03-22 15:22:58 +00001449 if (buf != content) /* buf was allocated by us, so free it */
1450 xmlFree(buf);
William M. Bracka9c612c2004-02-01 10:04:05 +00001451 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001452
1453 return sum;
1454}
1455
1456/**
1457 * xmlOutputBufferWriteBase64:
1458 * @out: the xmlOutputBufferPtr
1459 * @data: binary data
1460 * @len: the number of bytes to encode
1461 *
1462 * Write base64 encoded data to an xmlOutputBuffer.
1463 * Adapted from John Walker's base64.c (http://www.fourmilab.ch/).
1464 *
1465 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1466 */
1467static int
1468xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len,
1469 const unsigned char *data)
1470{
1471 static unsigned char dtable[64] =
William M. Brack47a31882004-09-11 16:09:09 +00001472 {'A','B','C','D','E','F','G','H','I','J','K','L','M',
1473 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
1474 'a','b','c','d','e','f','g','h','i','j','k','l','m',
1475 'n','o','p','q','r','s','t','u','v','w','x','y','z',
1476 '0','1','2','3','4','5','6','7','8','9','+','/'};
1477
Daniel Veillard1d211e22003-10-20 22:32:39 +00001478 int i;
1479 int linelen;
1480 int count;
1481 int sum;
1482
Daniel Veillarde43cc572004-11-03 11:50:29 +00001483 if ((out == NULL) || (len < 0) || (data == NULL))
1484 return(-1);
1485
Daniel Veillard1d211e22003-10-20 22:32:39 +00001486 linelen = 0;
1487 sum = 0;
1488
1489 i = 0;
1490 while (1) {
1491 unsigned char igroup[3];
1492 unsigned char ogroup[4];
1493 int c;
1494 int n;
1495
1496 igroup[0] = igroup[1] = igroup[2] = 0;
1497 for (n = 0; n < 3 && i < len; n++, i++) {
1498 c = data[i];
1499 igroup[n] = (unsigned char) c;
1500 }
1501
1502 if (n > 0) {
1503 ogroup[0] = dtable[igroup[0] >> 2];
1504 ogroup[1] = dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)];
1505 ogroup[2] =
1506 dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)];
1507 ogroup[3] = dtable[igroup[2] & 0x3F];
1508
1509 if (n < 3) {
1510 ogroup[3] = '=';
1511 if (n < 2) {
1512 ogroup[2] = '=';
1513 }
1514 }
1515
1516 if (linelen >= B64LINELEN) {
1517 count = xmlOutputBufferWrite(out, 2, B64CRLF);
1518 if (count == -1)
1519 return -1;
1520 sum += count;
1521 linelen = 0;
1522 }
1523 count = xmlOutputBufferWrite(out, 4, (const char *) ogroup);
1524 if (count == -1)
1525 return -1;
1526 sum += count;
1527
1528 linelen += 4;
1529 }
Daniel Veillard929714b2003-10-22 12:34:36 +00001530
1531 if (i >= len)
1532 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001533 }
1534
Daniel Veillard1d211e22003-10-20 22:32:39 +00001535 return sum;
1536}
1537
1538/**
1539 * xmlTextWriterWriteBase64:
1540 * @writer: the xmlTextWriterPtr
1541 * @data: binary data
1542 * @start: the position within the data of the first byte to encode
1543 * @len: the number of bytes to encode
1544 *
1545 * Write an base64 encoded xml text.
1546 *
1547 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1548 */
1549int
Daniel Veillardab69f362004-02-17 11:40:32 +00001550xmlTextWriterWriteBase64(xmlTextWriterPtr writer, const char *data,
Daniel Veillard1d211e22003-10-20 22:32:39 +00001551 int start, int len)
1552{
1553 int count;
1554 int sum;
1555 xmlLinkPtr lk;
1556 xmlTextWriterStackEntry *p;
1557
Daniel Veillarde43cc572004-11-03 11:50:29 +00001558 if ((writer == NULL) || (data == NULL) || (start < 0) || (len < 0))
Daniel Veillard1d211e22003-10-20 22:32:39 +00001559 return -1;
1560
Daniel Veillard1d211e22003-10-20 22:32:39 +00001561 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001562 lk = xmlListFront(writer->nodes);
1563 if (lk != 0) {
1564 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1565 if (p != 0) {
1566 count = xmlTextWriterHandleStateDependencies(writer, p);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001567 if (count < 0)
1568 return -1;
1569 sum += count;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001570 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001571 }
1572
Daniel Veillardab69f362004-02-17 11:40:32 +00001573 if (writer->indent)
1574 writer->doindent = 0;
1575
Daniel Veillard1d211e22003-10-20 22:32:39 +00001576 count =
1577 xmlOutputBufferWriteBase64(writer->out, len,
1578 (unsigned char *) data + start);
1579 if (count < 0)
1580 return -1;
1581 sum += count;
1582
1583 return sum;
1584}
1585
1586/**
1587 * xmlOutputBufferWriteBinHex:
1588 * @out: the xmlOutputBufferPtr
1589 * @data: binary data
1590 * @len: the number of bytes to encode
1591 *
1592 * Write hqx encoded data to an xmlOutputBuffer.
1593 * ::todo
1594 *
William M. Brack47a31882004-09-11 16:09:09 +00001595 * Returns the bytes written (may be 0 because of buffering)
1596 * or -1 in case of error
Daniel Veillard1d211e22003-10-20 22:32:39 +00001597 */
1598static int
Daniel Veillardab69f362004-02-17 11:40:32 +00001599xmlOutputBufferWriteBinHex(xmlOutputBufferPtr out,
1600 int len, const unsigned char *data)
Daniel Veillard1d211e22003-10-20 22:32:39 +00001601{
Daniel Veillardab69f362004-02-17 11:40:32 +00001602 int count;
1603 int sum;
William M. Brack47a31882004-09-11 16:09:09 +00001604 static char hex[16] =
1605 {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
Daniel Veillardab69f362004-02-17 11:40:32 +00001606 int i;
1607
Daniel Veillarde43cc572004-11-03 11:50:29 +00001608 if ((out == NULL) || (data == NULL) || (len < 0)) {
Daniel Veillardab69f362004-02-17 11:40:32 +00001609 return -1;
1610 }
1611
1612 sum = 0;
1613 for (i = 0; i < len; i++) {
1614 count =
1615 xmlOutputBufferWrite(out, 1,
1616 (const char *) &hex[data[i] >> 4]);
1617 if (count == -1)
1618 return -1;
1619 sum += count;
1620 count =
1621 xmlOutputBufferWrite(out, 1,
1622 (const char *) &hex[data[i] & 0xF]);
1623 if (count == -1)
1624 return -1;
1625 sum += count;
1626 }
1627
1628 return sum;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001629}
1630
1631/**
1632 * xmlTextWriterWriteBinHex:
1633 * @writer: the xmlTextWriterPtr
1634 * @data: binary data
1635 * @start: the position within the data of the first byte to encode
1636 * @len: the number of bytes to encode
1637 *
1638 * Write a BinHex encoded xml text.
1639 *
1640 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1641 */
1642int
Daniel Veillardab69f362004-02-17 11:40:32 +00001643xmlTextWriterWriteBinHex(xmlTextWriterPtr writer, const char *data,
Daniel Veillard1d211e22003-10-20 22:32:39 +00001644 int start, int len)
1645{
1646 int count;
1647 int sum;
1648 xmlLinkPtr lk;
1649 xmlTextWriterStackEntry *p;
1650
Daniel Veillarde43cc572004-11-03 11:50:29 +00001651 if ((writer == NULL) || (data == NULL) || (start < 0) || (len < 0))
Daniel Veillard1d211e22003-10-20 22:32:39 +00001652 return -1;
1653
Daniel Veillard1d211e22003-10-20 22:32:39 +00001654 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001655 lk = xmlListFront(writer->nodes);
1656 if (lk != 0) {
1657 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1658 if (p != 0) {
1659 count = xmlTextWriterHandleStateDependencies(writer, p);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001660 if (count < 0)
1661 return -1;
1662 sum += count;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001663 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001664 }
1665
Daniel Veillardab69f362004-02-17 11:40:32 +00001666 if (writer->indent)
1667 writer->doindent = 0;
1668
Daniel Veillard1d211e22003-10-20 22:32:39 +00001669 count =
1670 xmlOutputBufferWriteBinHex(writer->out, len,
1671 (unsigned char *) data + start);
1672 if (count < 0)
1673 return -1;
1674 sum += count;
1675
1676 return sum;
1677}
1678
1679/**
1680 * xmlTextWriterStartAttribute:
1681 * @writer: the xmlTextWriterPtr
1682 * @name: element name
1683 *
1684 * Start an xml attribute.
1685 *
1686 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1687 */
1688int
1689xmlTextWriterStartAttribute(xmlTextWriterPtr writer, const xmlChar * name)
1690{
1691 int count;
1692 int sum;
1693 xmlLinkPtr lk;
1694 xmlTextWriterStackEntry *p;
1695
1696 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1697 return -1;
1698
1699 sum = 0;
1700 lk = xmlListFront(writer->nodes);
1701 if (lk == 0)
1702 return -1;
1703
1704 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1705 if (p == 0)
1706 return -1;
1707
1708 switch (p->state) {
1709 case XML_TEXTWRITER_ATTRIBUTE:
1710 count = xmlTextWriterEndAttribute(writer);
1711 if (count < 0)
1712 return -1;
1713 sum += count;
1714 /* fallthrough */
1715 case XML_TEXTWRITER_NAME:
1716 count = xmlOutputBufferWriteString(writer->out, " ");
1717 if (count < 0)
1718 return -1;
1719 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00001720 count =
1721 xmlOutputBufferWriteString(writer->out,
1722 (const char *) name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001723 if (count < 0)
1724 return -1;
1725 sum += count;
1726 count = xmlOutputBufferWriteString(writer->out, "=");
1727 if (count < 0)
1728 return -1;
1729 sum += count;
1730 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
1731 if (count < 0)
1732 return -1;
1733 sum += count;
1734 p->state = XML_TEXTWRITER_ATTRIBUTE;
1735 break;
1736 default:
1737 return -1;
1738 }
1739
1740 return sum;
1741}
1742
1743/**
1744 * xmlTextWriterStartAttributeNS:
1745 * @writer: the xmlTextWriterPtr
1746 * @prefix: namespace prefix or NULL
1747 * @name: element local name
1748 * @namespaceURI: namespace URI or NULL
1749 *
1750 * Start an xml attribute with namespace support.
1751 *
1752 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1753 */
1754int
1755xmlTextWriterStartAttributeNS(xmlTextWriterPtr writer,
1756 const xmlChar * prefix, const xmlChar * name,
1757 const xmlChar * namespaceURI)
1758{
1759 int count;
1760 int sum;
1761 xmlChar *buf;
1762 xmlTextWriterNsStackEntry *p;
1763
1764 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1765 return -1;
1766
Daniel Veillard75e389d2005-07-29 22:02:24 +00001767 buf = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001768 if (prefix != 0) {
1769 buf = xmlStrdup(prefix);
1770 buf = xmlStrcat(buf, BAD_CAST ":");
1771 }
1772 buf = xmlStrcat(buf, name);
1773
1774 sum = 0;
1775 count = xmlTextWriterStartAttribute(writer, buf);
1776 xmlFree(buf);
1777 if (count < 0)
1778 return -1;
1779 sum += count;
1780
1781 if (namespaceURI != 0) {
1782 buf = xmlStrdup(BAD_CAST "xmlns");
1783 if (prefix != 0) {
1784 buf = xmlStrcat(buf, BAD_CAST ":");
1785 buf = xmlStrcat(buf, prefix);
1786 }
1787
1788 p = (xmlTextWriterNsStackEntry *)
1789 xmlMalloc(sizeof(xmlTextWriterNsStackEntry));
1790 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00001791 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00001792 "xmlTextWriterStartAttributeNS : out of memory!\n");
1793 return -1;
1794 }
1795
1796 p->prefix = buf;
1797 p->uri = xmlStrdup(namespaceURI);
1798 if (p->uri == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00001799 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00001800 "xmlTextWriterStartAttributeNS : out of memory!\n");
1801 xmlFree(p);
1802 return -1;
1803 }
1804 p->elem = xmlListFront(writer->nodes);
1805
1806 xmlListPushFront(writer->nsstack, p);
1807 }
1808
1809 return sum;
1810}
1811
1812/**
1813 * xmlTextWriterEndAttribute:
1814 * @writer: the xmlTextWriterPtr
1815 *
1816 * End the current xml element.
1817 *
1818 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1819 */
1820int
1821xmlTextWriterEndAttribute(xmlTextWriterPtr writer)
1822{
1823 int count;
1824 int sum;
1825 xmlLinkPtr lk;
1826 xmlTextWriterStackEntry *p;
1827 xmlTextWriterNsStackEntry *np;
1828
1829 if (writer == NULL)
1830 return -1;
1831
1832 lk = xmlListFront(writer->nodes);
1833 if (lk == 0) {
1834 xmlListDelete(writer->nsstack);
Daniel Veillarde43cc572004-11-03 11:50:29 +00001835 writer->nsstack = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001836 return -1;
1837 }
1838
1839 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1840 if (p == 0) {
1841 xmlListDelete(writer->nsstack);
Daniel Veillarde43cc572004-11-03 11:50:29 +00001842 writer->nsstack = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001843 return -1;
1844 }
1845
1846 sum = 0;
1847 switch (p->state) {
1848 case XML_TEXTWRITER_ATTRIBUTE:
1849 p->state = XML_TEXTWRITER_NAME;
1850
1851 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
1852 if (count < 0) {
1853 xmlListDelete(writer->nsstack);
Daniel Veillarde43cc572004-11-03 11:50:29 +00001854 writer->nsstack = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001855 return -1;
1856 }
1857 sum += count;
1858
1859 while (!xmlListEmpty(writer->nsstack)) {
Daniel Veillardbd8fb0a2005-02-21 13:49:46 +00001860 xmlChar *namespaceURI = NULL;
1861 xmlChar *prefix = NULL;
1862
Daniel Veillard1d211e22003-10-20 22:32:39 +00001863 lk = xmlListFront(writer->nsstack);
1864 np = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
Daniel Veillardbd8fb0a2005-02-21 13:49:46 +00001865
1866 if (np != 0) {
Daniel Veillard614fdc12005-02-23 14:05:37 +00001867 namespaceURI = xmlStrdup(np->uri);
1868 prefix = xmlStrdup(np->prefix);
Daniel Veillardbd8fb0a2005-02-21 13:49:46 +00001869 }
1870
1871 xmlListPopFront(writer->nsstack);
1872
Daniel Veillard1d211e22003-10-20 22:32:39 +00001873 if (np != 0) {
1874 count =
Daniel Veillardbd8fb0a2005-02-21 13:49:46 +00001875 xmlTextWriterWriteAttribute(writer, prefix,
1876 namespaceURI);
1877 xmlFree(namespaceURI);
1878 xmlFree(prefix);
1879
Daniel Veillard1d211e22003-10-20 22:32:39 +00001880 if (count < 0) {
1881 xmlListDelete(writer->nsstack);
Daniel Veillarde43cc572004-11-03 11:50:29 +00001882 writer->nsstack = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001883 return -1;
1884 }
1885 sum += count;
1886 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001887 }
1888 break;
1889
1890 default:
1891 xmlListClear(writer->nsstack);
1892 return -1;
1893 }
1894
1895 return sum;
1896}
1897
1898/**
1899 * xmlTextWriterWriteFormatAttribute:
1900 * @writer: the xmlTextWriterPtr
1901 * @name: attribute name
1902 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001903 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001904 *
1905 * Write a formatted xml attribute.
1906 *
1907 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1908 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00001909int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00001910xmlTextWriterWriteFormatAttribute(xmlTextWriterPtr writer,
1911 const xmlChar * name, const char *format,
1912 ...)
1913{
1914 int rc;
1915 va_list ap;
1916
1917 va_start(ap, format);
1918
1919 rc = xmlTextWriterWriteVFormatAttribute(writer, name, format, ap);
1920
1921 va_end(ap);
1922 return rc;
1923}
1924
1925/**
1926 * xmlTextWriterWriteVFormatAttribute:
1927 * @writer: the xmlTextWriterPtr
1928 * @name: attribute name
1929 * @format: format string (see printf)
1930 * @argptr: pointer to the first member of the variable argument list.
1931 *
1932 * Write a formatted xml attribute.
1933 *
1934 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1935 */
1936int
1937xmlTextWriterWriteVFormatAttribute(xmlTextWriterPtr writer,
1938 const xmlChar * name,
1939 const char *format, va_list argptr)
1940{
1941 int rc;
1942 xmlChar *buf;
1943
1944 if (writer == NULL)
1945 return -1;
1946
1947 buf = xmlTextWriterVSprintf(format, argptr);
1948 if (buf == 0)
1949 return 0;
1950
1951 rc = xmlTextWriterWriteAttribute(writer, name, buf);
1952
1953 xmlFree(buf);
1954 return rc;
1955}
1956
1957/**
1958 * xmlTextWriterWriteAttribute:
1959 * @writer: the xmlTextWriterPtr
1960 * @name: attribute name
1961 * @content: attribute content
1962 *
1963 * Write an xml attribute.
1964 *
1965 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1966 */
1967int
1968xmlTextWriterWriteAttribute(xmlTextWriterPtr writer, const xmlChar * name,
1969 const xmlChar * content)
1970{
1971 int count;
1972 int sum;
1973
1974 sum = 0;
1975 count = xmlTextWriterStartAttribute(writer, name);
1976 if (count < 0)
1977 return -1;
1978 sum += count;
1979 count = xmlTextWriterWriteString(writer, content);
1980 if (count < 0)
1981 return -1;
1982 sum += count;
1983 count = xmlTextWriterEndAttribute(writer);
1984 if (count < 0)
1985 return -1;
1986 sum += count;
1987
1988 return sum;
1989}
1990
1991/**
1992 * xmlTextWriterWriteFormatAttributeNS:
1993 * @writer: the xmlTextWriterPtr
1994 * @prefix: namespace prefix
1995 * @name: attribute local name
1996 * @namespaceURI: namespace URI
1997 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001998 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001999 *
2000 * Write a formatted xml attribute.with namespace support
2001 *
2002 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2003 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00002004int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00002005xmlTextWriterWriteFormatAttributeNS(xmlTextWriterPtr writer,
2006 const xmlChar * prefix,
2007 const xmlChar * name,
2008 const xmlChar * namespaceURI,
2009 const char *format, ...)
2010{
2011 int rc;
2012 va_list ap;
2013
2014 va_start(ap, format);
2015
2016 rc = xmlTextWriterWriteVFormatAttributeNS(writer, prefix, name,
2017 namespaceURI, format, ap);
2018
2019 va_end(ap);
2020 return rc;
2021}
2022
2023/**
2024 * xmlTextWriterWriteVFormatAttributeNS:
2025 * @writer: the xmlTextWriterPtr
2026 * @prefix: namespace prefix
2027 * @name: attribute local name
2028 * @namespaceURI: namespace URI
2029 * @format: format string (see printf)
2030 * @argptr: pointer to the first member of the variable argument list.
2031 *
2032 * Write a formatted xml attribute.with namespace support
2033 *
2034 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2035 */
2036int
2037xmlTextWriterWriteVFormatAttributeNS(xmlTextWriterPtr writer,
2038 const xmlChar * prefix,
2039 const xmlChar * name,
2040 const xmlChar * namespaceURI,
2041 const char *format, va_list argptr)
2042{
2043 int rc;
2044 xmlChar *buf;
2045
2046 if (writer == NULL)
2047 return -1;
2048
2049 buf = xmlTextWriterVSprintf(format, argptr);
2050 if (buf == 0)
2051 return 0;
2052
2053 rc = xmlTextWriterWriteAttributeNS(writer, prefix, name, namespaceURI,
2054 buf);
2055
2056 xmlFree(buf);
2057 return rc;
2058}
2059
2060/**
2061 * xmlTextWriterWriteAttributeNS:
2062 * @writer: the xmlTextWriterPtr
2063 * @prefix: namespace prefix
2064 * @name: attribute local name
2065 * @namespaceURI: namespace URI
2066 * @content: attribute content
2067 *
2068 * Write an xml attribute.
2069 *
2070 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2071 */
2072int
2073xmlTextWriterWriteAttributeNS(xmlTextWriterPtr writer,
2074 const xmlChar * prefix, const xmlChar * name,
2075 const xmlChar * namespaceURI,
2076 const xmlChar * content)
2077{
2078 int count;
2079 int sum;
2080 xmlChar *buf;
2081
2082 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
2083 return -1;
2084
Daniel Veillard75e389d2005-07-29 22:02:24 +00002085 buf = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002086 if (prefix != NULL) {
2087 buf = xmlStrdup(prefix);
2088 buf = xmlStrcat(buf, BAD_CAST ":");
2089 }
2090 buf = xmlStrcat(buf, name);
2091
2092 sum = 0;
2093 count = xmlTextWriterWriteAttribute(writer, buf, content);
2094 xmlFree(buf);
2095 if (count < 0)
2096 return -1;
2097 sum += count;
2098
2099 if (namespaceURI != NULL) {
Daniel Veillard75e389d2005-07-29 22:02:24 +00002100 buf = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002101 buf = xmlStrdup(BAD_CAST "xmlns");
2102 if (prefix != NULL) {
2103 buf = xmlStrcat(buf, BAD_CAST ":");
2104 buf = xmlStrcat(buf, prefix);
2105 }
2106 count = xmlTextWriterWriteAttribute(writer, buf, namespaceURI);
2107 xmlFree(buf);
2108 if (count < 0)
2109 return -1;
2110 sum += count;
2111 }
2112 return sum;
2113}
2114
2115/**
2116 * xmlTextWriterWriteFormatElement:
2117 * @writer: the xmlTextWriterPtr
2118 * @name: element name
2119 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002120 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002121 *
2122 * Write a formatted xml element.
2123 *
2124 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2125 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00002126int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00002127xmlTextWriterWriteFormatElement(xmlTextWriterPtr writer,
2128 const xmlChar * name, const char *format,
2129 ...)
2130{
2131 int rc;
2132 va_list ap;
2133
2134 va_start(ap, format);
2135
2136 rc = xmlTextWriterWriteVFormatElement(writer, name, format, ap);
2137
2138 va_end(ap);
2139 return rc;
2140}
2141
2142/**
2143 * xmlTextWriterWriteVFormatElement:
2144 * @writer: the xmlTextWriterPtr
2145 * @name: element name
2146 * @format: format string (see printf)
2147 * @argptr: pointer to the first member of the variable argument list.
2148 *
2149 * Write a formatted xml element.
2150 *
2151 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2152 */
2153int
2154xmlTextWriterWriteVFormatElement(xmlTextWriterPtr writer,
2155 const xmlChar * name, const char *format,
2156 va_list argptr)
2157{
2158 int rc;
2159 xmlChar *buf;
2160
2161 if (writer == NULL)
2162 return -1;
2163
2164 buf = xmlTextWriterVSprintf(format, argptr);
2165 if (buf == 0)
2166 return 0;
2167
2168 rc = xmlTextWriterWriteElement(writer, name, buf);
2169
2170 xmlFree(buf);
2171 return rc;
2172}
2173
2174/**
2175 * xmlTextWriterWriteElement:
2176 * @writer: the xmlTextWriterPtr
2177 * @name: element name
2178 * @content: element content
2179 *
2180 * Write an xml element.
2181 *
2182 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2183 */
2184int
2185xmlTextWriterWriteElement(xmlTextWriterPtr writer, const xmlChar * name,
2186 const xmlChar * content)
2187{
2188 int count;
2189 int sum;
2190
2191 sum = 0;
2192 count = xmlTextWriterStartElement(writer, name);
2193 if (count == -1)
2194 return -1;
2195 sum += count;
2196 count = xmlTextWriterWriteString(writer, content);
2197 if (count == -1)
2198 return -1;
2199 sum += count;
2200 count = xmlTextWriterEndElement(writer);
2201 if (count == -1)
2202 return -1;
2203 sum += count;
2204
2205 return sum;
2206}
2207
2208/**
2209 * xmlTextWriterWriteFormatElementNS:
2210 * @writer: the xmlTextWriterPtr
2211 * @prefix: namespace prefix
2212 * @name: element local name
2213 * @namespaceURI: namespace URI
2214 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002215 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002216 *
2217 * Write a formatted xml element with namespace support.
2218 *
2219 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2220 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00002221int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00002222xmlTextWriterWriteFormatElementNS(xmlTextWriterPtr writer,
2223 const xmlChar * prefix,
2224 const xmlChar * name,
2225 const xmlChar * namespaceURI,
2226 const char *format, ...)
2227{
2228 int rc;
2229 va_list ap;
2230
2231 va_start(ap, format);
2232
2233 rc = xmlTextWriterWriteVFormatElementNS(writer, prefix, name,
2234 namespaceURI, format, ap);
2235
2236 va_end(ap);
2237 return rc;
2238}
2239
2240/**
2241 * xmlTextWriterWriteVFormatElementNS:
2242 * @writer: the xmlTextWriterPtr
2243 * @prefix: namespace prefix
2244 * @name: element local name
2245 * @namespaceURI: namespace URI
2246 * @format: format string (see printf)
2247 * @argptr: pointer to the first member of the variable argument list.
2248 *
2249 * Write a formatted xml element with namespace support.
2250 *
2251 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2252 */
2253int
2254xmlTextWriterWriteVFormatElementNS(xmlTextWriterPtr writer,
2255 const xmlChar * prefix,
2256 const xmlChar * name,
2257 const xmlChar * namespaceURI,
2258 const char *format, va_list argptr)
2259{
2260 int rc;
2261 xmlChar *buf;
2262
2263 if (writer == NULL)
2264 return -1;
2265
2266 buf = xmlTextWriterVSprintf(format, argptr);
2267 if (buf == 0)
2268 return 0;
2269
2270 rc = xmlTextWriterWriteElementNS(writer, prefix, name, namespaceURI,
2271 buf);
2272
2273 xmlFree(buf);
2274 return rc;
2275}
2276
2277/**
2278 * xmlTextWriterWriteElementNS:
2279 * @writer: the xmlTextWriterPtr
2280 * @prefix: namespace prefix
2281 * @name: element local name
2282 * @namespaceURI: namespace URI
2283 * @content: element content
2284 *
2285 * Write an xml element with namespace support.
2286 *
2287 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2288 */
2289int
2290xmlTextWriterWriteElementNS(xmlTextWriterPtr writer,
2291 const xmlChar * prefix, const xmlChar * name,
2292 const xmlChar * namespaceURI,
2293 const xmlChar * content)
2294{
2295 int count;
2296 int sum;
2297
2298 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
2299 return -1;
2300
2301 sum = 0;
2302 count =
2303 xmlTextWriterStartElementNS(writer, prefix, name, namespaceURI);
2304 if (count < 0)
2305 return -1;
2306 sum += count;
2307 count = xmlTextWriterWriteString(writer, content);
2308 if (count == -1)
2309 return -1;
2310 sum += count;
2311 count = xmlTextWriterEndElement(writer);
2312 if (count == -1)
2313 return -1;
2314 sum += count;
2315
2316 return sum;
2317}
2318
2319/**
2320 * xmlTextWriterStartPI:
2321 * @writer: the xmlTextWriterPtr
2322 * @target: PI target
2323 *
2324 * Start an xml PI.
2325 *
2326 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2327 */
2328int
2329xmlTextWriterStartPI(xmlTextWriterPtr writer, const xmlChar * target)
2330{
2331 int count;
2332 int sum;
2333 xmlLinkPtr lk;
2334 xmlTextWriterStackEntry *p;
2335
2336 if ((writer == NULL) || (target == NULL) || (*target == '\0'))
2337 return -1;
2338
2339 if (xmlStrcasecmp(target, (const xmlChar *) "xml") == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002340 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002341 "xmlTextWriterStartPI : target name [Xx][Mm][Ll] is reserved for xml standardization!\n");
2342 return -1;
2343 }
2344
2345 sum = 0;
2346 lk = xmlListFront(writer->nodes);
2347 if (lk != 0) {
2348 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2349 if (p != 0) {
2350 switch (p->state) {
2351 case XML_TEXTWRITER_ATTRIBUTE:
2352 count = xmlTextWriterEndAttribute(writer);
2353 if (count < 0)
2354 return -1;
2355 sum += count;
2356 /* fallthrough */
2357 case XML_TEXTWRITER_NAME:
2358 count = xmlOutputBufferWriteString(writer->out, ">");
2359 if (count < 0)
2360 return -1;
2361 sum += count;
2362 p->state = XML_TEXTWRITER_TEXT;
2363 break;
Daniel Veillardab69f362004-02-17 11:40:32 +00002364 case XML_TEXTWRITER_NONE:
2365 case XML_TEXTWRITER_TEXT:
2366 case XML_TEXTWRITER_DTD:
2367 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002368 case XML_TEXTWRITER_PI:
2369 case XML_TEXTWRITER_PI_TEXT:
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002370 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002371 "xmlTextWriterStartPI : nested PI!\n");
2372 return -1;
2373 default:
2374 return -1;
2375 }
2376 }
2377 }
2378
2379 p = (xmlTextWriterStackEntry *)
2380 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2381 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002382 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002383 "xmlTextWriterStartPI : out of memory!\n");
2384 return -1;
2385 }
2386
2387 p->name = xmlStrdup(target);
2388 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002389 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002390 "xmlTextWriterStartPI : out of memory!\n");
2391 xmlFree(p);
2392 return -1;
2393 }
2394 p->state = XML_TEXTWRITER_PI;
2395
2396 xmlListPushFront(writer->nodes, p);
2397
2398 count = xmlOutputBufferWriteString(writer->out, "<?");
2399 if (count < 0)
2400 return -1;
2401 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002402 count =
2403 xmlOutputBufferWriteString(writer->out, (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002404 if (count < 0)
2405 return -1;
2406 sum += count;
2407
2408 return sum;
2409}
2410
2411/**
2412 * xmlTextWriterEndPI:
2413 * @writer: the xmlTextWriterPtr
2414 *
2415 * End the current xml PI.
2416 *
2417 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2418 */
2419int
2420xmlTextWriterEndPI(xmlTextWriterPtr writer)
2421{
2422 int count;
2423 int sum;
2424 xmlLinkPtr lk;
2425 xmlTextWriterStackEntry *p;
2426
2427 if (writer == NULL)
2428 return -1;
2429
2430 lk = xmlListFront(writer->nodes);
2431 if (lk == 0)
2432 return 0;
2433
2434 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2435 if (p == 0)
2436 return 0;
2437
2438 sum = 0;
2439 switch (p->state) {
2440 case XML_TEXTWRITER_PI:
2441 case XML_TEXTWRITER_PI_TEXT:
2442 count = xmlOutputBufferWriteString(writer->out, "?>");
2443 if (count < 0)
2444 return -1;
2445 sum += count;
2446 break;
2447 default:
2448 return -1;
2449 }
2450
2451 xmlListPopFront(writer->nodes);
2452 return sum;
2453}
2454
2455/**
2456 * xmlTextWriterWriteFormatPI:
2457 * @writer: the xmlTextWriterPtr
2458 * @target: PI target
2459 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002460 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002461 *
2462 * Write a formatted PI.
2463 *
2464 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2465 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00002466int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00002467xmlTextWriterWriteFormatPI(xmlTextWriterPtr writer, const xmlChar * target,
2468 const char *format, ...)
2469{
2470 int rc;
2471 va_list ap;
2472
2473 va_start(ap, format);
2474
2475 rc = xmlTextWriterWriteVFormatPI(writer, target, format, ap);
2476
2477 va_end(ap);
2478 return rc;
2479}
2480
2481/**
2482 * xmlTextWriterWriteVFormatPI:
2483 * @writer: the xmlTextWriterPtr
2484 * @target: PI target
2485 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002486 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00002487 *
2488 * Write a formatted xml PI.
2489 *
2490 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2491 */
2492int
2493xmlTextWriterWriteVFormatPI(xmlTextWriterPtr writer,
2494 const xmlChar * target, const char *format,
2495 va_list argptr)
2496{
2497 int rc;
2498 xmlChar *buf;
2499
2500 if (writer == NULL)
2501 return -1;
2502
2503 buf = xmlTextWriterVSprintf(format, argptr);
2504 if (buf == 0)
2505 return 0;
2506
2507 rc = xmlTextWriterWritePI(writer, target, buf);
2508
2509 xmlFree(buf);
2510 return rc;
2511}
2512
2513/**
2514 * xmlTextWriterWritePI:
2515 * @writer: the xmlTextWriterPtr
2516 * @target: PI target
2517 * @content: PI content
2518 *
2519 * Write an xml PI.
2520 *
2521 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2522 */
2523int
2524xmlTextWriterWritePI(xmlTextWriterPtr writer, const xmlChar * target,
2525 const xmlChar * content)
2526{
2527 int count;
2528 int sum;
2529
2530 sum = 0;
2531 count = xmlTextWriterStartPI(writer, target);
2532 if (count == -1)
2533 return -1;
2534 sum += count;
2535 if (content != 0) {
2536 count = xmlTextWriterWriteString(writer, content);
2537 if (count == -1)
2538 return -1;
2539 sum += count;
2540 }
2541 count = xmlTextWriterEndPI(writer);
2542 if (count == -1)
2543 return -1;
2544 sum += count;
2545
2546 return sum;
2547}
2548
2549/**
2550 * xmlTextWriterStartCDATA:
2551 * @writer: the xmlTextWriterPtr
2552 *
2553 * Start an xml CDATA section.
2554 *
2555 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2556 */
2557int
2558xmlTextWriterStartCDATA(xmlTextWriterPtr writer)
2559{
2560 int count;
2561 int sum;
2562 xmlLinkPtr lk;
2563 xmlTextWriterStackEntry *p;
2564
2565 if (writer == NULL)
2566 return -1;
2567
2568 sum = 0;
2569 lk = xmlListFront(writer->nodes);
2570 if (lk != 0) {
2571 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2572 if (p != 0) {
2573 switch (p->state) {
2574 case XML_TEXTWRITER_NONE:
2575 case XML_TEXTWRITER_PI:
2576 case XML_TEXTWRITER_PI_TEXT:
2577 break;
2578 case XML_TEXTWRITER_ATTRIBUTE:
2579 count = xmlTextWriterEndAttribute(writer);
2580 if (count < 0)
2581 return -1;
2582 sum += count;
2583 /* fallthrough */
2584 case XML_TEXTWRITER_NAME:
2585 count = xmlOutputBufferWriteString(writer->out, ">");
2586 if (count < 0)
2587 return -1;
2588 sum += count;
2589 p->state = XML_TEXTWRITER_TEXT;
2590 break;
2591 case XML_TEXTWRITER_CDATA:
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002592 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002593 "xmlTextWriterStartCDATA : CDATA not allowed in this context!\n");
2594 return -1;
2595 default:
2596 return -1;
2597 }
2598 }
2599 }
2600
2601 p = (xmlTextWriterStackEntry *)
2602 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2603 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002604 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002605 "xmlTextWriterStartCDATA : out of memory!\n");
2606 return -1;
2607 }
2608
Daniel Veillard75e389d2005-07-29 22:02:24 +00002609 p->name = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002610 p->state = XML_TEXTWRITER_CDATA;
2611
2612 xmlListPushFront(writer->nodes, p);
2613
2614 count = xmlOutputBufferWriteString(writer->out, "<![CDATA[");
2615 if (count < 0)
2616 return -1;
2617 sum += count;
2618
2619 return sum;
2620}
2621
2622/**
2623 * xmlTextWriterEndCDATA:
2624 * @writer: the xmlTextWriterPtr
2625 *
2626 * End an xml CDATA section.
2627 *
2628 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2629 */
2630int
2631xmlTextWriterEndCDATA(xmlTextWriterPtr writer)
2632{
2633 int count;
2634 int sum;
2635 xmlLinkPtr lk;
2636 xmlTextWriterStackEntry *p;
2637
2638 if (writer == NULL)
2639 return -1;
2640
2641 lk = xmlListFront(writer->nodes);
2642 if (lk == 0)
2643 return -1;
2644
2645 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2646 if (p == 0)
2647 return -1;
2648
2649 sum = 0;
2650 switch (p->state) {
2651 case XML_TEXTWRITER_CDATA:
2652 count = xmlOutputBufferWriteString(writer->out, "]]>");
2653 if (count < 0)
2654 return -1;
2655 sum += count;
2656 break;
2657 default:
2658 return -1;
2659 }
2660
2661 xmlListPopFront(writer->nodes);
2662 return sum;
2663}
2664
2665/**
2666 * xmlTextWriterWriteFormatCDATA:
2667 * @writer: the xmlTextWriterPtr
2668 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002669 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002670 *
2671 * Write a formatted xml CDATA.
2672 *
2673 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2674 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00002675int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00002676xmlTextWriterWriteFormatCDATA(xmlTextWriterPtr writer, const char *format,
2677 ...)
2678{
2679 int rc;
2680 va_list ap;
2681
2682 va_start(ap, format);
2683
2684 rc = xmlTextWriterWriteVFormatCDATA(writer, format, ap);
2685
2686 va_end(ap);
2687 return rc;
2688}
2689
2690/**
2691 * xmlTextWriterWriteVFormatCDATA:
2692 * @writer: the xmlTextWriterPtr
2693 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002694 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00002695 *
2696 * Write a formatted xml CDATA.
2697 *
2698 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2699 */
2700int
2701xmlTextWriterWriteVFormatCDATA(xmlTextWriterPtr writer, const char *format,
2702 va_list argptr)
2703{
2704 int rc;
2705 xmlChar *buf;
2706
2707 if (writer == NULL)
2708 return -1;
2709
2710 buf = xmlTextWriterVSprintf(format, argptr);
2711 if (buf == 0)
2712 return 0;
2713
2714 rc = xmlTextWriterWriteCDATA(writer, buf);
2715
2716 xmlFree(buf);
2717 return rc;
2718}
2719
2720/**
2721 * xmlTextWriterWriteCDATA:
2722 * @writer: the xmlTextWriterPtr
2723 * @content: CDATA content
2724 *
2725 * Write an xml CDATA.
2726 *
2727 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2728 */
2729int
2730xmlTextWriterWriteCDATA(xmlTextWriterPtr writer, const xmlChar * content)
2731{
2732 int count;
2733 int sum;
2734
2735 sum = 0;
2736 count = xmlTextWriterStartCDATA(writer);
2737 if (count == -1)
2738 return -1;
2739 sum += count;
2740 if (content != 0) {
2741 count = xmlTextWriterWriteString(writer, content);
2742 if (count == -1)
2743 return -1;
2744 sum += count;
2745 }
2746 count = xmlTextWriterEndCDATA(writer);
2747 if (count == -1)
2748 return -1;
2749 sum += count;
2750
2751 return sum;
2752}
2753
2754/**
2755 * xmlTextWriterStartDTD:
2756 * @writer: the xmlTextWriterPtr
2757 * @name: the name of the DTD
2758 * @pubid: the public identifier, which is an alternative to the system identifier
2759 * @sysid: the system identifier, which is the URI of the DTD
2760 *
2761 * Start an xml DTD.
2762 *
2763 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2764 */
2765int
2766xmlTextWriterStartDTD(xmlTextWriterPtr writer,
2767 const xmlChar * name,
2768 const xmlChar * pubid, const xmlChar * sysid)
2769{
2770 int count;
2771 int sum;
2772 xmlLinkPtr lk;
2773 xmlTextWriterStackEntry *p;
2774
2775 if (writer == NULL || name == NULL || *name == '\0')
2776 return -1;
2777
2778 sum = 0;
2779 lk = xmlListFront(writer->nodes);
Daniel Veillardab69f362004-02-17 11:40:32 +00002780 if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002781 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002782 "xmlTextWriterStartDTD : DTD allowed only in prolog!\n");
2783 return -1;
2784 }
2785
2786 p = (xmlTextWriterStackEntry *)
2787 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2788 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002789 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002790 "xmlTextWriterStartDTD : out of memory!\n");
2791 return -1;
2792 }
2793
2794 p->name = xmlStrdup(name);
2795 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002796 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002797 "xmlTextWriterStartDTD : out of memory!\n");
2798 xmlFree(p);
2799 return -1;
2800 }
2801 p->state = XML_TEXTWRITER_DTD;
2802
2803 xmlListPushFront(writer->nodes, p);
2804
2805 count = xmlOutputBufferWriteString(writer->out, "<!DOCTYPE ");
2806 if (count < 0)
2807 return -1;
2808 sum += count;
2809 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
2810 if (count < 0)
2811 return -1;
2812 sum += count;
2813
2814 if (pubid != 0) {
2815 if (sysid == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002816 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002817 "xmlTextWriterStartDTD : system identifier needed!\n");
2818 return -1;
2819 }
2820
Daniel Veillard500a1de2004-03-22 15:22:58 +00002821 if (writer->indent)
2822 count = xmlOutputBufferWrite(writer->out, 1, "\n");
2823 else
2824 count = xmlOutputBufferWrite(writer->out, 1, " ");
2825 if (count < 0)
2826 return -1;
2827 sum += count;
2828
2829 count = xmlOutputBufferWriteString(writer->out, "PUBLIC ");
2830 if (count < 0)
2831 return -1;
2832 sum += count;
2833
2834 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002835 if (count < 0)
2836 return -1;
2837 sum += count;
2838
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002839 count =
2840 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002841 if (count < 0)
2842 return -1;
2843 sum += count;
2844
Daniel Veillard500a1de2004-03-22 15:22:58 +00002845 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002846 if (count < 0)
2847 return -1;
2848 sum += count;
2849 }
2850
2851 if (sysid != 0) {
2852 if (pubid == 0) {
Daniel Veillard500a1de2004-03-22 15:22:58 +00002853 if (writer->indent)
2854 count = xmlOutputBufferWrite(writer->out, 1, "\n");
2855 else
2856 count = xmlOutputBufferWrite(writer->out, 1, " ");
2857 if (count < 0)
2858 return -1;
2859 sum += count;
2860 count = xmlOutputBufferWriteString(writer->out, "SYSTEM ");
2861 if (count < 0)
2862 return -1;
2863 sum += count;
2864 } else if (writer->indent) {
2865 count = xmlOutputBufferWriteString(writer->out, "\n ");
Daniel Veillard1d211e22003-10-20 22:32:39 +00002866 if (count < 0)
2867 return -1;
2868 sum += count;
2869 }
2870
Daniel Veillard500a1de2004-03-22 15:22:58 +00002871 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002872 if (count < 0)
2873 return -1;
2874 sum += count;
2875
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002876 count =
2877 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002878 if (count < 0)
2879 return -1;
2880 sum += count;
2881
Daniel Veillard500a1de2004-03-22 15:22:58 +00002882 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002883 if (count < 0)
2884 return -1;
2885 sum += count;
2886 }
2887
2888 return sum;
2889}
2890
2891/**
2892 * xmlTextWriterEndDTD:
2893 * @writer: the xmlTextWriterPtr
2894 *
2895 * End an xml DTD.
2896 *
2897 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2898 */
2899int
2900xmlTextWriterEndDTD(xmlTextWriterPtr writer)
2901{
Daniel Veillard500a1de2004-03-22 15:22:58 +00002902 int loop;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002903 int count;
2904 int sum;
2905 xmlLinkPtr lk;
2906 xmlTextWriterStackEntry *p;
2907
2908 if (writer == NULL)
2909 return -1;
2910
2911 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00002912 loop = 1;
2913 while (loop) {
2914 lk = xmlListFront(writer->nodes);
2915 if (lk == NULL)
Daniel Veillard1d211e22003-10-20 22:32:39 +00002916 break;
Daniel Veillard500a1de2004-03-22 15:22:58 +00002917 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2918 if (p == 0)
2919 break;
2920 switch (p->state) {
2921 case XML_TEXTWRITER_DTD_TEXT:
2922 count = xmlOutputBufferWriteString(writer->out, "]");
2923 if (count < 0)
2924 return -1;
2925 sum += count;
2926 /* fallthrough */
2927 case XML_TEXTWRITER_DTD:
2928 count = xmlOutputBufferWriteString(writer->out, ">");
2929
2930 if (writer->indent) {
2931 if (count < 0)
2932 return -1;
2933 sum += count;
2934 count = xmlOutputBufferWriteString(writer->out, "\n");
2935 }
2936
2937 xmlListPopFront(writer->nodes);
2938 break;
2939 case XML_TEXTWRITER_DTD_ELEM:
2940 case XML_TEXTWRITER_DTD_ELEM_TEXT:
2941 count = xmlTextWriterEndDTDElement(writer);
2942 break;
2943 case XML_TEXTWRITER_DTD_ATTL:
2944 case XML_TEXTWRITER_DTD_ATTL_TEXT:
2945 count = xmlTextWriterEndDTDAttlist(writer);
2946 break;
2947 case XML_TEXTWRITER_DTD_ENTY:
2948 case XML_TEXTWRITER_DTD_PENT:
2949 case XML_TEXTWRITER_DTD_ENTY_TEXT:
2950 count = xmlTextWriterEndDTDEntity(writer);
2951 break;
2952 case XML_TEXTWRITER_COMMENT:
2953 count = xmlTextWriterEndComment(writer);
2954 break;
2955 default:
2956 loop = 0;
2957 continue;
2958 }
2959
2960 if (count < 0)
Daniel Veillard1d211e22003-10-20 22:32:39 +00002961 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00002962 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002963 }
2964
Daniel Veillard1d211e22003-10-20 22:32:39 +00002965 return sum;
2966}
2967
2968/**
2969 * xmlTextWriterWriteFormatDTD:
2970 * @writer: the xmlTextWriterPtr
2971 * @name: the name of the DTD
2972 * @pubid: the public identifier, which is an alternative to the system identifier
2973 * @sysid: the system identifier, which is the URI of the DTD
2974 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002975 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002976 *
2977 * Write a DTD with a formatted markup declarations part.
2978 *
2979 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2980 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00002981int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00002982xmlTextWriterWriteFormatDTD(xmlTextWriterPtr writer,
2983 const xmlChar * name,
2984 const xmlChar * pubid,
2985 const xmlChar * sysid, const char *format, ...)
2986{
2987 int rc;
2988 va_list ap;
2989
2990 va_start(ap, format);
2991
2992 rc = xmlTextWriterWriteVFormatDTD(writer, name, pubid, sysid, format,
2993 ap);
2994
2995 va_end(ap);
2996 return rc;
2997}
2998
2999/**
3000 * xmlTextWriterWriteVFormatDTD:
3001 * @writer: the xmlTextWriterPtr
3002 * @name: the name of the DTD
3003 * @pubid: the public identifier, which is an alternative to the system identifier
3004 * @sysid: the system identifier, which is the URI of the DTD
3005 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003006 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00003007 *
3008 * Write a DTD with a formatted markup declarations part.
3009 *
3010 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3011 */
3012int
3013xmlTextWriterWriteVFormatDTD(xmlTextWriterPtr writer,
3014 const xmlChar * name,
3015 const xmlChar * pubid,
3016 const xmlChar * sysid,
3017 const char *format, va_list argptr)
3018{
3019 int rc;
3020 xmlChar *buf;
3021
3022 if (writer == NULL)
3023 return -1;
3024
3025 buf = xmlTextWriterVSprintf(format, argptr);
3026 if (buf == 0)
3027 return 0;
3028
3029 rc = xmlTextWriterWriteDTD(writer, name, pubid, sysid, buf);
3030
3031 xmlFree(buf);
3032 return rc;
3033}
3034
3035/**
3036 * xmlTextWriterWriteDTD:
3037 * @writer: the xmlTextWriterPtr
3038 * @name: the name of the DTD
3039 * @pubid: the public identifier, which is an alternative to the system identifier
3040 * @sysid: the system identifier, which is the URI of the DTD
William M. Brackb1d53162003-11-18 06:54:40 +00003041 * @subset: string content of the DTD
Daniel Veillard1d211e22003-10-20 22:32:39 +00003042 *
3043 * Write a DTD.
3044 *
3045 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3046 */
3047int
3048xmlTextWriterWriteDTD(xmlTextWriterPtr writer,
3049 const xmlChar * name,
3050 const xmlChar * pubid,
3051 const xmlChar * sysid, const xmlChar * subset)
3052{
3053 int count;
3054 int sum;
3055
3056 sum = 0;
3057 count = xmlTextWriterStartDTD(writer, name, pubid, sysid);
3058 if (count == -1)
3059 return -1;
3060 sum += count;
3061 if (subset != 0) {
3062 count = xmlTextWriterWriteString(writer, subset);
3063 if (count == -1)
3064 return -1;
3065 sum += count;
3066 }
3067 count = xmlTextWriterEndDTD(writer);
3068 if (count == -1)
3069 return -1;
3070 sum += count;
3071
3072 return sum;
3073}
3074
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003075/**
3076 * xmlTextWriterStartDTDElement:
3077 * @writer: the xmlTextWriterPtr
3078 * @name: the name of the DTD element
3079 *
3080 * Start an xml DTD element.
3081 *
3082 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3083 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003084int
3085xmlTextWriterStartDTDElement(xmlTextWriterPtr writer, const xmlChar * name)
3086{
3087 int count;
3088 int sum;
3089 xmlLinkPtr lk;
3090 xmlTextWriterStackEntry *p;
3091
3092 if (writer == NULL || name == NULL || *name == '\0')
3093 return -1;
3094
3095 sum = 0;
3096 lk = xmlListFront(writer->nodes);
3097 if (lk == 0) {
3098 return -1;
3099 }
3100
3101 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
Daniel Veillard500a1de2004-03-22 15:22:58 +00003102 if (p != 0) {
3103 switch (p->state) {
3104 case XML_TEXTWRITER_DTD:
3105 count = xmlOutputBufferWriteString(writer->out, " [");
3106 if (count < 0)
3107 return -1;
3108 sum += count;
3109 if (writer->indent) {
3110 count = xmlOutputBufferWriteString(writer->out, "\n");
3111 if (count < 0)
3112 return -1;
3113 sum += count;
3114 }
3115 p->state = XML_TEXTWRITER_DTD_TEXT;
3116 /* fallthrough */
3117 case XML_TEXTWRITER_DTD_TEXT:
3118 case XML_TEXTWRITER_NONE:
3119 break;
3120 default:
Daniel Veillard1d211e22003-10-20 22:32:39 +00003121 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00003122 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00003123 }
3124
3125 p = (xmlTextWriterStackEntry *)
3126 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3127 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003128 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003129 "xmlTextWriterStartDTDElement : out of memory!\n");
3130 return -1;
3131 }
3132
3133 p->name = xmlStrdup(name);
3134 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003135 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003136 "xmlTextWriterStartDTDElement : out of memory!\n");
3137 xmlFree(p);
3138 return -1;
3139 }
3140 p->state = XML_TEXTWRITER_DTD_ELEM;
3141
3142 xmlListPushFront(writer->nodes, p);
3143
Daniel Veillard500a1de2004-03-22 15:22:58 +00003144 if (writer->indent) {
3145 count = xmlTextWriterWriteIndent(writer);
3146 if (count < 0)
3147 return -1;
3148 sum += count;
3149 }
3150
Daniel Veillard1d211e22003-10-20 22:32:39 +00003151 count = xmlOutputBufferWriteString(writer->out, "<!ELEMENT ");
3152 if (count < 0)
3153 return -1;
3154 sum += count;
3155 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
3156 if (count < 0)
3157 return -1;
3158 sum += count;
3159
3160 return sum;
3161}
3162
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003163/**
Daniel Veillard500a1de2004-03-22 15:22:58 +00003164 * xmlTextWriterEndDTDElement:
3165 * @writer: the xmlTextWriterPtr
3166 *
3167 * End an xml DTD element.
3168 *
3169 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3170 */
3171int
3172xmlTextWriterEndDTDElement(xmlTextWriterPtr writer)
3173{
3174 int count;
3175 int sum;
3176 xmlLinkPtr lk;
3177 xmlTextWriterStackEntry *p;
3178
3179 if (writer == NULL)
3180 return -1;
3181
3182 sum = 0;
3183 lk = xmlListFront(writer->nodes);
3184 if (lk == 0)
3185 return -1;
3186
3187 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3188 if (p == 0)
3189 return -1;
3190
3191 switch (p->state) {
3192 case XML_TEXTWRITER_DTD_ELEM:
3193 case XML_TEXTWRITER_DTD_ELEM_TEXT:
3194 count = xmlOutputBufferWriteString(writer->out, ">");
3195 if (count < 0)
3196 return -1;
3197 sum += count;
3198 break;
3199 default:
3200 return -1;
3201 }
3202
3203 if (writer->indent) {
3204 count = xmlOutputBufferWriteString(writer->out, "\n");
3205 if (count < 0)
3206 return -1;
3207 sum += count;
3208 }
3209
3210 xmlListPopFront(writer->nodes);
3211 return sum;
3212}
3213
3214/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003215 * xmlTextWriterWriteFormatDTDElement:
3216 * @writer: the xmlTextWriterPtr
3217 * @name: the name of the DTD element
3218 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003219 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003220 *
3221 * Write a formatted DTD element.
3222 *
3223 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3224 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00003225int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00003226xmlTextWriterWriteFormatDTDElement(xmlTextWriterPtr writer,
3227 const xmlChar * name,
3228 const char *format, ...)
3229{
3230 int rc;
3231 va_list ap;
3232
3233 va_start(ap, format);
3234
3235 rc = xmlTextWriterWriteVFormatDTDElement(writer, name, format, ap);
3236
3237 va_end(ap);
3238 return rc;
3239}
3240
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003241/**
3242 * xmlTextWriterWriteVFormatDTDElement:
3243 * @writer: the xmlTextWriterPtr
3244 * @name: the name of the DTD element
3245 * @format: format string (see printf)
3246 * @argptr: pointer to the first member of the variable argument list.
3247 *
3248 * Write a formatted DTD element.
3249 *
3250 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3251 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003252int
3253xmlTextWriterWriteVFormatDTDElement(xmlTextWriterPtr writer,
3254 const xmlChar * name,
3255 const char *format, va_list argptr)
3256{
3257 int rc;
3258 xmlChar *buf;
3259
3260 if (writer == NULL)
3261 return -1;
3262
3263 buf = xmlTextWriterVSprintf(format, argptr);
3264 if (buf == 0)
3265 return 0;
3266
3267 rc = xmlTextWriterWriteDTDElement(writer, name, buf);
3268
3269 xmlFree(buf);
3270 return rc;
3271}
3272
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003273/**
3274 * xmlTextWriterWriteDTDElement:
3275 * @writer: the xmlTextWriterPtr
3276 * @name: the name of the DTD element
3277 * @content: content of the element
3278 *
3279 * Write a DTD element.
3280 *
3281 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3282 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003283int
3284xmlTextWriterWriteDTDElement(xmlTextWriterPtr writer,
3285 const xmlChar * name, const xmlChar * content)
3286{
3287 int count;
3288 int sum;
3289
3290 if (content == NULL)
3291 return -1;
3292
3293 sum = 0;
3294 count = xmlTextWriterStartDTDElement(writer, name);
3295 if (count == -1)
3296 return -1;
3297 sum += count;
3298
Daniel Veillard1d211e22003-10-20 22:32:39 +00003299 count = xmlTextWriterWriteString(writer, content);
3300 if (count == -1)
3301 return -1;
3302 sum += count;
3303
3304 count = xmlTextWriterEndDTDElement(writer);
3305 if (count == -1)
3306 return -1;
3307 sum += count;
3308
3309 return sum;
3310}
3311
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003312/**
3313 * xmlTextWriterStartDTDAttlist:
3314 * @writer: the xmlTextWriterPtr
3315 * @name: the name of the DTD ATTLIST
3316 *
3317 * Start an xml DTD ATTLIST.
3318 *
3319 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3320 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003321int
3322xmlTextWriterStartDTDAttlist(xmlTextWriterPtr writer, const xmlChar * name)
3323{
3324 int count;
3325 int sum;
3326 xmlLinkPtr lk;
3327 xmlTextWriterStackEntry *p;
3328
3329 if (writer == NULL || name == NULL || *name == '\0')
3330 return -1;
3331
3332 sum = 0;
3333 lk = xmlListFront(writer->nodes);
3334 if (lk == 0) {
3335 return -1;
3336 }
3337
3338 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
Daniel Veillard500a1de2004-03-22 15:22:58 +00003339 if (p != 0) {
3340 switch (p->state) {
3341 case XML_TEXTWRITER_DTD:
3342 count = xmlOutputBufferWriteString(writer->out, " [");
3343 if (count < 0)
3344 return -1;
3345 sum += count;
3346 if (writer->indent) {
3347 count = xmlOutputBufferWriteString(writer->out, "\n");
3348 if (count < 0)
3349 return -1;
3350 sum += count;
3351 }
3352 p->state = XML_TEXTWRITER_DTD_TEXT;
3353 /* fallthrough */
3354 case XML_TEXTWRITER_DTD_TEXT:
3355 case XML_TEXTWRITER_NONE:
3356 break;
3357 default:
Daniel Veillard1d211e22003-10-20 22:32:39 +00003358 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00003359 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00003360 }
3361
3362 p = (xmlTextWriterStackEntry *)
3363 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3364 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003365 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003366 "xmlTextWriterStartDTDAttlist : out of memory!\n");
3367 return -1;
3368 }
3369
3370 p->name = xmlStrdup(name);
3371 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003372 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003373 "xmlTextWriterStartDTDAttlist : out of memory!\n");
3374 xmlFree(p);
3375 return -1;
3376 }
3377 p->state = XML_TEXTWRITER_DTD_ATTL;
3378
3379 xmlListPushFront(writer->nodes, p);
3380
Daniel Veillard500a1de2004-03-22 15:22:58 +00003381 if (writer->indent) {
3382 count = xmlTextWriterWriteIndent(writer);
3383 if (count < 0)
3384 return -1;
3385 sum += count;
3386 }
3387
Daniel Veillard1d211e22003-10-20 22:32:39 +00003388 count = xmlOutputBufferWriteString(writer->out, "<!ATTLIST ");
3389 if (count < 0)
3390 return -1;
3391 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +00003392 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003393 if (count < 0)
3394 return -1;
3395 sum += count;
3396
3397 return sum;
3398}
3399
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003400/**
Daniel Veillard500a1de2004-03-22 15:22:58 +00003401 * xmlTextWriterEndDTDAttlist:
3402 * @writer: the xmlTextWriterPtr
3403 *
3404 * End an xml DTD attribute list.
3405 *
3406 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3407 */
3408int
3409xmlTextWriterEndDTDAttlist(xmlTextWriterPtr writer)
3410{
3411 int count;
3412 int sum;
3413 xmlLinkPtr lk;
3414 xmlTextWriterStackEntry *p;
3415
3416 if (writer == NULL)
3417 return -1;
3418
3419 sum = 0;
3420 lk = xmlListFront(writer->nodes);
3421 if (lk == 0)
3422 return -1;
3423
3424 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3425 if (p == 0)
3426 return -1;
3427
3428 switch (p->state) {
3429 case XML_TEXTWRITER_DTD_ATTL:
3430 case XML_TEXTWRITER_DTD_ATTL_TEXT:
3431 count = xmlOutputBufferWriteString(writer->out, ">");
3432 if (count < 0)
3433 return -1;
3434 sum += count;
3435 break;
3436 default:
3437 return -1;
3438 }
3439
3440 if (writer->indent) {
3441 count = xmlOutputBufferWriteString(writer->out, "\n");
3442 if (count < 0)
3443 return -1;
3444 sum += count;
3445 }
3446
3447 xmlListPopFront(writer->nodes);
3448 return sum;
3449}
3450
3451/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003452 * xmlTextWriterWriteFormatDTDAttlist:
3453 * @writer: the xmlTextWriterPtr
3454 * @name: the name of the DTD ATTLIST
3455 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003456 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003457 *
3458 * Write a formatted DTD ATTLIST.
3459 *
3460 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3461 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00003462int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00003463xmlTextWriterWriteFormatDTDAttlist(xmlTextWriterPtr writer,
3464 const xmlChar * name,
3465 const char *format, ...)
3466{
3467 int rc;
3468 va_list ap;
3469
3470 va_start(ap, format);
3471
3472 rc = xmlTextWriterWriteVFormatDTDAttlist(writer, name, format, ap);
3473
3474 va_end(ap);
3475 return rc;
3476}
3477
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003478/**
3479 * xmlTextWriterWriteVFormatDTDAttlist:
3480 * @writer: the xmlTextWriterPtr
3481 * @name: the name of the DTD ATTLIST
3482 * @format: format string (see printf)
3483 * @argptr: pointer to the first member of the variable argument list.
3484 *
3485 * Write a formatted DTD ATTLIST.
3486 *
3487 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3488 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003489int
3490xmlTextWriterWriteVFormatDTDAttlist(xmlTextWriterPtr writer,
3491 const xmlChar * name,
3492 const char *format, va_list argptr)
3493{
3494 int rc;
3495 xmlChar *buf;
3496
3497 if (writer == NULL)
3498 return -1;
3499
3500 buf = xmlTextWriterVSprintf(format, argptr);
3501 if (buf == 0)
3502 return 0;
3503
3504 rc = xmlTextWriterWriteDTDAttlist(writer, name, buf);
3505
3506 xmlFree(buf);
3507 return rc;
3508}
3509
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003510/**
3511 * xmlTextWriterWriteDTDAttlist:
3512 * @writer: the xmlTextWriterPtr
3513 * @name: the name of the DTD ATTLIST
3514 * @content: content of the ATTLIST
3515 *
3516 * Write a DTD ATTLIST.
3517 *
3518 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3519 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003520int
3521xmlTextWriterWriteDTDAttlist(xmlTextWriterPtr writer,
3522 const xmlChar * name, const xmlChar * content)
3523{
3524 int count;
3525 int sum;
3526
3527 if (content == NULL)
3528 return -1;
3529
3530 sum = 0;
3531 count = xmlTextWriterStartDTDAttlist(writer, name);
3532 if (count == -1)
3533 return -1;
3534 sum += count;
3535
Daniel Veillard1d211e22003-10-20 22:32:39 +00003536 count = xmlTextWriterWriteString(writer, content);
3537 if (count == -1)
3538 return -1;
3539 sum += count;
3540
3541 count = xmlTextWriterEndDTDAttlist(writer);
3542 if (count == -1)
3543 return -1;
3544 sum += count;
3545
3546 return sum;
3547}
3548
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003549/**
3550 * xmlTextWriterStartDTDEntity:
3551 * @writer: the xmlTextWriterPtr
3552 * @pe: TRUE if this is a parameter entity, FALSE if not
3553 * @name: the name of the DTD ATTLIST
3554 *
3555 * Start an xml DTD ATTLIST.
3556 *
3557 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3558 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003559int
3560xmlTextWriterStartDTDEntity(xmlTextWriterPtr writer,
3561 int pe, const xmlChar * name)
3562{
3563 int count;
3564 int sum;
3565 xmlLinkPtr lk;
3566 xmlTextWriterStackEntry *p;
3567
3568 if (writer == NULL || name == NULL || *name == '\0')
3569 return -1;
3570
3571 sum = 0;
3572 lk = xmlListFront(writer->nodes);
Daniel Veillard500a1de2004-03-22 15:22:58 +00003573 if (lk != 0) {
Daniel Veillard1d211e22003-10-20 22:32:39 +00003574
Daniel Veillard500a1de2004-03-22 15:22:58 +00003575 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3576 if (p != 0) {
3577 switch (p->state) {
3578 case XML_TEXTWRITER_DTD:
3579 count = xmlOutputBufferWriteString(writer->out, " [");
3580 if (count < 0)
3581 return -1;
3582 sum += count;
3583 if (writer->indent) {
3584 count =
3585 xmlOutputBufferWriteString(writer->out, "\n");
3586 if (count < 0)
3587 return -1;
3588 sum += count;
3589 }
3590 p->state = XML_TEXTWRITER_DTD_TEXT;
3591 /* fallthrough */
3592 case XML_TEXTWRITER_DTD_TEXT:
3593 case XML_TEXTWRITER_NONE:
3594 break;
3595 default:
3596 return -1;
3597 }
3598 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00003599 }
3600
3601 p = (xmlTextWriterStackEntry *)
3602 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3603 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003604 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003605 "xmlTextWriterStartDTDElement : out of memory!\n");
3606 return -1;
3607 }
3608
3609 p->name = xmlStrdup(name);
3610 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003611 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003612 "xmlTextWriterStartDTDElement : out of memory!\n");
3613 xmlFree(p);
3614 return -1;
3615 }
Daniel Veillard500a1de2004-03-22 15:22:58 +00003616
3617 if (pe != 0)
3618 p->state = XML_TEXTWRITER_DTD_PENT;
3619 else
3620 p->state = XML_TEXTWRITER_DTD_ENTY;
Daniel Veillard1d211e22003-10-20 22:32:39 +00003621
3622 xmlListPushFront(writer->nodes, p);
3623
Daniel Veillard500a1de2004-03-22 15:22:58 +00003624 if (writer->indent) {
3625 count = xmlTextWriterWriteIndent(writer);
3626 if (count < 0)
3627 return -1;
3628 sum += count;
3629 }
3630
Daniel Veillard1d211e22003-10-20 22:32:39 +00003631 count = xmlOutputBufferWriteString(writer->out, "<!ENTITY ");
3632 if (count < 0)
3633 return -1;
3634 sum += count;
3635
3636 if (pe != 0) {
Daniel Veillard500a1de2004-03-22 15:22:58 +00003637 count = xmlOutputBufferWriteString(writer->out, "% ");
Daniel Veillard1d211e22003-10-20 22:32:39 +00003638 if (count < 0)
3639 return -1;
3640 sum += count;
3641 }
3642
Daniel Veillardab69f362004-02-17 11:40:32 +00003643 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003644 if (count < 0)
3645 return -1;
3646 sum += count;
3647
3648 return sum;
3649}
3650
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003651/**
Daniel Veillard500a1de2004-03-22 15:22:58 +00003652 * xmlTextWriterEndDTDEntity:
3653 * @writer: the xmlTextWriterPtr
3654 *
3655 * End an xml DTD entity.
3656 *
3657 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3658 */
3659int
3660xmlTextWriterEndDTDEntity(xmlTextWriterPtr writer)
3661{
3662 int count;
3663 int sum;
3664 xmlLinkPtr lk;
3665 xmlTextWriterStackEntry *p;
3666
3667 if (writer == NULL)
3668 return -1;
3669
3670 sum = 0;
3671 lk = xmlListFront(writer->nodes);
3672 if (lk == 0)
3673 return -1;
3674
3675 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3676 if (p == 0)
3677 return -1;
3678
3679 switch (p->state) {
3680 case XML_TEXTWRITER_DTD_ENTY_TEXT:
3681 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3682 if (count < 0)
3683 return -1;
3684 sum += count;
3685 case XML_TEXTWRITER_DTD_ENTY:
3686 case XML_TEXTWRITER_DTD_PENT:
Daniel Veillard500a1de2004-03-22 15:22:58 +00003687 count = xmlOutputBufferWriteString(writer->out, ">");
3688 if (count < 0)
3689 return -1;
3690 sum += count;
3691 break;
3692 default:
3693 return -1;
3694 }
3695
3696 if (writer->indent) {
3697 count = xmlOutputBufferWriteString(writer->out, "\n");
3698 if (count < 0)
3699 return -1;
3700 sum += count;
3701 }
3702
3703 xmlListPopFront(writer->nodes);
3704 return sum;
3705}
3706
3707/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003708 * xmlTextWriterWriteFormatDTDInternalEntity:
3709 * @writer: the xmlTextWriterPtr
3710 * @pe: TRUE if this is a parameter entity, FALSE if not
3711 * @name: the name of the DTD entity
3712 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003713 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003714 *
3715 * Write a formatted DTD internal entity.
3716 *
3717 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3718 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00003719int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00003720xmlTextWriterWriteFormatDTDInternalEntity(xmlTextWriterPtr writer,
3721 int pe,
3722 const xmlChar * name,
3723 const char *format, ...)
3724{
3725 int rc;
3726 va_list ap;
3727
3728 va_start(ap, format);
3729
3730 rc = xmlTextWriterWriteVFormatDTDInternalEntity(writer, pe, name,
3731 format, ap);
3732
3733 va_end(ap);
3734 return rc;
3735}
3736
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003737/**
3738 * xmlTextWriterWriteVFormatDTDInternalEntity:
3739 * @writer: the xmlTextWriterPtr
3740 * @pe: TRUE if this is a parameter entity, FALSE if not
3741 * @name: the name of the DTD entity
3742 * @format: format string (see printf)
3743 * @argptr: pointer to the first member of the variable argument list.
3744 *
3745 * Write a formatted DTD internal entity.
3746 *
3747 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3748 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003749int
3750xmlTextWriterWriteVFormatDTDInternalEntity(xmlTextWriterPtr writer,
3751 int pe,
3752 const xmlChar * name,
3753 const char *format,
3754 va_list argptr)
3755{
3756 int rc;
3757 xmlChar *buf;
3758
3759 if (writer == NULL)
3760 return -1;
3761
3762 buf = xmlTextWriterVSprintf(format, argptr);
3763 if (buf == 0)
3764 return 0;
3765
3766 rc = xmlTextWriterWriteDTDInternalEntity(writer, pe, name, buf);
3767
3768 xmlFree(buf);
3769 return rc;
3770}
3771
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003772/**
3773 * xmlTextWriterWriteDTDEntity:
3774 * @writer: the xmlTextWriterPtr
3775 * @pe: TRUE if this is a parameter entity, FALSE if not
3776 * @name: the name of the DTD entity
3777 * @pubid: the public identifier, which is an alternative to the system identifier
3778 * @sysid: the system identifier, which is the URI of the DTD
3779 * @ndataid: the xml notation name.
3780 * @content: content of the entity
3781 *
3782 * Write a DTD entity.
3783 *
3784 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3785 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003786int
3787xmlTextWriterWriteDTDEntity(xmlTextWriterPtr writer,
3788 int pe,
3789 const xmlChar * name,
3790 const xmlChar * pubid,
3791 const xmlChar * sysid,
3792 const xmlChar * ndataid,
3793 const xmlChar * content)
3794{
Daniel Veillard500a1de2004-03-22 15:22:58 +00003795 if ((content == NULL) && (pubid == NULL) && (sysid == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00003796 return -1;
3797 if ((pe != 0) && (ndataid != NULL))
3798 return -1;
3799
Daniel Veillard500a1de2004-03-22 15:22:58 +00003800 if ((pubid == NULL) && (sysid == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00003801 return xmlTextWriterWriteDTDInternalEntity(writer, pe, name,
3802 content);
3803
3804 return xmlTextWriterWriteDTDExternalEntity(writer, pe, name, pubid,
3805 sysid, ndataid);
3806}
3807
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003808/**
3809 * xmlTextWriterWriteDTDInternalEntity:
3810 * @writer: the xmlTextWriterPtr
3811 * @pe: TRUE if this is a parameter entity, FALSE if not
3812 * @name: the name of the DTD entity
3813 * @content: content of the entity
3814 *
3815 * Write a DTD internal entity.
3816 *
3817 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3818 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003819int
3820xmlTextWriterWriteDTDInternalEntity(xmlTextWriterPtr writer,
3821 int pe,
3822 const xmlChar * name,
3823 const xmlChar * content)
3824{
3825 int count;
3826 int sum;
3827
3828 if ((name == NULL) || (*name == '\0') || (content == NULL))
3829 return -1;
3830
3831 sum = 0;
3832 count = xmlTextWriterStartDTDEntity(writer, pe, name);
3833 if (count == -1)
3834 return -1;
3835 sum += count;
3836
Daniel Veillard1d211e22003-10-20 22:32:39 +00003837 count = xmlTextWriterWriteString(writer, content);
3838 if (count == -1)
3839 return -1;
3840 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00003841
3842 count = xmlTextWriterEndDTDEntity(writer);
3843 if (count == -1)
3844 return -1;
3845 sum += count;
3846
3847 return sum;
3848}
3849
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003850/**
3851 * xmlTextWriterWriteDTDExternalEntity:
3852 * @writer: the xmlTextWriterPtr
3853 * @pe: TRUE if this is a parameter entity, FALSE if not
3854 * @name: the name of the DTD entity
3855 * @pubid: the public identifier, which is an alternative to the system identifier
3856 * @sysid: the system identifier, which is the URI of the DTD
3857 * @ndataid: the xml notation name.
3858 *
Daniel Veillard500a1de2004-03-22 15:22:58 +00003859 * Write a DTD external entity. The entity must have been started with xmlTextWriterStartDTDEntity
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003860 *
3861 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3862 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003863int
3864xmlTextWriterWriteDTDExternalEntity(xmlTextWriterPtr writer,
3865 int pe,
3866 const xmlChar * name,
3867 const xmlChar * pubid,
3868 const xmlChar * sysid,
3869 const xmlChar * ndataid)
3870{
3871 int count;
3872 int sum;
3873
Daniel Veillard500a1de2004-03-22 15:22:58 +00003874 if (((pubid == NULL) && (sysid == NULL)))
Daniel Veillard1d211e22003-10-20 22:32:39 +00003875 return -1;
3876 if ((pe != 0) && (ndataid != NULL))
3877 return -1;
3878
3879 sum = 0;
3880 count = xmlTextWriterStartDTDEntity(writer, pe, name);
3881 if (count == -1)
3882 return -1;
3883 sum += count;
3884
Daniel Veillard500a1de2004-03-22 15:22:58 +00003885 count =
3886 xmlTextWriterWriteDTDExternalEntityContents(writer, pubid, sysid,
3887 ndataid);
3888 if (count < 0)
3889 return -1;
3890 sum += count;
3891
3892 count = xmlTextWriterEndDTDEntity(writer);
3893 if (count == -1)
3894 return -1;
3895 sum += count;
3896
3897 return sum;
3898}
3899
3900/**
3901 * xmlTextWriterWriteDTDExternalEntityContents:
3902 * @writer: the xmlTextWriterPtr
3903 * @pubid: the public identifier, which is an alternative to the system identifier
3904 * @sysid: the system identifier, which is the URI of the DTD
3905 * @ndataid: the xml notation name.
3906 *
3907 * Write the contents of a DTD external entity.
3908 *
3909 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3910 */
3911int
3912xmlTextWriterWriteDTDExternalEntityContents(xmlTextWriterPtr writer,
3913 const xmlChar * pubid,
3914 const xmlChar * sysid,
3915 const xmlChar * ndataid)
3916{
3917 int count;
3918 int sum;
3919 xmlLinkPtr lk;
3920 xmlTextWriterStackEntry *p;
3921
3922 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003923 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003924 "xmlTextWriterWriteDTDExternalEntityContents: xmlTextWriterPtr invalid!\n");
3925 return -1;
3926 }
3927
3928 sum = 0;
3929 lk = xmlListFront(writer->nodes);
3930 if (lk == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003931 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003932 "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n");
3933 return -1;
3934 }
3935
3936 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3937 if (p == 0)
3938 return -1;
3939
3940 switch (p->state) {
3941 case XML_TEXTWRITER_DTD_ENTY:
3942 break;
3943 case XML_TEXTWRITER_DTD_PENT:
3944 if (ndataid != NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003945 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003946 "xmlTextWriterWriteDTDExternalEntityContents: notation not allowed with parameter entities!\n");
3947 return -1;
3948 }
3949 break;
3950 default:
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003951 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003952 "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n");
3953 return -1;
3954 }
3955
Daniel Veillard1d211e22003-10-20 22:32:39 +00003956 if (pubid != 0) {
3957 if (sysid == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003958 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003959 "xmlTextWriterWriteDTDExternalEntityContents: system identifier needed!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +00003960 return -1;
3961 }
3962
3963 count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
3964 if (count < 0)
3965 return -1;
3966 sum += count;
3967
3968 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3969 if (count < 0)
3970 return -1;
3971 sum += count;
3972
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003973 count =
3974 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003975 if (count < 0)
3976 return -1;
3977 sum += count;
3978
3979 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3980 if (count < 0)
3981 return -1;
3982 sum += count;
3983 }
3984
3985 if (sysid != 0) {
3986 if (pubid == 0) {
3987 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
3988 if (count < 0)
3989 return -1;
3990 sum += count;
3991 }
3992
3993 count = xmlOutputBufferWriteString(writer->out, " ");
3994 if (count < 0)
3995 return -1;
3996 sum += count;
3997
3998 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3999 if (count < 0)
4000 return -1;
4001 sum += count;
4002
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004003 count =
4004 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004005 if (count < 0)
4006 return -1;
4007 sum += count;
4008
4009 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4010 if (count < 0)
4011 return -1;
4012 sum += count;
4013 }
4014
4015 if (ndataid != NULL) {
4016 count = xmlOutputBufferWriteString(writer->out, " NDATA ");
4017 if (count < 0)
4018 return -1;
4019 sum += count;
4020
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004021 count =
4022 xmlOutputBufferWriteString(writer->out,
4023 (const char *) ndataid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004024 if (count < 0)
4025 return -1;
4026 sum += count;
4027 }
4028
Daniel Veillard1d211e22003-10-20 22:32:39 +00004029 return sum;
4030}
4031
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004032/**
4033 * xmlTextWriterWriteDTDNotation:
4034 * @writer: the xmlTextWriterPtr
4035 * @name: the name of the xml notation
4036 * @pubid: the public identifier, which is an alternative to the system identifier
4037 * @sysid: the system identifier, which is the URI of the DTD
4038 *
4039 * Write a DTD entity.
4040 *
4041 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
4042 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00004043int
4044xmlTextWriterWriteDTDNotation(xmlTextWriterPtr writer,
4045 const xmlChar * name,
4046 const xmlChar * pubid, const xmlChar * sysid)
4047{
4048 int count;
4049 int sum;
4050 xmlLinkPtr lk;
4051 xmlTextWriterStackEntry *p;
4052
4053 if (writer == NULL || name == NULL || *name == '\0')
4054 return -1;
4055
4056 sum = 0;
4057 lk = xmlListFront(writer->nodes);
4058 if (lk == 0) {
4059 return -1;
4060 }
4061
4062 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
Daniel Veillard500a1de2004-03-22 15:22:58 +00004063 if (p != 0) {
4064 switch (p->state) {
4065 case XML_TEXTWRITER_DTD:
4066 count = xmlOutputBufferWriteString(writer->out, " [");
4067 if (count < 0)
4068 return -1;
4069 sum += count;
4070 if (writer->indent) {
4071 count = xmlOutputBufferWriteString(writer->out, "\n");
4072 if (count < 0)
4073 return -1;
4074 sum += count;
4075 }
4076 p->state = XML_TEXTWRITER_DTD_TEXT;
4077 /* fallthrough */
4078 case XML_TEXTWRITER_DTD_TEXT:
4079 break;
4080 default:
4081 return -1;
4082 }
4083 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00004084
Daniel Veillard500a1de2004-03-22 15:22:58 +00004085 if (writer->indent) {
4086 count = xmlTextWriterWriteIndent(writer);
4087 if (count < 0)
Daniel Veillard1d211e22003-10-20 22:32:39 +00004088 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00004089 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00004090 }
4091
4092 count = xmlOutputBufferWriteString(writer->out, "<!NOTATION ");
4093 if (count < 0)
4094 return -1;
4095 sum += count;
4096 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
4097 if (count < 0)
4098 return -1;
4099 sum += count;
4100
4101 if (pubid != 0) {
4102 count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
4103 if (count < 0)
4104 return -1;
4105 sum += count;
4106 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4107 if (count < 0)
4108 return -1;
4109 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004110 count =
4111 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004112 if (count < 0)
4113 return -1;
4114 sum += count;
4115 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4116 if (count < 0)
4117 return -1;
4118 sum += count;
4119 }
4120
4121 if (sysid != 0) {
4122 if (pubid == 0) {
4123 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
4124 if (count < 0)
4125 return -1;
4126 sum += count;
4127 }
4128 count = xmlOutputBufferWriteString(writer->out, " ");
4129 if (count < 0)
4130 return -1;
4131 sum += count;
4132 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4133 if (count < 0)
4134 return -1;
4135 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004136 count =
4137 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004138 if (count < 0)
4139 return -1;
4140 sum += count;
4141 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4142 if (count < 0)
4143 return -1;
4144 sum += count;
4145 }
4146
4147 count = xmlOutputBufferWriteString(writer->out, ">");
4148 if (count < 0)
4149 return -1;
4150 sum += count;
4151
4152 return sum;
4153}
4154
4155/**
4156 * xmlTextWriterFlush:
4157 * @writer: the xmlTextWriterPtr
4158 *
4159 * Flush the output buffer.
4160 *
4161 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
4162 */
4163int
4164xmlTextWriterFlush(xmlTextWriterPtr writer)
4165{
4166 int count;
4167
4168 if (writer == NULL)
4169 return -1;
4170
4171 if (writer->out == NULL)
4172 count = 0;
4173 else
4174 count = xmlOutputBufferFlush(writer->out);
4175
4176 return count;
4177}
4178
4179/**
4180 * misc
4181 */
4182
4183/**
4184 * xmlFreeTextWriterStackEntry:
4185 * @lk: the xmlLinkPtr
4186 *
4187 * Free callback for the xmlList.
4188 */
4189static void
4190xmlFreeTextWriterStackEntry(xmlLinkPtr lk)
4191{
4192 xmlTextWriterStackEntry *p;
4193
4194 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
4195 if (p == 0)
4196 return;
4197
4198 if (p->name != 0)
4199 xmlFree(p->name);
4200 xmlFree(p);
4201}
4202
4203/**
4204 * xmlCmpTextWriterStackEntry:
4205 * @data0: the first data
4206 * @data1: the second data
4207 *
4208 * Compare callback for the xmlList.
4209 *
4210 * Returns -1, 0, 1
4211 */
4212static int
4213xmlCmpTextWriterStackEntry(const void *data0, const void *data1)
4214{
4215 xmlTextWriterStackEntry *p0;
4216 xmlTextWriterStackEntry *p1;
4217
4218 if (data0 == data1)
4219 return 0;
4220
4221 if (data0 == 0)
4222 return -1;
4223
4224 if (data1 == 0)
4225 return 1;
4226
4227 p0 = (xmlTextWriterStackEntry *) data0;
4228 p1 = (xmlTextWriterStackEntry *) data1;
4229
4230 return xmlStrcmp(p0->name, p1->name);
4231}
4232
4233/**
4234 * misc
4235 */
4236
4237/**
4238 * xmlFreeTextWriterNsStackEntry:
4239 * @lk: the xmlLinkPtr
4240 *
4241 * Free callback for the xmlList.
4242 */
4243static void
4244xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk)
4245{
4246 xmlTextWriterNsStackEntry *p;
4247
4248 p = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
4249 if (p == 0)
4250 return;
4251
4252 if (p->prefix != 0)
4253 xmlFree(p->prefix);
4254 if (p->uri != 0)
4255 xmlFree(p->uri);
4256
4257 xmlFree(p);
4258}
4259
4260/**
4261 * xmlCmpTextWriterNsStackEntry:
4262 * @data0: the first data
4263 * @data1: the second data
4264 *
4265 * Compare callback for the xmlList.
4266 *
4267 * Returns -1, 0, 1
4268 */
4269static int
4270xmlCmpTextWriterNsStackEntry(const void *data0, const void *data1)
4271{
4272 xmlTextWriterNsStackEntry *p0;
4273 xmlTextWriterNsStackEntry *p1;
4274 int rc;
4275
4276 if (data0 == data1)
4277 return 0;
4278
4279 if (data0 == 0)
4280 return -1;
4281
4282 if (data1 == 0)
4283 return 1;
4284
4285 p0 = (xmlTextWriterNsStackEntry *) data0;
4286 p1 = (xmlTextWriterNsStackEntry *) data1;
4287
4288 rc = xmlStrcmp(p0->prefix, p1->prefix);
4289
4290 if (rc == 0)
4291 rc = p0->elem == p1->elem;
4292
4293 return rc;
4294}
4295
4296/**
4297 * xmlTextWriterWriteMemCallback:
4298 * @context: the xmlBufferPtr
4299 * @str: the data to write
4300 * @len: the length of the data
4301 *
4302 * Write callback for the xmlOutputBuffer with target xmlBuffer
4303 *
4304 * Returns -1, 0, 1
4305 */
4306static int
4307xmlTextWriterWriteMemCallback(void *context, const xmlChar * str, int len)
4308{
4309 xmlBufferPtr buf = (xmlBufferPtr) context;
4310
4311 xmlBufferAdd(buf, str, len);
4312
4313 return len;
4314}
4315
4316/**
4317 * xmlTextWriterCloseMemCallback:
4318 * @context: the xmlBufferPtr
4319 *
4320 * Close callback for the xmlOutputBuffer with target xmlBuffer
4321 *
4322 * Returns -1, 0, 1
4323 */
4324static int
4325xmlTextWriterCloseMemCallback(void *context ATTRIBUTE_UNUSED)
4326{
4327 return 0;
4328}
4329
4330/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004331 * xmlTextWriterWriteDocCallback:
4332 * @context: the xmlBufferPtr
4333 * @str: the data to write
4334 * @len: the length of the data
4335 *
4336 * Write callback for the xmlOutputBuffer with target xmlBuffer
4337 *
4338 * Returns -1, 0, 1
4339 */
4340static int
4341xmlTextWriterWriteDocCallback(void *context, const xmlChar * str, int len)
4342{
4343 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context;
4344 int rc;
4345
Daniel Veillard1d913862003-11-21 00:28:39 +00004346 if ((rc = xmlParseChunk(ctxt, (const char *) str, len, 0)) != 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004347 xmlWriterErrMsgInt(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004348 "xmlTextWriterWriteDocCallback : XML error %d !\n",
4349 rc);
4350 return -1;
4351 }
4352
4353 return len;
4354}
4355
4356/**
4357 * xmlTextWriterCloseDocCallback:
4358 * @context: the xmlBufferPtr
4359 *
4360 * Close callback for the xmlOutputBuffer with target xmlBuffer
4361 *
4362 * Returns -1, 0, 1
4363 */
4364static int
4365xmlTextWriterCloseDocCallback(void *context)
4366{
4367 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context;
4368 int rc;
4369
4370 if ((rc = xmlParseChunk(ctxt, NULL, 0, 1)) != 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004371 xmlWriterErrMsgInt(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004372 "xmlTextWriterWriteDocCallback : XML error %d !\n",
4373 rc);
4374 return -1;
4375 }
4376
4377 return 0;
4378}
4379
4380/**
Daniel Veillard1d211e22003-10-20 22:32:39 +00004381 * xmlTextWriterVSprintf:
4382 * @format: see printf
4383 * @argptr: pointer to the first member of the variable argument list.
4384 *
4385 * Utility function for formatted output
4386 *
4387 * Returns a new xmlChar buffer with the data or NULL on error. This buffer must be freed.
4388 */
4389static xmlChar *
4390xmlTextWriterVSprintf(const char *format, va_list argptr)
4391{
4392 int size;
4393 int count;
4394 xmlChar *buf;
William M. Brackf4caa5e2005-10-20 09:04:05 +00004395 va_list locarg;
Daniel Veillard1d211e22003-10-20 22:32:39 +00004396
4397 size = BUFSIZ;
4398 buf = (xmlChar *) xmlMalloc(size);
4399 if (buf == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004400 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00004401 "xmlTextWriterVSprintf : out of memory!\n");
4402 return NULL;
4403 }
4404
William M. Brackf4caa5e2005-10-20 09:04:05 +00004405 VA_COPY(locarg, argptr);
4406 while (((count = vsnprintf((char *) buf, size, format, locarg)) < 0)
Daniel Veillard1d211e22003-10-20 22:32:39 +00004407 || (count == size - 1) || (count == size) || (count > size)) {
William M. Brackf4caa5e2005-10-20 09:04:05 +00004408 va_end(locarg);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004409 xmlFree(buf);
4410 size += BUFSIZ;
4411 buf = (xmlChar *) xmlMalloc(size);
4412 if (buf == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004413 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00004414 "xmlTextWriterVSprintf : out of memory!\n");
4415 return NULL;
4416 }
William M. Brackf4caa5e2005-10-20 09:04:05 +00004417 VA_COPY(locarg, argptr);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004418 }
William M. Brackf4caa5e2005-10-20 09:04:05 +00004419 va_end(locarg);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004420
4421 return buf;
4422}
4423
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004424/**
4425 * xmlTextWriterStartDocumentCallback:
4426 * @ctx: the user data (XML parser context)
4427 *
4428 * called at the start of document processing.
4429 */
4430static void
4431xmlTextWriterStartDocumentCallback(void *ctx)
4432{
4433 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
4434 xmlDocPtr doc;
4435
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004436 if (ctxt->html) {
4437#ifdef LIBXML_HTML_ENABLED
4438 if (ctxt->myDoc == NULL)
4439 ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
4440 if (ctxt->myDoc == NULL) {
4441 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
4442 ctxt->sax->error(ctxt->userData,
4443 "SAX.startDocument(): out of memory\n");
4444 ctxt->errNo = XML_ERR_NO_MEMORY;
4445 ctxt->instate = XML_PARSER_EOF;
4446 ctxt->disableSAX = 1;
4447 return;
4448 }
4449#else
Daniel Veillardd0cf7f62004-11-09 16:17:02 +00004450 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004451 "libxml2 built without HTML support\n");
4452 ctxt->errNo = XML_ERR_INTERNAL_ERROR;
4453 ctxt->instate = XML_PARSER_EOF;
4454 ctxt->disableSAX = 1;
4455 return;
4456#endif
4457 } else {
4458 doc = ctxt->myDoc;
4459 if (doc == NULL)
4460 doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
4461 if (doc != NULL) {
4462 if (doc->children == NULL) {
4463 if (ctxt->encoding != NULL)
4464 doc->encoding = xmlStrdup(ctxt->encoding);
4465 else
4466 doc->encoding = NULL;
4467 doc->standalone = ctxt->standalone;
4468 }
4469 } else {
4470 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
4471 ctxt->sax->error(ctxt->userData,
4472 "SAX.startDocument(): out of memory\n");
4473 ctxt->errNo = XML_ERR_NO_MEMORY;
4474 ctxt->instate = XML_PARSER_EOF;
4475 ctxt->disableSAX = 1;
4476 return;
4477 }
4478 }
4479 if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) &&
4480 (ctxt->input != NULL) && (ctxt->input->filename != NULL)) {
4481 ctxt->myDoc->URL =
4482 xmlCanonicPath((const xmlChar *) ctxt->input->filename);
4483 if (ctxt->myDoc->URL == NULL)
4484 ctxt->myDoc->URL =
4485 xmlStrdup((const xmlChar *) ctxt->input->filename);
4486 }
4487}
4488
Daniel Veillard2cca4462004-01-02 20:04:23 +00004489/**
4490 * xmlTextWriterSetIndent:
4491 * @writer: the xmlTextWriterPtr
4492 * @indent: do indentation?
4493 *
4494 * Set indentation output. indent = 0 do not indentation. indent > 0 do indentation.
4495 *
4496 * Returns -1 on error or 0 otherwise.
4497 */
4498int
Daniel Veillardab69f362004-02-17 11:40:32 +00004499xmlTextWriterSetIndent(xmlTextWriterPtr writer, int indent)
Daniel Veillard2cca4462004-01-02 20:04:23 +00004500{
Daniel Veillarde43cc572004-11-03 11:50:29 +00004501 if ((writer == NULL) || (indent < 0))
Daniel Veillardab69f362004-02-17 11:40:32 +00004502 return -1;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004503
Daniel Veillardab69f362004-02-17 11:40:32 +00004504 writer->indent = indent;
4505 writer->doindent = 1;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004506
Daniel Veillardab69f362004-02-17 11:40:32 +00004507 return 0;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004508}
4509
4510/**
4511 * xmlTextWriterSetIndentString:
4512 * @writer: the xmlTextWriterPtr
4513 * @str: the xmlChar string
4514 *
4515 * Set string indentation.
4516 *
4517 * Returns -1 on error or 0 otherwise.
4518 */
4519int
Daniel Veillardab69f362004-02-17 11:40:32 +00004520xmlTextWriterSetIndentString(xmlTextWriterPtr writer, const xmlChar * str)
Daniel Veillard2cca4462004-01-02 20:04:23 +00004521{
Daniel Veillarde43cc572004-11-03 11:50:29 +00004522 if ((writer == NULL) || (!str))
Daniel Veillardab69f362004-02-17 11:40:32 +00004523 return -1;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004524
Daniel Veillardab69f362004-02-17 11:40:32 +00004525 if (writer->ichar != NULL)
4526 xmlFree(writer->ichar);
4527 writer->ichar = xmlStrdup(str);
4528
4529 if (!writer->ichar)
4530 return -1;
4531 else
4532 return 0;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004533}
4534
4535/**
4536 * xmlTextWriterWriteIndent:
4537 * @writer: the xmlTextWriterPtr
4538 *
4539 * Write indent string.
4540 *
4541 * Returns -1 on error or the number of strings written.
Daniel Veillardab69f362004-02-17 11:40:32 +00004542 */
Daniel Veillard2cca4462004-01-02 20:04:23 +00004543static int
Daniel Veillardab69f362004-02-17 11:40:32 +00004544xmlTextWriterWriteIndent(xmlTextWriterPtr writer)
Daniel Veillard2cca4462004-01-02 20:04:23 +00004545{
Daniel Veillardab69f362004-02-17 11:40:32 +00004546 int lksize;
4547 int i;
4548 int ret;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004549
Daniel Veillardab69f362004-02-17 11:40:32 +00004550 lksize = xmlListSize(writer->nodes);
4551 if (lksize < 1)
4552 return (-1); /* list is empty */
4553 for (i = 0; i < (lksize - 1); i++) {
4554 ret = xmlOutputBufferWriteString(writer->out,
4555 (const char *) writer->ichar);
4556 if (ret == -1)
4557 return (-1);
4558 }
4559
4560 return (lksize - 1);
Daniel Veillard2cca4462004-01-02 20:04:23 +00004561}
4562
Daniel Veillard500a1de2004-03-22 15:22:58 +00004563/**
4564 * xmlTextWriterHandleStateDependencies:
4565 * @writer: the xmlTextWriterPtr
4566 * @p: the xmlTextWriterStackEntry
4567 *
4568 * Write state dependent strings.
4569 *
4570 * Returns -1 on error or the number of characters written.
4571 */
4572static int
4573xmlTextWriterHandleStateDependencies(xmlTextWriterPtr writer,
4574 xmlTextWriterStackEntry * p)
4575{
4576 int count;
4577 int sum;
4578 char extra[3];
4579
4580 if (writer == NULL)
4581 return -1;
4582
4583 if (p == NULL)
4584 return 0;
4585
4586 sum = 0;
4587 extra[0] = extra[1] = extra[2] = '\0';
4588 if (p != 0) {
4589 sum = 0;
4590 switch (p->state) {
4591 case XML_TEXTWRITER_NAME:
4592 extra[0] = '>';
4593 p->state = XML_TEXTWRITER_TEXT;
4594 break;
4595 case XML_TEXTWRITER_PI:
4596 extra[0] = ' ';
4597 p->state = XML_TEXTWRITER_PI_TEXT;
4598 break;
4599 case XML_TEXTWRITER_DTD:
4600 extra[0] = ' ';
4601 extra[1] = '[';
4602 p->state = XML_TEXTWRITER_DTD_TEXT;
4603 break;
4604 case XML_TEXTWRITER_DTD_ELEM:
4605 extra[0] = ' ';
4606 p->state = XML_TEXTWRITER_DTD_ELEM_TEXT;
4607 break;
4608 case XML_TEXTWRITER_DTD_ATTL:
4609 extra[0] = ' ';
4610 p->state = XML_TEXTWRITER_DTD_ATTL_TEXT;
4611 break;
4612 case XML_TEXTWRITER_DTD_ENTY:
4613 case XML_TEXTWRITER_DTD_PENT:
4614 extra[0] = ' ';
4615 extra[1] = writer->qchar;
4616 p->state = XML_TEXTWRITER_DTD_ENTY_TEXT;
4617 break;
4618 default:
4619 break;
4620 }
4621 }
4622
4623 if (*extra != '\0') {
4624 count = xmlOutputBufferWriteString(writer->out, extra);
4625 if (count < 0)
4626 return -1;
4627 sum += count;
4628 }
4629
4630 return sum;
4631}
4632
Daniel Veillard5d4644e2005-04-01 13:11:58 +00004633#define bottom_xmlwriter
4634#include "elfgcchack.h"
Daniel Veillard1d211e22003-10-20 22:32:39 +00004635#endif