blob: 11b15e03571e0973fcd697bdc67d0ff9cfcc824a [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
William M. Brackc1099be2007-01-31 18:38:56 +000012#include "libxml.h"
Daniel Veillard1d211e22003-10-20 22:32:39 +000013#include <string.h>
Daniel Veillard1d211e22003-10-20 22:32:39 +000014
Daniel Veillard1d211e22003-10-20 22:32:39 +000015#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;
Rob Richards9db68f02006-08-16 22:48:51 +000094 xmlDocPtr doc;
Daniel Veillard1d211e22003-10-20 22:32:39 +000095};
96
97static void xmlFreeTextWriterStackEntry(xmlLinkPtr lk);
98static int xmlCmpTextWriterStackEntry(const void *data0,
99 const void *data1);
Rob Richardsb8769d62007-06-08 08:50:47 +0000100static int xmlTextWriterOutputNSDecl(xmlTextWriterPtr writer);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000101static void xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk);
102static int xmlCmpTextWriterNsStackEntry(const void *data0,
103 const void *data1);
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000104static int xmlTextWriterWriteDocCallback(void *context,
105 const xmlChar * str, int len);
106static int xmlTextWriterCloseDocCallback(void *context);
107
Daniel Veillard1d211e22003-10-20 22:32:39 +0000108static xmlChar *xmlTextWriterVSprintf(const char *format, va_list argptr);
109static int xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len,
110 const unsigned char *data);
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000111static void xmlTextWriterStartDocumentCallback(void *ctx);
Daniel Veillardab69f362004-02-17 11:40:32 +0000112static int xmlTextWriterWriteIndent(xmlTextWriterPtr writer);
Daniel Veillard500a1de2004-03-22 15:22:58 +0000113static int
114 xmlTextWriterHandleStateDependencies(xmlTextWriterPtr writer,
115 xmlTextWriterStackEntry * p);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000116
117/**
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000118 * xmlWriterErrMsg:
119 * @ctxt: a writer context
120 * @error: the error number
121 * @msg: the error message
122 *
123 * Handle a writer error
124 */
125static void
126xmlWriterErrMsg(xmlTextWriterPtr ctxt, xmlParserErrors error,
127 const char *msg)
128{
129 if (ctxt != NULL) {
130 __xmlRaiseError(NULL, NULL, NULL, ctxt->ctxt,
131 NULL, XML_FROM_WRITER, error, XML_ERR_FATAL,
Daniel Veillardbccae2d2009-06-04 11:22:45 +0200132 NULL, 0, NULL, NULL, NULL, 0, 0, "%s", msg);
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000133 } else {
134 __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_WRITER, error,
Daniel Veillardbccae2d2009-06-04 11:22:45 +0200135 XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, 0, 0, "%s", msg);
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000136 }
137}
138
139/**
140 * xmlWriterErrMsgInt:
141 * @ctxt: a writer context
142 * @error: the error number
143 * @msg: the error message
144 * @val: an int
145 *
146 * Handle a writer error
147 */
148static void
149xmlWriterErrMsgInt(xmlTextWriterPtr ctxt, xmlParserErrors error,
150 const char *msg, int val)
151{
152 if (ctxt != NULL) {
153 __xmlRaiseError(NULL, NULL, NULL, ctxt->ctxt,
154 NULL, XML_FROM_WRITER, error, XML_ERR_FATAL,
155 NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
156 } else {
157 __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_WRITER, error,
158 XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
159 }
160}
161
162/**
Daniel Veillard1d211e22003-10-20 22:32:39 +0000163 * xmlNewTextWriter:
164 * @out: an xmlOutputBufferPtr
165 *
166 * Create a new xmlNewTextWriter structure using an xmlOutputBufferPtr
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000167 * NOTE: the @out parameter will be deallocated when the writer is closed
168 * (if the call succeed.)
Daniel Veillard1d211e22003-10-20 22:32:39 +0000169 *
170 * Returns the new xmlTextWriterPtr or NULL in case of error
171 */
172xmlTextWriterPtr
173xmlNewTextWriter(xmlOutputBufferPtr out)
174{
175 xmlTextWriterPtr ret;
176
177 ret = (xmlTextWriterPtr) xmlMalloc(sizeof(xmlTextWriter));
178 if (ret == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000179 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000180 "xmlNewTextWriter : out of memory!\n");
181 return NULL;
182 }
183 memset(ret, 0, (size_t) sizeof(xmlTextWriter));
184
185 ret->nodes = xmlListCreate((xmlListDeallocator)
186 xmlFreeTextWriterStackEntry,
187 (xmlListDataCompare)
188 xmlCmpTextWriterStackEntry);
189 if (ret->nodes == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000190 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000191 "xmlNewTextWriter : out of memory!\n");
192 xmlFree(ret);
193 return NULL;
194 }
195
196 ret->nsstack = xmlListCreate((xmlListDeallocator)
197 xmlFreeTextWriterNsStackEntry,
198 (xmlListDataCompare)
199 xmlCmpTextWriterNsStackEntry);
200 if (ret->nsstack == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000201 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000202 "xmlNewTextWriter : out of memory!\n");
Daniel Veillard500a1de2004-03-22 15:22:58 +0000203 xmlListDelete(ret->nodes);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000204 xmlFree(ret);
205 return NULL;
206 }
207
208 ret->out = out;
Daniel Veillardab69f362004-02-17 11:40:32 +0000209 ret->ichar = xmlStrdup(BAD_CAST " ");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000210 ret->qchar = '"';
211
Daniel Veillard500a1de2004-03-22 15:22:58 +0000212 if (!ret->ichar) {
213 xmlListDelete(ret->nodes);
214 xmlListDelete(ret->nsstack);
215 xmlFree(ret);
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000216 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000217 "xmlNewTextWriter : out of memory!\n");
Daniel Veillardab69f362004-02-17 11:40:32 +0000218 return NULL;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000219 }
Rob Richards9db68f02006-08-16 22:48:51 +0000220
221 ret->doc = xmlNewDoc(NULL);
222
Daniel Veillarda521d282004-11-09 14:59:59 +0000223 ret->no_doc_free = 0;
Daniel Veillardab69f362004-02-17 11:40:32 +0000224
Daniel Veillard1d211e22003-10-20 22:32:39 +0000225 return ret;
226}
227
228/**
229 * xmlNewTextWriterFilename:
230 * @uri: the URI of the resource for the output
231 * @compression: compress the output?
232 *
233 * Create a new xmlNewTextWriter structure with @uri as output
234 *
235 * Returns the new xmlTextWriterPtr or NULL in case of error
236 */
237xmlTextWriterPtr
238xmlNewTextWriterFilename(const char *uri, int compression)
239{
240 xmlTextWriterPtr ret;
241 xmlOutputBufferPtr out;
242
243 out = xmlOutputBufferCreateFilename(uri, NULL, compression);
244 if (out == NULL) {
Rob Richards798743a2009-06-19 13:54:25 -0400245 xmlWriterErrMsg(NULL, XML_IO_EIO,
246 "xmlNewTextWriterFilename : cannot open uri\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000247 return NULL;
248 }
249
250 ret = xmlNewTextWriter(out);
251 if (ret == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000252 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000253 "xmlNewTextWriterFilename : out of memory!\n");
254 xmlOutputBufferClose(out);
255 return NULL;
256 }
257
Daniel Veillard2cca4462004-01-02 20:04:23 +0000258 ret->indent = 0;
259 ret->doindent = 0;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000260 return ret;
261}
262
263/**
264 * xmlNewTextWriterMemory:
265 * @buf: xmlBufferPtr
266 * @compression: compress the output?
267 *
268 * Create a new xmlNewTextWriter structure with @buf as output
269 * TODO: handle compression
270 *
271 * Returns the new xmlTextWriterPtr or NULL in case of error
272 */
273xmlTextWriterPtr
274xmlNewTextWriterMemory(xmlBufferPtr buf, int compression ATTRIBUTE_UNUSED)
275{
276 xmlTextWriterPtr ret;
277 xmlOutputBufferPtr out;
278
279/*::todo handle compression */
Rob Richardsa44f2342005-11-09 18:03:45 +0000280 out = xmlOutputBufferCreateBuffer(buf, NULL);
281
Daniel Veillard1d211e22003-10-20 22:32:39 +0000282 if (out == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000283 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000284 "xmlNewTextWriterMemory : out of memory!\n");
285 return NULL;
286 }
287
288 ret = xmlNewTextWriter(out);
289 if (ret == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000290 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000291 "xmlNewTextWriterMemory : out of memory!\n");
292 xmlOutputBufferClose(out);
293 return NULL;
294 }
295
296 return ret;
297}
298
299/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000300 * xmlNewTextWriterPushParser:
301 * @ctxt: xmlParserCtxtPtr to hold the new XML document tree
302 * @compression: compress the output?
303 *
304 * Create a new xmlNewTextWriter structure with @ctxt as output
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000305 * NOTE: the @ctxt context will be freed with the resulting writer
306 * (if the call succeeds).
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000307 * TODO: handle compression
308 *
309 * Returns the new xmlTextWriterPtr or NULL in case of error
310 */
311xmlTextWriterPtr
Daniel Veillard1d913862003-11-21 00:28:39 +0000312xmlNewTextWriterPushParser(xmlParserCtxtPtr ctxt,
313 int compression ATTRIBUTE_UNUSED)
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000314{
315 xmlTextWriterPtr ret;
316 xmlOutputBufferPtr out;
317
Daniel Veillard500a1de2004-03-22 15:22:58 +0000318 if (ctxt == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000319 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000320 "xmlNewTextWriterPushParser : invalid context!\n");
321 return NULL;
322 }
323
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000324 out = xmlOutputBufferCreateIO((xmlOutputWriteCallback)
325 xmlTextWriterWriteDocCallback,
326 (xmlOutputCloseCallback)
327 xmlTextWriterCloseDocCallback,
328 (void *) ctxt, NULL);
329 if (out == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000330 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000331 "xmlNewTextWriterPushParser : error at xmlOutputBufferCreateIO!\n");
332 return NULL;
333 }
334
335 ret = xmlNewTextWriter(out);
336 if (ret == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000337 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000338 "xmlNewTextWriterPushParser : error at xmlNewTextWriter!\n");
339 xmlOutputBufferClose(out);
340 return NULL;
341 }
342
Daniel Veillard20c5e782004-01-21 09:57:31 +0000343 ret->ctxt = ctxt;
344
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000345 return ret;
346}
347
348/**
349 * xmlNewTextWriterDoc:
350 * @doc: address of a xmlDocPtr to hold the new XML document tree
351 * @compression: compress the output?
352 *
353 * Create a new xmlNewTextWriter structure with @*doc as output
354 *
355 * Returns the new xmlTextWriterPtr or NULL in case of error
356 */
357xmlTextWriterPtr
358xmlNewTextWriterDoc(xmlDocPtr * doc, int compression)
359{
360 xmlTextWriterPtr ret;
361 xmlSAXHandler saxHandler;
362 xmlParserCtxtPtr ctxt;
363
364 memset(&saxHandler, '\0', sizeof(saxHandler));
365 xmlSAX2InitDefaultSAXHandler(&saxHandler, 1);
366 saxHandler.startDocument = xmlTextWriterStartDocumentCallback;
367 saxHandler.startElement = xmlSAX2StartElement;
368 saxHandler.endElement = xmlSAX2EndElement;
369
370 ctxt = xmlCreatePushParserCtxt(&saxHandler, NULL, NULL, 0, NULL);
371 if (ctxt == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000372 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillardeb0a0b22009-02-20 08:19:53 +0000373 "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\n");
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000374 return NULL;
375 }
Daniel Veillard03a53c32004-10-26 16:06:51 +0000376 /*
377 * For some reason this seems to completely break if node names
378 * are interned.
379 */
380 ctxt->dictNames = 0;
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000381
Daniel Veillard1d913862003-11-21 00:28:39 +0000382 ctxt->myDoc = xmlNewDoc(BAD_CAST XML_DEFAULT_VERSION);
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000383 if (ctxt->myDoc == NULL) {
384 xmlFreeParserCtxt(ctxt);
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000385 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000386 "xmlNewTextWriterDoc : error at xmlNewDoc!\n");
387 return NULL;
388 }
389
390 ret = xmlNewTextWriterPushParser(ctxt, compression);
391 if (ret == NULL) {
Daniel Veillardeb0a0b22009-02-20 08:19:53 +0000392 xmlFreeDoc(ctxt->myDoc);
393 xmlFreeParserCtxt(ctxt);
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000394 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillardeb0a0b22009-02-20 08:19:53 +0000395 "xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n");
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000396 return NULL;
397 }
398
Daniel Veillard500a1de2004-03-22 15:22:58 +0000399 xmlSetDocCompressMode(ctxt->myDoc, compression);
400
Daniel Veillarda521d282004-11-09 14:59:59 +0000401 if (doc != NULL) {
Daniel Veillard500a1de2004-03-22 15:22:58 +0000402 *doc = ctxt->myDoc;
Daniel Veillarda521d282004-11-09 14:59:59 +0000403 ret->no_doc_free = 1;
404 }
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000405
406 return ret;
407}
408
409/**
410 * xmlNewTextWriterTree:
411 * @doc: xmlDocPtr
412 * @node: xmlNodePtr or NULL for doc->children
413 * @compression: compress the output?
414 *
415 * Create a new xmlNewTextWriter structure with @doc as output
416 * starting at @node
417 *
418 * Returns the new xmlTextWriterPtr or NULL in case of error
419 */
420xmlTextWriterPtr
421xmlNewTextWriterTree(xmlDocPtr doc, xmlNodePtr node, int compression)
422{
423 xmlTextWriterPtr ret;
424 xmlSAXHandler saxHandler;
425 xmlParserCtxtPtr ctxt;
426
427 if (doc == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000428 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000429 "xmlNewTextWriterTree : invalid document tree!\n");
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000430 return NULL;
431 }
432
433 memset(&saxHandler, '\0', sizeof(saxHandler));
434 xmlSAX2InitDefaultSAXHandler(&saxHandler, 1);
435 saxHandler.startDocument = xmlTextWriterStartDocumentCallback;
436 saxHandler.startElement = xmlSAX2StartElement;
437 saxHandler.endElement = xmlSAX2EndElement;
438
439 ctxt = xmlCreatePushParserCtxt(&saxHandler, NULL, NULL, 0, NULL);
440 if (ctxt == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000441 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000442 "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\n");
443 return NULL;
444 }
Daniel Veillard03a53c32004-10-26 16:06:51 +0000445 /*
446 * For some reason this seems to completely break if node names
447 * are interned.
448 */
449 ctxt->dictNames = 0;
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000450
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000451 ret = xmlNewTextWriterPushParser(ctxt, compression);
452 if (ret == NULL) {
Daniel Veillard500a1de2004-03-22 15:22:58 +0000453 xmlFreeParserCtxt(ctxt);
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000454 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000455 "xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n");
456 return NULL;
457 }
458
Daniel Veillard500a1de2004-03-22 15:22:58 +0000459 ctxt->myDoc = doc;
460 ctxt->node = node;
Daniel Veillarda521d282004-11-09 14:59:59 +0000461 ret->no_doc_free = 1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000462
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000463 xmlSetDocCompressMode(doc, compression);
464
465 return ret;
466}
467
468/**
Daniel Veillard1d211e22003-10-20 22:32:39 +0000469 * xmlFreeTextWriter:
470 * @writer: the xmlTextWriterPtr
471 *
472 * Deallocate all the resources associated to the writer
473 */
474void
475xmlFreeTextWriter(xmlTextWriterPtr writer)
476{
477 if (writer == NULL)
478 return;
479
480 if (writer->out != NULL)
481 xmlOutputBufferClose(writer->out);
482
483 if (writer->nodes != NULL)
484 xmlListDelete(writer->nodes);
485
486 if (writer->nsstack != NULL)
487 xmlListDelete(writer->nsstack);
488
Daniel Veillarda521d282004-11-09 14:59:59 +0000489 if (writer->ctxt != NULL) {
490 if ((writer->ctxt->myDoc != NULL) && (writer->no_doc_free == 0)) {
491 xmlFreeDoc(writer->ctxt->myDoc);
492 writer->ctxt->myDoc = NULL;
493 }
Daniel Veillard20c5e782004-01-21 09:57:31 +0000494 xmlFreeParserCtxt(writer->ctxt);
Daniel Veillarda521d282004-11-09 14:59:59 +0000495 }
Daniel Veillard20c5e782004-01-21 09:57:31 +0000496
Rob Richards9db68f02006-08-16 22:48:51 +0000497 if (writer->doc != NULL)
498 xmlFreeDoc(writer->doc);
499
Daniel Veillard4773df22004-01-23 13:15:13 +0000500 if (writer->ichar != NULL)
501 xmlFree(writer->ichar);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000502 xmlFree(writer);
503}
504
505/**
506 * xmlTextWriterStartDocument:
507 * @writer: the xmlTextWriterPtr
508 * @version: the xml version ("1.0") or NULL for default ("1.0")
509 * @encoding: the encoding or NULL for default
510 * @standalone: "yes" or "no" or NULL for default
511 *
512 * Start a new xml document
513 *
514 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
515 */
516int
517xmlTextWriterStartDocument(xmlTextWriterPtr writer, const char *version,
518 const char *encoding, const char *standalone)
519{
520 int count;
521 int sum;
522 xmlLinkPtr lk;
523 xmlCharEncodingHandlerPtr encoder;
524
Daniel Veillard500a1de2004-03-22 15:22:58 +0000525 if ((writer == NULL) || (writer->out == NULL)) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000526 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000527 "xmlTextWriterStartDocument : invalid writer!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000528 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000529 }
Daniel Veillard1d211e22003-10-20 22:32:39 +0000530
531 lk = xmlListFront(writer->nodes);
532 if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000533 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000534 "xmlTextWriterStartDocument : not allowed in this context!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000535 return -1;
536 }
537
538 encoder = NULL;
539 if (encoding != NULL) {
540 encoder = xmlFindCharEncodingHandler(encoding);
541 if (encoder == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000542 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000543 "xmlTextWriterStartDocument : out of memory!\n");
544 return -1;
545 }
546 }
547
548 writer->out->encoder = encoder;
549 if (encoder != NULL) {
Daniel Veillardcaa19512007-07-04 15:42:46 +0000550 if (writer->out->conv == NULL) {
551 writer->out->conv = xmlBufferCreateSize(4000);
552 }
Daniel Veillard1d211e22003-10-20 22:32:39 +0000553 xmlCharEncOutFunc(encoder, writer->out->conv, NULL);
Rob Richards9db68f02006-08-16 22:48:51 +0000554 if ((writer->doc != NULL) && (writer->doc->encoding == NULL))
555 writer->doc->encoding = xmlStrdup((xmlChar *)writer->out->encoder->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000556 } else
557 writer->out->conv = NULL;
558
559 sum = 0;
560 count = xmlOutputBufferWriteString(writer->out, "<?xml version=");
561 if (count < 0)
562 return -1;
563 sum += count;
564 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
565 if (count < 0)
566 return -1;
567 sum += count;
568 if (version != 0)
569 count = xmlOutputBufferWriteString(writer->out, version);
570 else
571 count = xmlOutputBufferWriteString(writer->out, "1.0");
572 if (count < 0)
573 return -1;
574 sum += count;
575 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
576 if (count < 0)
577 return -1;
578 sum += count;
579 if (writer->out->encoder != 0) {
580 count = xmlOutputBufferWriteString(writer->out, " encoding=");
581 if (count < 0)
582 return -1;
583 sum += count;
584 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
585 if (count < 0)
586 return -1;
587 sum += count;
588 count =
589 xmlOutputBufferWriteString(writer->out,
590 writer->out->encoder->name);
591 if (count < 0)
592 return -1;
593 sum += count;
594 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
595 if (count < 0)
596 return -1;
597 sum += count;
598 }
599
600 if (standalone != 0) {
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 count = xmlOutputBufferWriteString(writer->out, standalone);
610 if (count < 0)
611 return -1;
612 sum += count;
613 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
614 if (count < 0)
615 return -1;
616 sum += count;
617 }
618
619 count = xmlOutputBufferWriteString(writer->out, "?>\n");
620 if (count < 0)
621 return -1;
622 sum += count;
623
624 return sum;
625}
626
627/**
628 * xmlTextWriterEndDocument:
629 * @writer: the xmlTextWriterPtr
630 *
Daniel Veillard3ff24112008-02-13 10:17:41 +0000631 * End an xml document. All open elements are closed, and
632 * the content is flushed to the output.
Daniel Veillard1d211e22003-10-20 22:32:39 +0000633 *
Daniel Veillard3ff24112008-02-13 10:17:41 +0000634 * Returns the bytes written or -1 in case of error
Daniel Veillard1d211e22003-10-20 22:32:39 +0000635 */
636int
637xmlTextWriterEndDocument(xmlTextWriterPtr writer)
638{
639 int count;
640 int sum;
641 xmlLinkPtr lk;
642 xmlTextWriterStackEntry *p;
643
Daniel Veillard500a1de2004-03-22 15:22:58 +0000644 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000645 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000646 "xmlTextWriterEndDocument : invalid writer!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000647 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000648 }
Daniel Veillard1d211e22003-10-20 22:32:39 +0000649
650 sum = 0;
651 while ((lk = xmlListFront(writer->nodes)) != NULL) {
652 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
653 if (p == 0)
654 break;
655 switch (p->state) {
656 case XML_TEXTWRITER_NAME:
657 case XML_TEXTWRITER_ATTRIBUTE:
658 case XML_TEXTWRITER_TEXT:
659 count = xmlTextWriterEndElement(writer);
660 if (count < 0)
661 return -1;
662 sum += count;
663 break;
664 case XML_TEXTWRITER_PI:
665 case XML_TEXTWRITER_PI_TEXT:
666 count = xmlTextWriterEndPI(writer);
667 if (count < 0)
668 return -1;
669 sum += count;
670 break;
671 case XML_TEXTWRITER_CDATA:
672 count = xmlTextWriterEndCDATA(writer);
673 if (count < 0)
674 return -1;
675 sum += count;
676 break;
677 case XML_TEXTWRITER_DTD:
Daniel Veillard500a1de2004-03-22 15:22:58 +0000678 case XML_TEXTWRITER_DTD_TEXT:
679 case XML_TEXTWRITER_DTD_ELEM:
680 case XML_TEXTWRITER_DTD_ELEM_TEXT:
681 case XML_TEXTWRITER_DTD_ATTL:
682 case XML_TEXTWRITER_DTD_ATTL_TEXT:
683 case XML_TEXTWRITER_DTD_ENTY:
684 case XML_TEXTWRITER_DTD_ENTY_TEXT:
685 case XML_TEXTWRITER_DTD_PENT:
Daniel Veillard1d211e22003-10-20 22:32:39 +0000686 count = xmlTextWriterEndDTD(writer);
687 if (count < 0)
688 return -1;
689 sum += count;
690 break;
Daniel Veillardab69f362004-02-17 11:40:32 +0000691 case XML_TEXTWRITER_COMMENT:
692 count = xmlTextWriterEndComment(writer);
693 if (count < 0)
694 return -1;
695 sum += count;
696 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000697 default:
Daniel Veillardab69f362004-02-17 11:40:32 +0000698 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000699 }
700 }
701
Daniel Veillard2cca4462004-01-02 20:04:23 +0000702 if (!writer->indent) {
Daniel Veillardab69f362004-02-17 11:40:32 +0000703 count = xmlOutputBufferWriteString(writer->out, "\n");
704 if (count < 0)
705 return -1;
706 sum += count;
707 }
Daniel Veillard3ff24112008-02-13 10:17:41 +0000708
709 sum += xmlTextWriterFlush(writer);
710
Daniel Veillardab69f362004-02-17 11:40:32 +0000711 return sum;
712}
713
Daniel Veillardab69f362004-02-17 11:40:32 +0000714/**
715 * xmlTextWriterStartComment:
716 * @writer: the xmlTextWriterPtr
717 *
718 * Start an xml comment.
719 *
720 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
721 */
722int
723xmlTextWriterStartComment(xmlTextWriterPtr writer)
724{
725 int count;
726 int sum;
727 xmlLinkPtr lk;
728 xmlTextWriterStackEntry *p;
729
Daniel Veillard500a1de2004-03-22 15:22:58 +0000730 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000731 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000732 "xmlTextWriterStartComment : invalid writer!\n");
Daniel Veillardab69f362004-02-17 11:40:32 +0000733 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000734 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000735
736 sum = 0;
737 lk = xmlListFront(writer->nodes);
738 if (lk != 0) {
739 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
740 if (p != 0) {
741 switch (p->state) {
742 case XML_TEXTWRITER_TEXT:
743 case XML_TEXTWRITER_NONE:
744 break;
745 case XML_TEXTWRITER_NAME:
Rob Richardsb8769d62007-06-08 08:50:47 +0000746 /* Output namespace declarations */
747 count = xmlTextWriterOutputNSDecl(writer);
748 if (count < 0)
749 return -1;
750 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +0000751 count = xmlOutputBufferWriteString(writer->out, ">");
752 if (count < 0)
753 return -1;
754 sum += count;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000755 if (writer->indent) {
756 count =
757 xmlOutputBufferWriteString(writer->out, "\n");
758 if (count < 0)
759 return -1;
760 sum += count;
761 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000762 p->state = XML_TEXTWRITER_TEXT;
763 break;
764 default:
765 return -1;
766 }
767 }
768 }
769
770 p = (xmlTextWriterStackEntry *)
771 xmlMalloc(sizeof(xmlTextWriterStackEntry));
772 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000773 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillardab69f362004-02-17 11:40:32 +0000774 "xmlTextWriterStartElement : out of memory!\n");
775 return -1;
776 }
777
Daniel Veillard75e389d2005-07-29 22:02:24 +0000778 p->name = NULL;
Daniel Veillardab69f362004-02-17 11:40:32 +0000779 p->state = XML_TEXTWRITER_COMMENT;
780
781 xmlListPushFront(writer->nodes, p);
782
783 if (writer->indent) {
Daniel Veillardab69f362004-02-17 11:40:32 +0000784 count = xmlTextWriterWriteIndent(writer);
785 if (count < 0)
786 return -1;
787 sum += count;
788 }
789
790 count = xmlOutputBufferWriteString(writer->out, "<!--");
791 if (count < 0)
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000792 return -1;
793 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +0000794
795 return sum;
796}
797
798/**
799 * xmlTextWriterEndComment:
800 * @writer: the xmlTextWriterPtr
801 *
802 * End the current xml coment.
803 *
804 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
805 */
806int
807xmlTextWriterEndComment(xmlTextWriterPtr writer)
808{
809 int count;
810 int sum;
811 xmlLinkPtr lk;
812 xmlTextWriterStackEntry *p;
813
Daniel Veillard500a1de2004-03-22 15:22:58 +0000814 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000815 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000816 "xmlTextWriterEndComment : invalid writer!\n");
Daniel Veillardab69f362004-02-17 11:40:32 +0000817 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000818 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000819
820 lk = xmlListFront(writer->nodes);
Daniel Veillard500a1de2004-03-22 15:22:58 +0000821 if (lk == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000822 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000823 "xmlTextWriterEndComment : not allowed in this context!\n");
Daniel Veillardab69f362004-02-17 11:40:32 +0000824 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000825 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000826
827 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
828 if (p == 0)
829 return -1;
830
831 sum = 0;
832 switch (p->state) {
833 case XML_TEXTWRITER_COMMENT:
834 count = xmlOutputBufferWriteString(writer->out, "-->");
835 if (count < 0)
836 return -1;
837 sum += count;
838 break;
839 default:
840 return -1;
Daniel Veillard2cca4462004-01-02 20:04:23 +0000841 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000842
843 if (writer->indent) {
844 count = xmlOutputBufferWriteString(writer->out, "\n");
845 if (count < 0)
846 return -1;
847 sum += count;
848 }
849
850 xmlListPopFront(writer->nodes);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000851 return sum;
852}
853
854/**
855 * xmlTextWriterWriteFormatComment:
856 * @writer: the xmlTextWriterPtr
857 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +0000858 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +0000859 *
860 * Write an xml comment.
861 *
862 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
863 */
Daniel Veillardffa3c742005-07-21 13:24:09 +0000864int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +0000865xmlTextWriterWriteFormatComment(xmlTextWriterPtr writer,
866 const char *format, ...)
867{
868 int rc;
869 va_list ap;
870
871 va_start(ap, format);
872
873 rc = xmlTextWriterWriteVFormatComment(writer, format, ap);
874
875 va_end(ap);
876 return rc;
877}
878
879/**
880 * xmlTextWriterWriteVFormatComment:
881 * @writer: the xmlTextWriterPtr
882 * @format: format string (see printf)
883 * @argptr: pointer to the first member of the variable argument list.
884 *
885 * Write an xml comment.
886 *
887 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
888 */
889int
890xmlTextWriterWriteVFormatComment(xmlTextWriterPtr writer,
891 const char *format, va_list argptr)
892{
893 int rc;
894 xmlChar *buf;
895
Daniel Veillard500a1de2004-03-22 15:22:58 +0000896 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000897 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000898 "xmlTextWriterWriteVFormatComment : invalid writer!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000899 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000900 }
Daniel Veillard1d211e22003-10-20 22:32:39 +0000901
902 buf = xmlTextWriterVSprintf(format, argptr);
Daniel Veillardcb0ae192009-02-20 08:40:55 +0000903 if (buf == NULL)
904 return -1;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000905
906 rc = xmlTextWriterWriteComment(writer, buf);
907
908 xmlFree(buf);
909 return rc;
910}
911
912/**
913 * xmlTextWriterWriteComment:
914 * @writer: the xmlTextWriterPtr
915 * @content: comment string
916 *
917 * Write an xml comment.
918 *
919 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
920 */
921int
922xmlTextWriterWriteComment(xmlTextWriterPtr writer, const xmlChar * content)
923{
924 int count;
925 int sum;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000926
927 sum = 0;
Daniel Veillardab69f362004-02-17 11:40:32 +0000928 count = xmlTextWriterStartComment(writer);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000929 if (count < 0)
930 return -1;
931 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +0000932 count = xmlTextWriterWriteString(writer, content);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000933 if (count < 0)
934 return -1;
935 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +0000936 count = xmlTextWriterEndComment(writer);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000937 if (count < 0)
938 return -1;
939 sum += count;
940
941 return sum;
942}
943
944/**
945 * xmlTextWriterStartElement:
946 * @writer: the xmlTextWriterPtr
947 * @name: element name
948 *
949 * Start an xml element.
950 *
951 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
952 */
953int
954xmlTextWriterStartElement(xmlTextWriterPtr writer, const xmlChar * name)
955{
956 int count;
957 int sum;
958 xmlLinkPtr lk;
959 xmlTextWriterStackEntry *p;
960
961 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
962 return -1;
963
964 sum = 0;
965 lk = xmlListFront(writer->nodes);
966 if (lk != 0) {
967 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
968 if (p != 0) {
969 switch (p->state) {
970 case XML_TEXTWRITER_PI:
971 case XML_TEXTWRITER_PI_TEXT:
972 return -1;
973 case XML_TEXTWRITER_NONE:
974 break;
Daniel Veillard614fdc12005-02-23 14:05:37 +0000975 case XML_TEXTWRITER_ATTRIBUTE:
976 count = xmlTextWriterEndAttribute(writer);
977 if (count < 0)
978 return -1;
979 sum += count;
980 /* fallthrough */
Daniel Veillard1d211e22003-10-20 22:32:39 +0000981 case XML_TEXTWRITER_NAME:
Rob Richardsb8769d62007-06-08 08:50:47 +0000982 /* Output namespace declarations */
983 count = xmlTextWriterOutputNSDecl(writer);
984 if (count < 0)
985 return -1;
986 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000987 count = xmlOutputBufferWriteString(writer->out, ">");
988 if (count < 0)
989 return -1;
990 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +0000991 if (writer->indent)
992 count =
993 xmlOutputBufferWriteString(writer->out, "\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000994 p->state = XML_TEXTWRITER_TEXT;
995 break;
Daniel Veillardab69f362004-02-17 11:40:32 +0000996 default:
997 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000998 }
999 }
1000 }
1001
1002 p = (xmlTextWriterStackEntry *)
1003 xmlMalloc(sizeof(xmlTextWriterStackEntry));
1004 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00001005 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00001006 "xmlTextWriterStartElement : out of memory!\n");
1007 return -1;
1008 }
1009
1010 p->name = xmlStrdup(name);
1011 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00001012 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00001013 "xmlTextWriterStartElement : out of memory!\n");
1014 xmlFree(p);
1015 return -1;
1016 }
1017 p->state = XML_TEXTWRITER_NAME;
1018
1019 xmlListPushFront(writer->nodes, p);
1020
Daniel Veillardab69f362004-02-17 11:40:32 +00001021 if (writer->indent) {
1022 count = xmlTextWriterWriteIndent(writer);
1023 sum += count;
Daniel Veillard2cca4462004-01-02 20:04:23 +00001024 }
1025
Daniel Veillard1d211e22003-10-20 22:32:39 +00001026 count = xmlOutputBufferWriteString(writer->out, "<");
1027 if (count < 0)
1028 return -1;
1029 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00001030 count =
1031 xmlOutputBufferWriteString(writer->out, (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001032 if (count < 0)
1033 return -1;
1034 sum += count;
1035
1036 return sum;
1037}
1038
1039/**
1040 * xmlTextWriterStartElementNS:
1041 * @writer: the xmlTextWriterPtr
1042 * @prefix: namespace prefix or NULL
1043 * @name: element local name
1044 * @namespaceURI: namespace URI or NULL
1045 *
1046 * Start an xml element with namespace support.
1047 *
1048 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1049 */
1050int
1051xmlTextWriterStartElementNS(xmlTextWriterPtr writer,
1052 const xmlChar * prefix, const xmlChar * name,
1053 const xmlChar * namespaceURI)
1054{
1055 int count;
1056 int sum;
1057 xmlChar *buf;
1058
1059 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1060 return -1;
1061
Daniel Veillard75e389d2005-07-29 22:02:24 +00001062 buf = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001063 if (prefix != 0) {
1064 buf = xmlStrdup(prefix);
1065 buf = xmlStrcat(buf, BAD_CAST ":");
1066 }
1067 buf = xmlStrcat(buf, name);
1068
1069 sum = 0;
1070 count = xmlTextWriterStartElement(writer, buf);
1071 xmlFree(buf);
1072 if (count < 0)
1073 return -1;
1074 sum += count;
1075
1076 if (namespaceURI != 0) {
Rob Richardsb8769d62007-06-08 08:50:47 +00001077 xmlTextWriterNsStackEntry *p = (xmlTextWriterNsStackEntry *)
1078 xmlMalloc(sizeof(xmlTextWriterNsStackEntry));
1079 if (p == 0) {
1080 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
1081 "xmlTextWriterStartElementNS : out of memory!\n");
1082 return -1;
1083 }
1084
Daniel Veillard1d211e22003-10-20 22:32:39 +00001085 buf = xmlStrdup(BAD_CAST "xmlns");
1086 if (prefix != 0) {
1087 buf = xmlStrcat(buf, BAD_CAST ":");
1088 buf = xmlStrcat(buf, prefix);
1089 }
1090
Rob Richardsb8769d62007-06-08 08:50:47 +00001091 p->prefix = buf;
1092 p->uri = xmlStrdup(namespaceURI);
1093 if (p->uri == 0) {
1094 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
1095 "xmlTextWriterStartElementNS : out of memory!\n");
1096 xmlFree(p);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001097 return -1;
Rob Richardsb8769d62007-06-08 08:50:47 +00001098 }
1099 p->elem = xmlListFront(writer->nodes);
1100
1101 xmlListPushFront(writer->nsstack, p);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001102 }
1103
1104 return sum;
1105}
1106
1107/**
1108 * xmlTextWriterEndElement:
1109 * @writer: the xmlTextWriterPtr
1110 *
1111 * End the current xml element.
1112 *
1113 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1114 */
1115int
1116xmlTextWriterEndElement(xmlTextWriterPtr writer)
1117{
1118 int count;
1119 int sum;
1120 xmlLinkPtr lk;
1121 xmlTextWriterStackEntry *p;
1122
1123 if (writer == NULL)
1124 return -1;
1125
1126 lk = xmlListFront(writer->nodes);
Rob Richardsb8769d62007-06-08 08:50:47 +00001127 if (lk == 0) {
1128 xmlListDelete(writer->nsstack);
1129 writer->nsstack = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001130 return -1;
Rob Richardsb8769d62007-06-08 08:50:47 +00001131 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001132
1133 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
Rob Richardsb8769d62007-06-08 08:50:47 +00001134 if (p == 0) {
1135 xmlListDelete(writer->nsstack);
1136 writer->nsstack = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001137 return -1;
Rob Richardsb8769d62007-06-08 08:50:47 +00001138 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001139
1140 sum = 0;
1141 switch (p->state) {
1142 case XML_TEXTWRITER_ATTRIBUTE:
1143 count = xmlTextWriterEndAttribute(writer);
Rob Richardsb8769d62007-06-08 08:50:47 +00001144 if (count < 0) {
1145 xmlListDelete(writer->nsstack);
1146 writer->nsstack = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001147 return -1;
Rob Richardsb8769d62007-06-08 08:50:47 +00001148 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001149 sum += count;
1150 /* fallthrough */
1151 case XML_TEXTWRITER_NAME:
Rob Richardsb8769d62007-06-08 08:50:47 +00001152 /* Output namespace declarations */
1153 count = xmlTextWriterOutputNSDecl(writer);
1154 if (count < 0)
1155 return -1;
1156 sum += count;
1157
Daniel Veillardab69f362004-02-17 11:40:32 +00001158 if (writer->indent) /* next element needs indent */
1159 writer->doindent = 1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001160 count = xmlOutputBufferWriteString(writer->out, "/>");
1161 if (count < 0)
1162 return -1;
1163 sum += count;
1164 break;
1165 case XML_TEXTWRITER_TEXT:
Daniel Veillardab69f362004-02-17 11:40:32 +00001166 if ((writer->indent) && (writer->doindent)) {
1167 count = xmlTextWriterWriteIndent(writer);
1168 sum += count;
1169 writer->doindent = 1;
1170 } else
1171 writer->doindent = 1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001172 count = xmlOutputBufferWriteString(writer->out, "</");
1173 if (count < 0)
1174 return -1;
1175 sum += count;
1176 count = xmlOutputBufferWriteString(writer->out,
Daniel Veillardab69f362004-02-17 11:40:32 +00001177 (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001178 if (count < 0)
1179 return -1;
1180 sum += count;
1181 count = xmlOutputBufferWriteString(writer->out, ">");
1182 if (count < 0)
1183 return -1;
1184 sum += count;
1185 break;
1186 default:
1187 return -1;
1188 }
1189
Daniel Veillard2cca4462004-01-02 20:04:23 +00001190 if (writer->indent) {
Daniel Veillardab69f362004-02-17 11:40:32 +00001191 count = xmlOutputBufferWriteString(writer->out, "\n");
1192 sum += count;
Daniel Veillard2cca4462004-01-02 20:04:23 +00001193 }
1194
Daniel Veillard1d211e22003-10-20 22:32:39 +00001195 xmlListPopFront(writer->nodes);
1196 return sum;
1197}
1198
1199/**
1200 * xmlTextWriterFullEndElement:
1201 * @writer: the xmlTextWriterPtr
1202 *
1203 * End the current xml element. Writes an end tag even if the element is empty
1204 *
1205 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1206 */
1207int
1208xmlTextWriterFullEndElement(xmlTextWriterPtr writer)
1209{
1210 int count;
1211 int sum;
1212 xmlLinkPtr lk;
1213 xmlTextWriterStackEntry *p;
1214
1215 if (writer == NULL)
1216 return -1;
1217
1218 lk = xmlListFront(writer->nodes);
1219 if (lk == 0)
1220 return -1;
1221
1222 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1223 if (p == 0)
1224 return -1;
1225
1226 sum = 0;
1227 switch (p->state) {
1228 case XML_TEXTWRITER_ATTRIBUTE:
1229 count = xmlTextWriterEndAttribute(writer);
1230 if (count < 0)
1231 return -1;
1232 sum += count;
1233 /* fallthrough */
1234 case XML_TEXTWRITER_NAME:
Rob Richardsb8769d62007-06-08 08:50:47 +00001235 /* Output namespace declarations */
1236 count = xmlTextWriterOutputNSDecl(writer);
1237 if (count < 0)
1238 return -1;
1239 sum += count;
1240
Daniel Veillard1d211e22003-10-20 22:32:39 +00001241 count = xmlOutputBufferWriteString(writer->out, ">");
1242 if (count < 0)
1243 return -1;
1244 sum += count;
Rob Richards5a7d8bd2008-12-27 13:17:43 +00001245 if (writer->indent)
1246 writer->doindent = 0;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001247 /* fallthrough */
1248 case XML_TEXTWRITER_TEXT:
Rob Richards5a7d8bd2008-12-27 13:17:43 +00001249 if ((writer->indent) && (writer->doindent)) {
1250 count = xmlTextWriterWriteIndent(writer);
1251 sum += count;
1252 writer->doindent = 1;
1253 } else
1254 writer->doindent = 1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001255 count = xmlOutputBufferWriteString(writer->out, "</");
1256 if (count < 0)
1257 return -1;
1258 sum += count;
1259 count = xmlOutputBufferWriteString(writer->out,
Daniel Veillardab69f362004-02-17 11:40:32 +00001260 (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001261 if (count < 0)
1262 return -1;
1263 sum += count;
1264 count = xmlOutputBufferWriteString(writer->out, ">");
1265 if (count < 0)
1266 return -1;
1267 sum += count;
1268 break;
1269 default:
1270 return -1;
1271 }
1272
Daniel Veillard7e26fb42008-01-09 02:19:50 +00001273 if (writer->indent) {
1274 count = xmlOutputBufferWriteString(writer->out, "\n");
1275 sum += count;
1276 }
1277
Daniel Veillard1d211e22003-10-20 22:32:39 +00001278 xmlListPopFront(writer->nodes);
1279 return sum;
1280}
1281
1282/**
1283 * xmlTextWriterWriteFormatRaw:
1284 * @writer: the xmlTextWriterPtr
1285 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001286 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001287 *
1288 * Write a formatted raw xml text.
1289 *
1290 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1291 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00001292int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00001293xmlTextWriterWriteFormatRaw(xmlTextWriterPtr writer, const char *format,
1294 ...)
1295{
1296 int rc;
1297 va_list ap;
1298
1299 va_start(ap, format);
1300
1301 rc = xmlTextWriterWriteVFormatRaw(writer, format, ap);
1302
1303 va_end(ap);
1304 return rc;
1305}
1306
1307/**
1308 * xmlTextWriterWriteVFormatRaw:
1309 * @writer: the xmlTextWriterPtr
1310 * @format: format string (see printf)
1311 * @argptr: pointer to the first member of the variable argument list.
1312 *
1313 * Write a formatted raw xml text.
1314 *
1315 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1316 */
1317int
1318xmlTextWriterWriteVFormatRaw(xmlTextWriterPtr writer, const char *format,
1319 va_list argptr)
1320{
1321 int rc;
1322 xmlChar *buf;
1323
1324 if (writer == NULL)
1325 return -1;
1326
1327 buf = xmlTextWriterVSprintf(format, argptr);
Daniel Veillardcb0ae192009-02-20 08:40:55 +00001328 if (buf == NULL)
1329 return -1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001330
1331 rc = xmlTextWriterWriteRaw(writer, buf);
1332
1333 xmlFree(buf);
1334 return rc;
1335}
1336
1337/**
Daniel Veillard1e906612003-12-05 14:57:46 +00001338 * xmlTextWriterWriteRawLen:
Daniel Veillard1d211e22003-10-20 22:32:39 +00001339 * @writer: the xmlTextWriterPtr
1340 * @content: text string
1341 * @len: length of the text string
1342 *
1343 * Write an xml text.
1344 * TODO: what about entities and special chars??
1345 *
1346 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1347 */
1348int
1349xmlTextWriterWriteRawLen(xmlTextWriterPtr writer, const xmlChar * content,
1350 int len)
1351{
1352 int count;
1353 int sum;
1354 xmlLinkPtr lk;
1355 xmlTextWriterStackEntry *p;
1356
Daniel Veillard500a1de2004-03-22 15:22:58 +00001357 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00001358 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00001359 "xmlTextWriterWriteRawLen : invalid writer!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +00001360 return -1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001361 }
1362
Daniel Veillarde43cc572004-11-03 11:50:29 +00001363 if ((content == NULL) || (len < 0)) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00001364 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00001365 "xmlTextWriterWriteRawLen : invalid content!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +00001366 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001367 }
1368
1369 sum = 0;
1370 lk = xmlListFront(writer->nodes);
1371 if (lk != 0) {
1372 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1373 count = xmlTextWriterHandleStateDependencies(writer, p);
1374 if (count < 0)
1375 return -1;
1376 sum += count;
1377 }
1378
1379 if (writer->indent)
1380 writer->doindent = 0;
1381
1382 if (content != NULL) {
1383 count =
1384 xmlOutputBufferWrite(writer->out, len, (const char *) content);
1385 if (count < 0)
1386 return -1;
1387 sum += count;
1388 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001389
1390 return sum;
1391}
1392
1393/**
1394 * xmlTextWriterWriteRaw:
1395 * @writer: the xmlTextWriterPtr
1396 * @content: text string
1397 *
1398 * Write a raw xml text.
1399 *
1400 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1401 */
1402int
1403xmlTextWriterWriteRaw(xmlTextWriterPtr writer, const xmlChar * content)
1404{
1405 return xmlTextWriterWriteRawLen(writer, content, xmlStrlen(content));
1406}
1407
1408/**
1409 * xmlTextWriterWriteFormatString:
1410 * @writer: the xmlTextWriterPtr
1411 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001412 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001413 *
1414 * Write a formatted xml text.
1415 *
1416 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1417 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00001418int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00001419xmlTextWriterWriteFormatString(xmlTextWriterPtr writer, const char *format,
1420 ...)
1421{
1422 int rc;
1423 va_list ap;
1424
Daniel Veillarde43cc572004-11-03 11:50:29 +00001425 if ((writer == NULL) || (format == NULL))
1426 return -1;
1427
Daniel Veillard1d211e22003-10-20 22:32:39 +00001428 va_start(ap, format);
1429
1430 rc = xmlTextWriterWriteVFormatString(writer, format, ap);
1431
1432 va_end(ap);
1433 return rc;
1434}
1435
1436/**
1437 * xmlTextWriterWriteVFormatString:
1438 * @writer: the xmlTextWriterPtr
1439 * @format: format string (see printf)
1440 * @argptr: pointer to the first member of the variable argument list.
1441 *
1442 * Write a formatted xml text.
1443 *
1444 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1445 */
1446int
1447xmlTextWriterWriteVFormatString(xmlTextWriterPtr writer,
1448 const char *format, va_list argptr)
1449{
1450 int rc;
1451 xmlChar *buf;
1452
Daniel Veillarde43cc572004-11-03 11:50:29 +00001453 if ((writer == NULL) || (format == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00001454 return -1;
1455
1456 buf = xmlTextWriterVSprintf(format, argptr);
Daniel Veillardcb0ae192009-02-20 08:40:55 +00001457 if (buf == NULL)
1458 return -1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001459
1460 rc = xmlTextWriterWriteString(writer, buf);
1461
1462 xmlFree(buf);
1463 return rc;
1464}
1465
1466/**
1467 * xmlTextWriterWriteString:
1468 * @writer: the xmlTextWriterPtr
1469 * @content: text string
1470 *
1471 * Write an xml text.
1472 *
1473 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1474 */
1475int
1476xmlTextWriterWriteString(xmlTextWriterPtr writer, const xmlChar * content)
1477{
Daniel Veillard500a1de2004-03-22 15:22:58 +00001478 int count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001479 int sum;
1480 xmlLinkPtr lk;
1481 xmlTextWriterStackEntry *p;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001482 xmlChar *buf;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001483
Daniel Veillarde43cc572004-11-03 11:50:29 +00001484 if ((writer == NULL) || (content == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00001485 return -1;
1486
Daniel Veillard1d211e22003-10-20 22:32:39 +00001487 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001488 buf = (xmlChar *) content;
1489 lk = xmlListFront(writer->nodes);
1490 if (lk != 0) {
1491 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1492 if (p != 0) {
1493 switch (p->state) {
1494 case XML_TEXTWRITER_NAME:
1495 case XML_TEXTWRITER_TEXT:
Daniel Veillard62040be2004-05-17 03:17:26 +00001496#if 0
1497 buf = NULL;
1498 xmlOutputBufferWriteEscape(writer->out, content, NULL);
1499#endif
Daniel Veillard500a1de2004-03-22 15:22:58 +00001500 buf = xmlEncodeSpecialChars(NULL, content);
1501 break;
1502 case XML_TEXTWRITER_ATTRIBUTE:
1503 buf = NULL;
Rob Richards9db68f02006-08-16 22:48:51 +00001504 xmlAttrSerializeTxtContent(writer->out->buffer, writer->doc,
Daniel Veillard500a1de2004-03-22 15:22:58 +00001505 NULL, content);
1506 break;
William M. Brack87640d52004-04-17 14:58:15 +00001507 default:
1508 break;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001509 }
1510 }
1511 }
1512
1513 if (buf != NULL) {
1514 count = xmlTextWriterWriteRaw(writer, buf);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001515
Daniel Veillard500a1de2004-03-22 15:22:58 +00001516 if (buf != content) /* buf was allocated by us, so free it */
1517 xmlFree(buf);
Daniel Veillardeb0a0b22009-02-20 08:19:53 +00001518
1519 if (count < 0)
1520 return -1;
1521 sum += count;
William M. Bracka9c612c2004-02-01 10:04:05 +00001522 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001523
1524 return sum;
1525}
1526
1527/**
1528 * xmlOutputBufferWriteBase64:
1529 * @out: the xmlOutputBufferPtr
1530 * @data: binary data
1531 * @len: the number of bytes to encode
1532 *
1533 * Write base64 encoded data to an xmlOutputBuffer.
1534 * Adapted from John Walker's base64.c (http://www.fourmilab.ch/).
1535 *
1536 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1537 */
1538static int
1539xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len,
1540 const unsigned char *data)
1541{
1542 static unsigned char dtable[64] =
William M. Brack47a31882004-09-11 16:09:09 +00001543 {'A','B','C','D','E','F','G','H','I','J','K','L','M',
1544 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
1545 'a','b','c','d','e','f','g','h','i','j','k','l','m',
1546 'n','o','p','q','r','s','t','u','v','w','x','y','z',
1547 '0','1','2','3','4','5','6','7','8','9','+','/'};
1548
Daniel Veillard1d211e22003-10-20 22:32:39 +00001549 int i;
1550 int linelen;
1551 int count;
1552 int sum;
1553
Daniel Veillarde43cc572004-11-03 11:50:29 +00001554 if ((out == NULL) || (len < 0) || (data == NULL))
1555 return(-1);
1556
Daniel Veillard1d211e22003-10-20 22:32:39 +00001557 linelen = 0;
1558 sum = 0;
1559
1560 i = 0;
1561 while (1) {
1562 unsigned char igroup[3];
1563 unsigned char ogroup[4];
1564 int c;
1565 int n;
1566
1567 igroup[0] = igroup[1] = igroup[2] = 0;
1568 for (n = 0; n < 3 && i < len; n++, i++) {
1569 c = data[i];
1570 igroup[n] = (unsigned char) c;
1571 }
1572
1573 if (n > 0) {
1574 ogroup[0] = dtable[igroup[0] >> 2];
1575 ogroup[1] = dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)];
1576 ogroup[2] =
1577 dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)];
1578 ogroup[3] = dtable[igroup[2] & 0x3F];
1579
1580 if (n < 3) {
1581 ogroup[3] = '=';
1582 if (n < 2) {
1583 ogroup[2] = '=';
1584 }
1585 }
1586
1587 if (linelen >= B64LINELEN) {
1588 count = xmlOutputBufferWrite(out, 2, B64CRLF);
1589 if (count == -1)
1590 return -1;
1591 sum += count;
1592 linelen = 0;
1593 }
1594 count = xmlOutputBufferWrite(out, 4, (const char *) ogroup);
1595 if (count == -1)
1596 return -1;
1597 sum += count;
1598
1599 linelen += 4;
1600 }
Daniel Veillard929714b2003-10-22 12:34:36 +00001601
1602 if (i >= len)
1603 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001604 }
1605
Daniel Veillard1d211e22003-10-20 22:32:39 +00001606 return sum;
1607}
1608
1609/**
1610 * xmlTextWriterWriteBase64:
1611 * @writer: the xmlTextWriterPtr
1612 * @data: binary data
1613 * @start: the position within the data of the first byte to encode
1614 * @len: the number of bytes to encode
1615 *
1616 * Write an base64 encoded xml text.
1617 *
1618 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1619 */
1620int
Daniel Veillardab69f362004-02-17 11:40:32 +00001621xmlTextWriterWriteBase64(xmlTextWriterPtr writer, const char *data,
Daniel Veillard1d211e22003-10-20 22:32:39 +00001622 int start, int len)
1623{
1624 int count;
1625 int sum;
1626 xmlLinkPtr lk;
1627 xmlTextWriterStackEntry *p;
1628
Daniel Veillarde43cc572004-11-03 11:50:29 +00001629 if ((writer == NULL) || (data == NULL) || (start < 0) || (len < 0))
Daniel Veillard1d211e22003-10-20 22:32:39 +00001630 return -1;
1631
Daniel Veillard1d211e22003-10-20 22:32:39 +00001632 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001633 lk = xmlListFront(writer->nodes);
1634 if (lk != 0) {
1635 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1636 if (p != 0) {
1637 count = xmlTextWriterHandleStateDependencies(writer, p);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001638 if (count < 0)
1639 return -1;
1640 sum += count;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001641 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001642 }
1643
Daniel Veillardab69f362004-02-17 11:40:32 +00001644 if (writer->indent)
1645 writer->doindent = 0;
1646
Daniel Veillard1d211e22003-10-20 22:32:39 +00001647 count =
1648 xmlOutputBufferWriteBase64(writer->out, len,
1649 (unsigned char *) data + start);
1650 if (count < 0)
1651 return -1;
1652 sum += count;
1653
1654 return sum;
1655}
1656
1657/**
1658 * xmlOutputBufferWriteBinHex:
1659 * @out: the xmlOutputBufferPtr
1660 * @data: binary data
1661 * @len: the number of bytes to encode
1662 *
1663 * Write hqx encoded data to an xmlOutputBuffer.
1664 * ::todo
1665 *
William M. Brack47a31882004-09-11 16:09:09 +00001666 * Returns the bytes written (may be 0 because of buffering)
1667 * or -1 in case of error
Daniel Veillard1d211e22003-10-20 22:32:39 +00001668 */
1669static int
Daniel Veillardab69f362004-02-17 11:40:32 +00001670xmlOutputBufferWriteBinHex(xmlOutputBufferPtr out,
1671 int len, const unsigned char *data)
Daniel Veillard1d211e22003-10-20 22:32:39 +00001672{
Daniel Veillardab69f362004-02-17 11:40:32 +00001673 int count;
1674 int sum;
William M. Brack47a31882004-09-11 16:09:09 +00001675 static char hex[16] =
1676 {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
Daniel Veillardab69f362004-02-17 11:40:32 +00001677 int i;
1678
Daniel Veillarde43cc572004-11-03 11:50:29 +00001679 if ((out == NULL) || (data == NULL) || (len < 0)) {
Daniel Veillardab69f362004-02-17 11:40:32 +00001680 return -1;
1681 }
1682
1683 sum = 0;
1684 for (i = 0; i < len; i++) {
1685 count =
1686 xmlOutputBufferWrite(out, 1,
1687 (const char *) &hex[data[i] >> 4]);
1688 if (count == -1)
1689 return -1;
1690 sum += count;
1691 count =
1692 xmlOutputBufferWrite(out, 1,
1693 (const char *) &hex[data[i] & 0xF]);
1694 if (count == -1)
1695 return -1;
1696 sum += count;
1697 }
1698
1699 return sum;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001700}
1701
1702/**
1703 * xmlTextWriterWriteBinHex:
1704 * @writer: the xmlTextWriterPtr
1705 * @data: binary data
1706 * @start: the position within the data of the first byte to encode
1707 * @len: the number of bytes to encode
1708 *
1709 * Write a BinHex encoded xml text.
1710 *
1711 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1712 */
1713int
Daniel Veillardab69f362004-02-17 11:40:32 +00001714xmlTextWriterWriteBinHex(xmlTextWriterPtr writer, const char *data,
Daniel Veillard1d211e22003-10-20 22:32:39 +00001715 int start, int len)
1716{
1717 int count;
1718 int sum;
1719 xmlLinkPtr lk;
1720 xmlTextWriterStackEntry *p;
1721
Daniel Veillarde43cc572004-11-03 11:50:29 +00001722 if ((writer == NULL) || (data == NULL) || (start < 0) || (len < 0))
Daniel Veillard1d211e22003-10-20 22:32:39 +00001723 return -1;
1724
Daniel Veillard1d211e22003-10-20 22:32:39 +00001725 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001726 lk = xmlListFront(writer->nodes);
1727 if (lk != 0) {
1728 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1729 if (p != 0) {
1730 count = xmlTextWriterHandleStateDependencies(writer, p);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001731 if (count < 0)
1732 return -1;
1733 sum += count;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001734 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001735 }
1736
Daniel Veillardab69f362004-02-17 11:40:32 +00001737 if (writer->indent)
1738 writer->doindent = 0;
1739
Daniel Veillard1d211e22003-10-20 22:32:39 +00001740 count =
1741 xmlOutputBufferWriteBinHex(writer->out, len,
1742 (unsigned char *) data + start);
1743 if (count < 0)
1744 return -1;
1745 sum += count;
1746
1747 return sum;
1748}
1749
1750/**
1751 * xmlTextWriterStartAttribute:
1752 * @writer: the xmlTextWriterPtr
1753 * @name: element name
1754 *
1755 * Start an xml attribute.
1756 *
1757 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1758 */
1759int
1760xmlTextWriterStartAttribute(xmlTextWriterPtr writer, const xmlChar * name)
1761{
1762 int count;
1763 int sum;
1764 xmlLinkPtr lk;
1765 xmlTextWriterStackEntry *p;
1766
1767 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1768 return -1;
1769
1770 sum = 0;
1771 lk = xmlListFront(writer->nodes);
1772 if (lk == 0)
1773 return -1;
1774
1775 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1776 if (p == 0)
1777 return -1;
1778
1779 switch (p->state) {
1780 case XML_TEXTWRITER_ATTRIBUTE:
1781 count = xmlTextWriterEndAttribute(writer);
1782 if (count < 0)
1783 return -1;
1784 sum += count;
1785 /* fallthrough */
1786 case XML_TEXTWRITER_NAME:
1787 count = xmlOutputBufferWriteString(writer->out, " ");
1788 if (count < 0)
1789 return -1;
1790 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00001791 count =
1792 xmlOutputBufferWriteString(writer->out,
1793 (const char *) name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001794 if (count < 0)
1795 return -1;
1796 sum += count;
1797 count = xmlOutputBufferWriteString(writer->out, "=");
1798 if (count < 0)
1799 return -1;
1800 sum += count;
1801 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
1802 if (count < 0)
1803 return -1;
1804 sum += count;
1805 p->state = XML_TEXTWRITER_ATTRIBUTE;
1806 break;
1807 default:
1808 return -1;
1809 }
1810
1811 return sum;
1812}
1813
1814/**
1815 * xmlTextWriterStartAttributeNS:
1816 * @writer: the xmlTextWriterPtr
1817 * @prefix: namespace prefix or NULL
1818 * @name: element local name
1819 * @namespaceURI: namespace URI or NULL
1820 *
1821 * Start an xml attribute with namespace support.
1822 *
1823 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1824 */
1825int
1826xmlTextWriterStartAttributeNS(xmlTextWriterPtr writer,
1827 const xmlChar * prefix, const xmlChar * name,
1828 const xmlChar * namespaceURI)
1829{
1830 int count;
1831 int sum;
1832 xmlChar *buf;
1833 xmlTextWriterNsStackEntry *p;
1834
1835 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1836 return -1;
1837
Rob Richardsb8769d62007-06-08 08:50:47 +00001838 /* Handle namespace first in case of error */
1839 if (namespaceURI != 0) {
1840 xmlTextWriterNsStackEntry nsentry, *curns;
1841
1842 buf = xmlStrdup(BAD_CAST "xmlns");
1843 if (prefix != 0) {
1844 buf = xmlStrcat(buf, BAD_CAST ":");
1845 buf = xmlStrcat(buf, prefix);
1846 }
1847
1848 nsentry.prefix = buf;
1849 nsentry.uri = (xmlChar *)namespaceURI;
1850 nsentry.elem = xmlListFront(writer->nodes);
1851
1852 curns = (xmlTextWriterNsStackEntry *)xmlListSearch(writer->nsstack,
1853 (void *)&nsentry);
1854 if ((curns != NULL)) {
1855 xmlFree(buf);
1856 if (xmlStrcmp(curns->uri, namespaceURI) == 0) {
1857 /* Namespace already defined on element skip */
1858 buf = NULL;
1859 } else {
1860 /* Prefix mismatch so error out */
1861 return -1;
1862 }
1863 }
1864
1865 /* Do not add namespace decl to list - it is already there */
1866 if (buf != NULL) {
1867 p = (xmlTextWriterNsStackEntry *)
1868 xmlMalloc(sizeof(xmlTextWriterNsStackEntry));
1869 if (p == 0) {
1870 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
1871 "xmlTextWriterStartAttributeNS : out of memory!\n");
1872 return -1;
1873 }
1874
1875 p->prefix = buf;
1876 p->uri = xmlStrdup(namespaceURI);
1877 if (p->uri == 0) {
1878 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
1879 "xmlTextWriterStartAttributeNS : out of memory!\n");
1880 xmlFree(p);
1881 return -1;
1882 }
1883 p->elem = xmlListFront(writer->nodes);
1884
1885 xmlListPushFront(writer->nsstack, p);
1886 }
1887 }
1888
Daniel Veillard75e389d2005-07-29 22:02:24 +00001889 buf = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001890 if (prefix != 0) {
1891 buf = xmlStrdup(prefix);
1892 buf = xmlStrcat(buf, BAD_CAST ":");
1893 }
1894 buf = xmlStrcat(buf, name);
1895
1896 sum = 0;
1897 count = xmlTextWriterStartAttribute(writer, buf);
1898 xmlFree(buf);
1899 if (count < 0)
1900 return -1;
1901 sum += count;
1902
Daniel Veillard1d211e22003-10-20 22:32:39 +00001903 return sum;
1904}
1905
1906/**
1907 * xmlTextWriterEndAttribute:
1908 * @writer: the xmlTextWriterPtr
1909 *
1910 * End the current xml element.
1911 *
1912 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1913 */
1914int
1915xmlTextWriterEndAttribute(xmlTextWriterPtr writer)
1916{
1917 int count;
1918 int sum;
1919 xmlLinkPtr lk;
1920 xmlTextWriterStackEntry *p;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001921
1922 if (writer == NULL)
1923 return -1;
1924
1925 lk = xmlListFront(writer->nodes);
1926 if (lk == 0) {
Daniel Veillard1d211e22003-10-20 22:32:39 +00001927 return -1;
1928 }
1929
1930 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1931 if (p == 0) {
Daniel Veillard1d211e22003-10-20 22:32:39 +00001932 return -1;
1933 }
1934
1935 sum = 0;
1936 switch (p->state) {
1937 case XML_TEXTWRITER_ATTRIBUTE:
1938 p->state = XML_TEXTWRITER_NAME;
1939
1940 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
1941 if (count < 0) {
Daniel Veillard1d211e22003-10-20 22:32:39 +00001942 return -1;
1943 }
1944 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001945 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001946 default:
Daniel Veillard1d211e22003-10-20 22:32:39 +00001947 return -1;
1948 }
1949
1950 return sum;
1951}
1952
1953/**
1954 * xmlTextWriterWriteFormatAttribute:
1955 * @writer: the xmlTextWriterPtr
1956 * @name: attribute name
1957 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001958 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001959 *
1960 * Write a formatted xml attribute.
1961 *
1962 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1963 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00001964int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00001965xmlTextWriterWriteFormatAttribute(xmlTextWriterPtr writer,
1966 const xmlChar * name, const char *format,
1967 ...)
1968{
1969 int rc;
1970 va_list ap;
1971
1972 va_start(ap, format);
1973
1974 rc = xmlTextWriterWriteVFormatAttribute(writer, name, format, ap);
1975
1976 va_end(ap);
1977 return rc;
1978}
1979
1980/**
1981 * xmlTextWriterWriteVFormatAttribute:
1982 * @writer: the xmlTextWriterPtr
1983 * @name: attribute name
1984 * @format: format string (see printf)
1985 * @argptr: pointer to the first member of the variable argument list.
1986 *
1987 * Write a formatted xml attribute.
1988 *
1989 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1990 */
1991int
1992xmlTextWriterWriteVFormatAttribute(xmlTextWriterPtr writer,
1993 const xmlChar * name,
1994 const char *format, va_list argptr)
1995{
1996 int rc;
1997 xmlChar *buf;
1998
1999 if (writer == NULL)
2000 return -1;
2001
2002 buf = xmlTextWriterVSprintf(format, argptr);
Daniel Veillardcb0ae192009-02-20 08:40:55 +00002003 if (buf == NULL)
2004 return -1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002005
2006 rc = xmlTextWriterWriteAttribute(writer, name, buf);
2007
2008 xmlFree(buf);
2009 return rc;
2010}
2011
2012/**
2013 * xmlTextWriterWriteAttribute:
2014 * @writer: the xmlTextWriterPtr
2015 * @name: attribute name
2016 * @content: attribute content
2017 *
2018 * Write an xml attribute.
2019 *
2020 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2021 */
2022int
2023xmlTextWriterWriteAttribute(xmlTextWriterPtr writer, const xmlChar * name,
2024 const xmlChar * content)
2025{
2026 int count;
2027 int sum;
2028
2029 sum = 0;
2030 count = xmlTextWriterStartAttribute(writer, name);
2031 if (count < 0)
2032 return -1;
2033 sum += count;
2034 count = xmlTextWriterWriteString(writer, content);
2035 if (count < 0)
2036 return -1;
2037 sum += count;
2038 count = xmlTextWriterEndAttribute(writer);
2039 if (count < 0)
2040 return -1;
2041 sum += count;
2042
2043 return sum;
2044}
2045
2046/**
2047 * xmlTextWriterWriteFormatAttributeNS:
2048 * @writer: the xmlTextWriterPtr
2049 * @prefix: namespace prefix
2050 * @name: attribute local name
2051 * @namespaceURI: namespace URI
2052 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002053 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002054 *
2055 * Write a formatted xml attribute.with namespace support
2056 *
2057 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2058 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00002059int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00002060xmlTextWriterWriteFormatAttributeNS(xmlTextWriterPtr writer,
2061 const xmlChar * prefix,
2062 const xmlChar * name,
2063 const xmlChar * namespaceURI,
2064 const char *format, ...)
2065{
2066 int rc;
2067 va_list ap;
2068
2069 va_start(ap, format);
2070
2071 rc = xmlTextWriterWriteVFormatAttributeNS(writer, prefix, name,
2072 namespaceURI, format, ap);
2073
2074 va_end(ap);
2075 return rc;
2076}
2077
2078/**
2079 * xmlTextWriterWriteVFormatAttributeNS:
2080 * @writer: the xmlTextWriterPtr
2081 * @prefix: namespace prefix
2082 * @name: attribute local name
2083 * @namespaceURI: namespace URI
2084 * @format: format string (see printf)
2085 * @argptr: pointer to the first member of the variable argument list.
2086 *
2087 * Write a formatted xml attribute.with namespace support
2088 *
2089 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2090 */
2091int
2092xmlTextWriterWriteVFormatAttributeNS(xmlTextWriterPtr writer,
2093 const xmlChar * prefix,
2094 const xmlChar * name,
2095 const xmlChar * namespaceURI,
2096 const char *format, va_list argptr)
2097{
2098 int rc;
2099 xmlChar *buf;
2100
2101 if (writer == NULL)
2102 return -1;
2103
2104 buf = xmlTextWriterVSprintf(format, argptr);
Daniel Veillardcb0ae192009-02-20 08:40:55 +00002105 if (buf == NULL)
2106 return -1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002107
2108 rc = xmlTextWriterWriteAttributeNS(writer, prefix, name, namespaceURI,
2109 buf);
2110
2111 xmlFree(buf);
2112 return rc;
2113}
2114
2115/**
2116 * xmlTextWriterWriteAttributeNS:
2117 * @writer: the xmlTextWriterPtr
2118 * @prefix: namespace prefix
2119 * @name: attribute local name
2120 * @namespaceURI: namespace URI
2121 * @content: attribute content
2122 *
2123 * Write an xml attribute.
2124 *
2125 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2126 */
2127int
2128xmlTextWriterWriteAttributeNS(xmlTextWriterPtr writer,
2129 const xmlChar * prefix, const xmlChar * name,
2130 const xmlChar * namespaceURI,
2131 const xmlChar * content)
2132{
2133 int count;
2134 int sum;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002135
2136 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
2137 return -1;
2138
Daniel Veillard1d211e22003-10-20 22:32:39 +00002139 sum = 0;
Rob Richardsb8769d62007-06-08 08:50:47 +00002140 count = xmlTextWriterStartAttributeNS(writer, prefix, name, namespaceURI);
2141 if (count < 0)
2142 return -1;
2143 sum += count;
2144 count = xmlTextWriterWriteString(writer, content);
2145 if (count < 0)
2146 return -1;
2147 sum += count;
2148 count = xmlTextWriterEndAttribute(writer);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002149 if (count < 0)
2150 return -1;
2151 sum += count;
2152
Daniel Veillard1d211e22003-10-20 22:32:39 +00002153 return sum;
2154}
2155
2156/**
2157 * xmlTextWriterWriteFormatElement:
2158 * @writer: the xmlTextWriterPtr
2159 * @name: element name
2160 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002161 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002162 *
2163 * Write a formatted xml element.
2164 *
2165 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2166 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00002167int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00002168xmlTextWriterWriteFormatElement(xmlTextWriterPtr writer,
2169 const xmlChar * name, const char *format,
2170 ...)
2171{
2172 int rc;
2173 va_list ap;
2174
2175 va_start(ap, format);
2176
2177 rc = xmlTextWriterWriteVFormatElement(writer, name, format, ap);
2178
2179 va_end(ap);
2180 return rc;
2181}
2182
2183/**
2184 * xmlTextWriterWriteVFormatElement:
2185 * @writer: the xmlTextWriterPtr
2186 * @name: element name
2187 * @format: format string (see printf)
2188 * @argptr: pointer to the first member of the variable argument list.
2189 *
2190 * Write a formatted xml element.
2191 *
2192 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2193 */
2194int
2195xmlTextWriterWriteVFormatElement(xmlTextWriterPtr writer,
2196 const xmlChar * name, const char *format,
2197 va_list argptr)
2198{
2199 int rc;
2200 xmlChar *buf;
2201
2202 if (writer == NULL)
2203 return -1;
2204
2205 buf = xmlTextWriterVSprintf(format, argptr);
Daniel Veillardcb0ae192009-02-20 08:40:55 +00002206 if (buf == NULL)
2207 return -1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002208
2209 rc = xmlTextWriterWriteElement(writer, name, buf);
2210
2211 xmlFree(buf);
2212 return rc;
2213}
2214
2215/**
2216 * xmlTextWriterWriteElement:
2217 * @writer: the xmlTextWriterPtr
2218 * @name: element name
2219 * @content: element content
2220 *
2221 * Write an xml element.
2222 *
2223 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2224 */
2225int
2226xmlTextWriterWriteElement(xmlTextWriterPtr writer, const xmlChar * name,
2227 const xmlChar * content)
2228{
2229 int count;
2230 int sum;
2231
2232 sum = 0;
2233 count = xmlTextWriterStartElement(writer, name);
2234 if (count == -1)
2235 return -1;
2236 sum += count;
2237 count = xmlTextWriterWriteString(writer, content);
2238 if (count == -1)
2239 return -1;
2240 sum += count;
2241 count = xmlTextWriterEndElement(writer);
2242 if (count == -1)
2243 return -1;
2244 sum += count;
2245
2246 return sum;
2247}
2248
2249/**
2250 * xmlTextWriterWriteFormatElementNS:
2251 * @writer: the xmlTextWriterPtr
2252 * @prefix: namespace prefix
2253 * @name: element local name
2254 * @namespaceURI: namespace URI
2255 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002256 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002257 *
2258 * Write a formatted xml element with namespace support.
2259 *
2260 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2261 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00002262int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00002263xmlTextWriterWriteFormatElementNS(xmlTextWriterPtr writer,
2264 const xmlChar * prefix,
2265 const xmlChar * name,
2266 const xmlChar * namespaceURI,
2267 const char *format, ...)
2268{
2269 int rc;
2270 va_list ap;
2271
2272 va_start(ap, format);
2273
2274 rc = xmlTextWriterWriteVFormatElementNS(writer, prefix, name,
2275 namespaceURI, format, ap);
2276
2277 va_end(ap);
2278 return rc;
2279}
2280
2281/**
2282 * xmlTextWriterWriteVFormatElementNS:
2283 * @writer: the xmlTextWriterPtr
2284 * @prefix: namespace prefix
2285 * @name: element local name
2286 * @namespaceURI: namespace URI
2287 * @format: format string (see printf)
2288 * @argptr: pointer to the first member of the variable argument list.
2289 *
2290 * Write a formatted xml element with namespace support.
2291 *
2292 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2293 */
2294int
2295xmlTextWriterWriteVFormatElementNS(xmlTextWriterPtr writer,
2296 const xmlChar * prefix,
2297 const xmlChar * name,
2298 const xmlChar * namespaceURI,
2299 const char *format, va_list argptr)
2300{
2301 int rc;
2302 xmlChar *buf;
2303
2304 if (writer == NULL)
2305 return -1;
2306
2307 buf = xmlTextWriterVSprintf(format, argptr);
Daniel Veillardcb0ae192009-02-20 08:40:55 +00002308 if (buf == NULL)
2309 return -1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002310
2311 rc = xmlTextWriterWriteElementNS(writer, prefix, name, namespaceURI,
2312 buf);
2313
2314 xmlFree(buf);
2315 return rc;
2316}
2317
2318/**
2319 * xmlTextWriterWriteElementNS:
2320 * @writer: the xmlTextWriterPtr
2321 * @prefix: namespace prefix
2322 * @name: element local name
2323 * @namespaceURI: namespace URI
2324 * @content: element content
2325 *
2326 * Write an xml element with namespace support.
2327 *
2328 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2329 */
2330int
2331xmlTextWriterWriteElementNS(xmlTextWriterPtr writer,
2332 const xmlChar * prefix, const xmlChar * name,
2333 const xmlChar * namespaceURI,
2334 const xmlChar * content)
2335{
2336 int count;
2337 int sum;
2338
2339 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
2340 return -1;
2341
2342 sum = 0;
2343 count =
2344 xmlTextWriterStartElementNS(writer, prefix, name, namespaceURI);
2345 if (count < 0)
2346 return -1;
2347 sum += count;
2348 count = xmlTextWriterWriteString(writer, content);
2349 if (count == -1)
2350 return -1;
2351 sum += count;
2352 count = xmlTextWriterEndElement(writer);
2353 if (count == -1)
2354 return -1;
2355 sum += count;
2356
2357 return sum;
2358}
2359
2360/**
2361 * xmlTextWriterStartPI:
2362 * @writer: the xmlTextWriterPtr
2363 * @target: PI target
2364 *
2365 * Start an xml PI.
2366 *
2367 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2368 */
2369int
2370xmlTextWriterStartPI(xmlTextWriterPtr writer, const xmlChar * target)
2371{
2372 int count;
2373 int sum;
2374 xmlLinkPtr lk;
2375 xmlTextWriterStackEntry *p;
2376
2377 if ((writer == NULL) || (target == NULL) || (*target == '\0'))
2378 return -1;
2379
2380 if (xmlStrcasecmp(target, (const xmlChar *) "xml") == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002381 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002382 "xmlTextWriterStartPI : target name [Xx][Mm][Ll] is reserved for xml standardization!\n");
2383 return -1;
2384 }
2385
2386 sum = 0;
2387 lk = xmlListFront(writer->nodes);
2388 if (lk != 0) {
2389 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2390 if (p != 0) {
2391 switch (p->state) {
2392 case XML_TEXTWRITER_ATTRIBUTE:
2393 count = xmlTextWriterEndAttribute(writer);
2394 if (count < 0)
2395 return -1;
2396 sum += count;
2397 /* fallthrough */
2398 case XML_TEXTWRITER_NAME:
Rob Richardsb8769d62007-06-08 08:50:47 +00002399 /* Output namespace declarations */
2400 count = xmlTextWriterOutputNSDecl(writer);
2401 if (count < 0)
2402 return -1;
2403 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002404 count = xmlOutputBufferWriteString(writer->out, ">");
2405 if (count < 0)
2406 return -1;
2407 sum += count;
2408 p->state = XML_TEXTWRITER_TEXT;
2409 break;
Daniel Veillardab69f362004-02-17 11:40:32 +00002410 case XML_TEXTWRITER_NONE:
2411 case XML_TEXTWRITER_TEXT:
2412 case XML_TEXTWRITER_DTD:
2413 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002414 case XML_TEXTWRITER_PI:
2415 case XML_TEXTWRITER_PI_TEXT:
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002416 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002417 "xmlTextWriterStartPI : nested PI!\n");
2418 return -1;
2419 default:
2420 return -1;
2421 }
2422 }
2423 }
2424
2425 p = (xmlTextWriterStackEntry *)
2426 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2427 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002428 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002429 "xmlTextWriterStartPI : out of memory!\n");
2430 return -1;
2431 }
2432
2433 p->name = xmlStrdup(target);
2434 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002435 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002436 "xmlTextWriterStartPI : out of memory!\n");
2437 xmlFree(p);
2438 return -1;
2439 }
2440 p->state = XML_TEXTWRITER_PI;
2441
2442 xmlListPushFront(writer->nodes, p);
2443
2444 count = xmlOutputBufferWriteString(writer->out, "<?");
2445 if (count < 0)
2446 return -1;
2447 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002448 count =
2449 xmlOutputBufferWriteString(writer->out, (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002450 if (count < 0)
2451 return -1;
2452 sum += count;
2453
2454 return sum;
2455}
2456
2457/**
2458 * xmlTextWriterEndPI:
2459 * @writer: the xmlTextWriterPtr
2460 *
2461 * End the current xml PI.
2462 *
2463 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2464 */
2465int
2466xmlTextWriterEndPI(xmlTextWriterPtr writer)
2467{
2468 int count;
2469 int sum;
2470 xmlLinkPtr lk;
2471 xmlTextWriterStackEntry *p;
2472
2473 if (writer == NULL)
2474 return -1;
2475
2476 lk = xmlListFront(writer->nodes);
2477 if (lk == 0)
2478 return 0;
2479
2480 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2481 if (p == 0)
2482 return 0;
2483
2484 sum = 0;
2485 switch (p->state) {
2486 case XML_TEXTWRITER_PI:
2487 case XML_TEXTWRITER_PI_TEXT:
2488 count = xmlOutputBufferWriteString(writer->out, "?>");
2489 if (count < 0)
2490 return -1;
2491 sum += count;
2492 break;
2493 default:
2494 return -1;
2495 }
2496
Daniel Veillard02c1f232006-04-27 08:10:25 +00002497 if (writer->indent) {
2498 count = xmlOutputBufferWriteString(writer->out, "\n");
2499 if (count < 0)
2500 return -1;
2501 sum += count;
2502 }
2503
Daniel Veillard1d211e22003-10-20 22:32:39 +00002504 xmlListPopFront(writer->nodes);
2505 return sum;
2506}
2507
2508/**
2509 * xmlTextWriterWriteFormatPI:
2510 * @writer: the xmlTextWriterPtr
2511 * @target: PI target
2512 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002513 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002514 *
2515 * Write a formatted PI.
2516 *
2517 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2518 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00002519int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00002520xmlTextWriterWriteFormatPI(xmlTextWriterPtr writer, const xmlChar * target,
2521 const char *format, ...)
2522{
2523 int rc;
2524 va_list ap;
2525
2526 va_start(ap, format);
2527
2528 rc = xmlTextWriterWriteVFormatPI(writer, target, format, ap);
2529
2530 va_end(ap);
2531 return rc;
2532}
2533
2534/**
2535 * xmlTextWriterWriteVFormatPI:
2536 * @writer: the xmlTextWriterPtr
2537 * @target: PI target
2538 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002539 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00002540 *
2541 * Write a formatted xml PI.
2542 *
2543 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2544 */
2545int
2546xmlTextWriterWriteVFormatPI(xmlTextWriterPtr writer,
2547 const xmlChar * target, const char *format,
2548 va_list argptr)
2549{
2550 int rc;
2551 xmlChar *buf;
2552
2553 if (writer == NULL)
2554 return -1;
2555
2556 buf = xmlTextWriterVSprintf(format, argptr);
Daniel Veillardcb0ae192009-02-20 08:40:55 +00002557 if (buf == NULL)
2558 return -1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002559
2560 rc = xmlTextWriterWritePI(writer, target, buf);
2561
2562 xmlFree(buf);
2563 return rc;
2564}
2565
2566/**
2567 * xmlTextWriterWritePI:
2568 * @writer: the xmlTextWriterPtr
2569 * @target: PI target
2570 * @content: PI content
2571 *
2572 * Write an xml PI.
2573 *
2574 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2575 */
2576int
2577xmlTextWriterWritePI(xmlTextWriterPtr writer, const xmlChar * target,
2578 const xmlChar * content)
2579{
2580 int count;
2581 int sum;
2582
2583 sum = 0;
2584 count = xmlTextWriterStartPI(writer, target);
2585 if (count == -1)
2586 return -1;
2587 sum += count;
2588 if (content != 0) {
2589 count = xmlTextWriterWriteString(writer, content);
2590 if (count == -1)
2591 return -1;
2592 sum += count;
2593 }
2594 count = xmlTextWriterEndPI(writer);
2595 if (count == -1)
2596 return -1;
2597 sum += count;
2598
2599 return sum;
2600}
2601
2602/**
2603 * xmlTextWriterStartCDATA:
2604 * @writer: the xmlTextWriterPtr
2605 *
2606 * Start an xml CDATA section.
2607 *
2608 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2609 */
2610int
2611xmlTextWriterStartCDATA(xmlTextWriterPtr writer)
2612{
2613 int count;
2614 int sum;
2615 xmlLinkPtr lk;
2616 xmlTextWriterStackEntry *p;
2617
2618 if (writer == NULL)
2619 return -1;
2620
2621 sum = 0;
2622 lk = xmlListFront(writer->nodes);
2623 if (lk != 0) {
2624 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2625 if (p != 0) {
2626 switch (p->state) {
2627 case XML_TEXTWRITER_NONE:
Daniel Veillardccc476f2008-03-04 13:19:49 +00002628 case XML_TEXTWRITER_TEXT:
Daniel Veillard1d211e22003-10-20 22:32:39 +00002629 case XML_TEXTWRITER_PI:
2630 case XML_TEXTWRITER_PI_TEXT:
2631 break;
2632 case XML_TEXTWRITER_ATTRIBUTE:
2633 count = xmlTextWriterEndAttribute(writer);
2634 if (count < 0)
2635 return -1;
2636 sum += count;
2637 /* fallthrough */
2638 case XML_TEXTWRITER_NAME:
Rob Richardsb8769d62007-06-08 08:50:47 +00002639 /* Output namespace declarations */
2640 count = xmlTextWriterOutputNSDecl(writer);
2641 if (count < 0)
2642 return -1;
2643 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002644 count = xmlOutputBufferWriteString(writer->out, ">");
2645 if (count < 0)
2646 return -1;
2647 sum += count;
2648 p->state = XML_TEXTWRITER_TEXT;
2649 break;
2650 case XML_TEXTWRITER_CDATA:
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002651 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002652 "xmlTextWriterStartCDATA : CDATA not allowed in this context!\n");
2653 return -1;
2654 default:
2655 return -1;
2656 }
2657 }
2658 }
2659
2660 p = (xmlTextWriterStackEntry *)
2661 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2662 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002663 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002664 "xmlTextWriterStartCDATA : out of memory!\n");
2665 return -1;
2666 }
2667
Daniel Veillard75e389d2005-07-29 22:02:24 +00002668 p->name = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002669 p->state = XML_TEXTWRITER_CDATA;
2670
2671 xmlListPushFront(writer->nodes, p);
2672
2673 count = xmlOutputBufferWriteString(writer->out, "<![CDATA[");
2674 if (count < 0)
2675 return -1;
2676 sum += count;
2677
2678 return sum;
2679}
2680
2681/**
2682 * xmlTextWriterEndCDATA:
2683 * @writer: the xmlTextWriterPtr
2684 *
2685 * End an xml CDATA section.
2686 *
2687 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2688 */
2689int
2690xmlTextWriterEndCDATA(xmlTextWriterPtr writer)
2691{
2692 int count;
2693 int sum;
2694 xmlLinkPtr lk;
2695 xmlTextWriterStackEntry *p;
2696
2697 if (writer == NULL)
2698 return -1;
2699
2700 lk = xmlListFront(writer->nodes);
2701 if (lk == 0)
2702 return -1;
2703
2704 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2705 if (p == 0)
2706 return -1;
2707
2708 sum = 0;
2709 switch (p->state) {
2710 case XML_TEXTWRITER_CDATA:
2711 count = xmlOutputBufferWriteString(writer->out, "]]>");
2712 if (count < 0)
2713 return -1;
2714 sum += count;
2715 break;
2716 default:
2717 return -1;
2718 }
2719
2720 xmlListPopFront(writer->nodes);
2721 return sum;
2722}
2723
2724/**
2725 * xmlTextWriterWriteFormatCDATA:
2726 * @writer: the xmlTextWriterPtr
2727 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002728 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002729 *
2730 * Write a formatted xml CDATA.
2731 *
2732 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2733 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00002734int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00002735xmlTextWriterWriteFormatCDATA(xmlTextWriterPtr writer, const char *format,
2736 ...)
2737{
2738 int rc;
2739 va_list ap;
2740
2741 va_start(ap, format);
2742
2743 rc = xmlTextWriterWriteVFormatCDATA(writer, format, ap);
2744
2745 va_end(ap);
2746 return rc;
2747}
2748
2749/**
2750 * xmlTextWriterWriteVFormatCDATA:
2751 * @writer: the xmlTextWriterPtr
2752 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002753 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00002754 *
2755 * Write a formatted xml CDATA.
2756 *
2757 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2758 */
2759int
2760xmlTextWriterWriteVFormatCDATA(xmlTextWriterPtr writer, const char *format,
2761 va_list argptr)
2762{
2763 int rc;
2764 xmlChar *buf;
2765
2766 if (writer == NULL)
2767 return -1;
2768
2769 buf = xmlTextWriterVSprintf(format, argptr);
Daniel Veillardcb0ae192009-02-20 08:40:55 +00002770 if (buf == NULL)
2771 return -1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002772
2773 rc = xmlTextWriterWriteCDATA(writer, buf);
2774
2775 xmlFree(buf);
2776 return rc;
2777}
2778
2779/**
2780 * xmlTextWriterWriteCDATA:
2781 * @writer: the xmlTextWriterPtr
2782 * @content: CDATA content
2783 *
2784 * Write an xml CDATA.
2785 *
2786 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2787 */
2788int
2789xmlTextWriterWriteCDATA(xmlTextWriterPtr writer, const xmlChar * content)
2790{
2791 int count;
2792 int sum;
2793
2794 sum = 0;
2795 count = xmlTextWriterStartCDATA(writer);
2796 if (count == -1)
2797 return -1;
2798 sum += count;
2799 if (content != 0) {
2800 count = xmlTextWriterWriteString(writer, content);
2801 if (count == -1)
2802 return -1;
2803 sum += count;
2804 }
2805 count = xmlTextWriterEndCDATA(writer);
2806 if (count == -1)
2807 return -1;
2808 sum += count;
2809
2810 return sum;
2811}
2812
2813/**
2814 * xmlTextWriterStartDTD:
2815 * @writer: the xmlTextWriterPtr
2816 * @name: the name of the DTD
2817 * @pubid: the public identifier, which is an alternative to the system identifier
2818 * @sysid: the system identifier, which is the URI of the DTD
2819 *
2820 * Start an xml DTD.
2821 *
2822 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2823 */
2824int
2825xmlTextWriterStartDTD(xmlTextWriterPtr writer,
2826 const xmlChar * name,
2827 const xmlChar * pubid, const xmlChar * sysid)
2828{
2829 int count;
2830 int sum;
2831 xmlLinkPtr lk;
2832 xmlTextWriterStackEntry *p;
2833
2834 if (writer == NULL || name == NULL || *name == '\0')
2835 return -1;
2836
2837 sum = 0;
2838 lk = xmlListFront(writer->nodes);
Daniel Veillardab69f362004-02-17 11:40:32 +00002839 if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002840 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002841 "xmlTextWriterStartDTD : DTD allowed only in prolog!\n");
2842 return -1;
2843 }
2844
2845 p = (xmlTextWriterStackEntry *)
2846 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2847 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002848 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002849 "xmlTextWriterStartDTD : out of memory!\n");
2850 return -1;
2851 }
2852
2853 p->name = xmlStrdup(name);
2854 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002855 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002856 "xmlTextWriterStartDTD : out of memory!\n");
2857 xmlFree(p);
2858 return -1;
2859 }
2860 p->state = XML_TEXTWRITER_DTD;
2861
2862 xmlListPushFront(writer->nodes, p);
2863
2864 count = xmlOutputBufferWriteString(writer->out, "<!DOCTYPE ");
2865 if (count < 0)
2866 return -1;
2867 sum += count;
2868 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
2869 if (count < 0)
2870 return -1;
2871 sum += count;
2872
2873 if (pubid != 0) {
2874 if (sysid == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002875 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002876 "xmlTextWriterStartDTD : system identifier needed!\n");
2877 return -1;
2878 }
2879
Daniel Veillard500a1de2004-03-22 15:22:58 +00002880 if (writer->indent)
2881 count = xmlOutputBufferWrite(writer->out, 1, "\n");
2882 else
2883 count = xmlOutputBufferWrite(writer->out, 1, " ");
2884 if (count < 0)
2885 return -1;
2886 sum += count;
2887
2888 count = xmlOutputBufferWriteString(writer->out, "PUBLIC ");
2889 if (count < 0)
2890 return -1;
2891 sum += count;
2892
2893 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002894 if (count < 0)
2895 return -1;
2896 sum += count;
2897
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002898 count =
2899 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002900 if (count < 0)
2901 return -1;
2902 sum += count;
2903
Daniel Veillard500a1de2004-03-22 15:22:58 +00002904 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002905 if (count < 0)
2906 return -1;
2907 sum += count;
2908 }
2909
2910 if (sysid != 0) {
2911 if (pubid == 0) {
Daniel Veillard500a1de2004-03-22 15:22:58 +00002912 if (writer->indent)
2913 count = xmlOutputBufferWrite(writer->out, 1, "\n");
2914 else
2915 count = xmlOutputBufferWrite(writer->out, 1, " ");
2916 if (count < 0)
2917 return -1;
2918 sum += count;
2919 count = xmlOutputBufferWriteString(writer->out, "SYSTEM ");
2920 if (count < 0)
2921 return -1;
2922 sum += count;
Rob Richardsffe47fe2005-12-09 17:52:21 +00002923 } else {
2924 if (writer->indent)
Daniel Veillard500a1de2004-03-22 15:22:58 +00002925 count = xmlOutputBufferWriteString(writer->out, "\n ");
Rob Richardsffe47fe2005-12-09 17:52:21 +00002926 else
2927 count = xmlOutputBufferWrite(writer->out, 1, " ");
Daniel Veillard1d211e22003-10-20 22:32:39 +00002928 if (count < 0)
2929 return -1;
2930 sum += count;
2931 }
2932
Daniel Veillard500a1de2004-03-22 15:22:58 +00002933 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002934 if (count < 0)
2935 return -1;
2936 sum += count;
2937
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002938 count =
2939 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002940 if (count < 0)
2941 return -1;
2942 sum += count;
2943
Daniel Veillard500a1de2004-03-22 15:22:58 +00002944 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002945 if (count < 0)
2946 return -1;
2947 sum += count;
2948 }
2949
2950 return sum;
2951}
2952
2953/**
2954 * xmlTextWriterEndDTD:
2955 * @writer: the xmlTextWriterPtr
2956 *
2957 * End an xml DTD.
2958 *
2959 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2960 */
2961int
2962xmlTextWriterEndDTD(xmlTextWriterPtr writer)
2963{
Daniel Veillard500a1de2004-03-22 15:22:58 +00002964 int loop;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002965 int count;
2966 int sum;
2967 xmlLinkPtr lk;
2968 xmlTextWriterStackEntry *p;
2969
2970 if (writer == NULL)
2971 return -1;
2972
2973 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00002974 loop = 1;
2975 while (loop) {
2976 lk = xmlListFront(writer->nodes);
2977 if (lk == NULL)
Daniel Veillard1d211e22003-10-20 22:32:39 +00002978 break;
Daniel Veillard500a1de2004-03-22 15:22:58 +00002979 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2980 if (p == 0)
2981 break;
2982 switch (p->state) {
2983 case XML_TEXTWRITER_DTD_TEXT:
2984 count = xmlOutputBufferWriteString(writer->out, "]");
2985 if (count < 0)
2986 return -1;
2987 sum += count;
2988 /* fallthrough */
2989 case XML_TEXTWRITER_DTD:
2990 count = xmlOutputBufferWriteString(writer->out, ">");
2991
2992 if (writer->indent) {
2993 if (count < 0)
2994 return -1;
2995 sum += count;
2996 count = xmlOutputBufferWriteString(writer->out, "\n");
2997 }
2998
2999 xmlListPopFront(writer->nodes);
3000 break;
3001 case XML_TEXTWRITER_DTD_ELEM:
3002 case XML_TEXTWRITER_DTD_ELEM_TEXT:
3003 count = xmlTextWriterEndDTDElement(writer);
3004 break;
3005 case XML_TEXTWRITER_DTD_ATTL:
3006 case XML_TEXTWRITER_DTD_ATTL_TEXT:
3007 count = xmlTextWriterEndDTDAttlist(writer);
3008 break;
3009 case XML_TEXTWRITER_DTD_ENTY:
3010 case XML_TEXTWRITER_DTD_PENT:
3011 case XML_TEXTWRITER_DTD_ENTY_TEXT:
3012 count = xmlTextWriterEndDTDEntity(writer);
3013 break;
3014 case XML_TEXTWRITER_COMMENT:
3015 count = xmlTextWriterEndComment(writer);
3016 break;
3017 default:
3018 loop = 0;
3019 continue;
3020 }
3021
3022 if (count < 0)
Daniel Veillard1d211e22003-10-20 22:32:39 +00003023 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00003024 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00003025 }
3026
Daniel Veillard1d211e22003-10-20 22:32:39 +00003027 return sum;
3028}
3029
3030/**
3031 * xmlTextWriterWriteFormatDTD:
3032 * @writer: the xmlTextWriterPtr
3033 * @name: the name of the DTD
3034 * @pubid: the public identifier, which is an alternative to the system identifier
3035 * @sysid: the system identifier, which is the URI of the DTD
3036 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003037 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00003038 *
3039 * Write a DTD with a formatted markup declarations part.
3040 *
3041 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3042 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00003043int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00003044xmlTextWriterWriteFormatDTD(xmlTextWriterPtr writer,
3045 const xmlChar * name,
3046 const xmlChar * pubid,
3047 const xmlChar * sysid, const char *format, ...)
3048{
3049 int rc;
3050 va_list ap;
3051
3052 va_start(ap, format);
3053
3054 rc = xmlTextWriterWriteVFormatDTD(writer, name, pubid, sysid, format,
3055 ap);
3056
3057 va_end(ap);
3058 return rc;
3059}
3060
3061/**
3062 * xmlTextWriterWriteVFormatDTD:
3063 * @writer: the xmlTextWriterPtr
3064 * @name: the name of the DTD
3065 * @pubid: the public identifier, which is an alternative to the system identifier
3066 * @sysid: the system identifier, which is the URI of the DTD
3067 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003068 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00003069 *
3070 * Write a DTD with a formatted markup declarations part.
3071 *
3072 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3073 */
3074int
3075xmlTextWriterWriteVFormatDTD(xmlTextWriterPtr writer,
3076 const xmlChar * name,
3077 const xmlChar * pubid,
3078 const xmlChar * sysid,
3079 const char *format, va_list argptr)
3080{
3081 int rc;
3082 xmlChar *buf;
3083
3084 if (writer == NULL)
3085 return -1;
3086
3087 buf = xmlTextWriterVSprintf(format, argptr);
Daniel Veillardcb0ae192009-02-20 08:40:55 +00003088 if (buf == NULL)
3089 return -1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00003090
3091 rc = xmlTextWriterWriteDTD(writer, name, pubid, sysid, buf);
3092
3093 xmlFree(buf);
3094 return rc;
3095}
3096
3097/**
3098 * xmlTextWriterWriteDTD:
3099 * @writer: the xmlTextWriterPtr
3100 * @name: the name of the DTD
3101 * @pubid: the public identifier, which is an alternative to the system identifier
3102 * @sysid: the system identifier, which is the URI of the DTD
William M. Brackb1d53162003-11-18 06:54:40 +00003103 * @subset: string content of the DTD
Daniel Veillard1d211e22003-10-20 22:32:39 +00003104 *
3105 * Write a DTD.
3106 *
3107 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3108 */
3109int
3110xmlTextWriterWriteDTD(xmlTextWriterPtr writer,
3111 const xmlChar * name,
3112 const xmlChar * pubid,
3113 const xmlChar * sysid, const xmlChar * subset)
3114{
3115 int count;
3116 int sum;
3117
3118 sum = 0;
3119 count = xmlTextWriterStartDTD(writer, name, pubid, sysid);
3120 if (count == -1)
3121 return -1;
3122 sum += count;
3123 if (subset != 0) {
3124 count = xmlTextWriterWriteString(writer, subset);
3125 if (count == -1)
3126 return -1;
3127 sum += count;
3128 }
3129 count = xmlTextWriterEndDTD(writer);
3130 if (count == -1)
3131 return -1;
3132 sum += count;
3133
3134 return sum;
3135}
3136
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003137/**
3138 * xmlTextWriterStartDTDElement:
3139 * @writer: the xmlTextWriterPtr
3140 * @name: the name of the DTD element
3141 *
3142 * Start an xml DTD element.
3143 *
3144 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3145 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003146int
3147xmlTextWriterStartDTDElement(xmlTextWriterPtr writer, const xmlChar * name)
3148{
3149 int count;
3150 int sum;
3151 xmlLinkPtr lk;
3152 xmlTextWriterStackEntry *p;
3153
3154 if (writer == NULL || name == NULL || *name == '\0')
3155 return -1;
3156
3157 sum = 0;
3158 lk = xmlListFront(writer->nodes);
3159 if (lk == 0) {
3160 return -1;
3161 }
3162
3163 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
Daniel Veillard500a1de2004-03-22 15:22:58 +00003164 if (p != 0) {
3165 switch (p->state) {
3166 case XML_TEXTWRITER_DTD:
3167 count = xmlOutputBufferWriteString(writer->out, " [");
3168 if (count < 0)
3169 return -1;
3170 sum += count;
3171 if (writer->indent) {
3172 count = xmlOutputBufferWriteString(writer->out, "\n");
3173 if (count < 0)
3174 return -1;
3175 sum += count;
3176 }
3177 p->state = XML_TEXTWRITER_DTD_TEXT;
3178 /* fallthrough */
3179 case XML_TEXTWRITER_DTD_TEXT:
3180 case XML_TEXTWRITER_NONE:
3181 break;
3182 default:
Daniel Veillard1d211e22003-10-20 22:32:39 +00003183 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00003184 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00003185 }
3186
3187 p = (xmlTextWriterStackEntry *)
3188 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3189 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003190 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003191 "xmlTextWriterStartDTDElement : out of memory!\n");
3192 return -1;
3193 }
3194
3195 p->name = xmlStrdup(name);
3196 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003197 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003198 "xmlTextWriterStartDTDElement : out of memory!\n");
3199 xmlFree(p);
3200 return -1;
3201 }
3202 p->state = XML_TEXTWRITER_DTD_ELEM;
3203
3204 xmlListPushFront(writer->nodes, p);
3205
Daniel Veillard500a1de2004-03-22 15:22:58 +00003206 if (writer->indent) {
3207 count = xmlTextWriterWriteIndent(writer);
3208 if (count < 0)
3209 return -1;
3210 sum += count;
3211 }
3212
Daniel Veillard1d211e22003-10-20 22:32:39 +00003213 count = xmlOutputBufferWriteString(writer->out, "<!ELEMENT ");
3214 if (count < 0)
3215 return -1;
3216 sum += count;
3217 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
3218 if (count < 0)
3219 return -1;
3220 sum += count;
3221
3222 return sum;
3223}
3224
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003225/**
Daniel Veillard500a1de2004-03-22 15:22:58 +00003226 * xmlTextWriterEndDTDElement:
3227 * @writer: the xmlTextWriterPtr
3228 *
3229 * End an xml DTD element.
3230 *
3231 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3232 */
3233int
3234xmlTextWriterEndDTDElement(xmlTextWriterPtr writer)
3235{
3236 int count;
3237 int sum;
3238 xmlLinkPtr lk;
3239 xmlTextWriterStackEntry *p;
3240
3241 if (writer == NULL)
3242 return -1;
3243
3244 sum = 0;
3245 lk = xmlListFront(writer->nodes);
3246 if (lk == 0)
3247 return -1;
3248
3249 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3250 if (p == 0)
3251 return -1;
3252
3253 switch (p->state) {
3254 case XML_TEXTWRITER_DTD_ELEM:
3255 case XML_TEXTWRITER_DTD_ELEM_TEXT:
3256 count = xmlOutputBufferWriteString(writer->out, ">");
3257 if (count < 0)
3258 return -1;
3259 sum += count;
3260 break;
3261 default:
3262 return -1;
3263 }
3264
3265 if (writer->indent) {
3266 count = xmlOutputBufferWriteString(writer->out, "\n");
3267 if (count < 0)
3268 return -1;
3269 sum += count;
3270 }
3271
3272 xmlListPopFront(writer->nodes);
3273 return sum;
3274}
3275
3276/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003277 * xmlTextWriterWriteFormatDTDElement:
3278 * @writer: the xmlTextWriterPtr
3279 * @name: the name of the DTD element
3280 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003281 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003282 *
3283 * Write a formatted DTD element.
3284 *
3285 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3286 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00003287int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00003288xmlTextWriterWriteFormatDTDElement(xmlTextWriterPtr writer,
3289 const xmlChar * name,
3290 const char *format, ...)
3291{
3292 int rc;
3293 va_list ap;
3294
3295 va_start(ap, format);
3296
3297 rc = xmlTextWriterWriteVFormatDTDElement(writer, name, format, ap);
3298
3299 va_end(ap);
3300 return rc;
3301}
3302
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003303/**
3304 * xmlTextWriterWriteVFormatDTDElement:
3305 * @writer: the xmlTextWriterPtr
3306 * @name: the name of the DTD element
3307 * @format: format string (see printf)
3308 * @argptr: pointer to the first member of the variable argument list.
3309 *
3310 * Write a formatted DTD element.
3311 *
3312 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3313 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003314int
3315xmlTextWriterWriteVFormatDTDElement(xmlTextWriterPtr writer,
3316 const xmlChar * name,
3317 const char *format, va_list argptr)
3318{
3319 int rc;
3320 xmlChar *buf;
3321
3322 if (writer == NULL)
3323 return -1;
3324
3325 buf = xmlTextWriterVSprintf(format, argptr);
Daniel Veillardcb0ae192009-02-20 08:40:55 +00003326 if (buf == NULL)
3327 return -1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00003328
3329 rc = xmlTextWriterWriteDTDElement(writer, name, buf);
3330
3331 xmlFree(buf);
3332 return rc;
3333}
3334
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003335/**
3336 * xmlTextWriterWriteDTDElement:
3337 * @writer: the xmlTextWriterPtr
3338 * @name: the name of the DTD element
3339 * @content: content of the element
3340 *
3341 * Write a DTD element.
3342 *
3343 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3344 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003345int
3346xmlTextWriterWriteDTDElement(xmlTextWriterPtr writer,
3347 const xmlChar * name, const xmlChar * content)
3348{
3349 int count;
3350 int sum;
3351
3352 if (content == NULL)
3353 return -1;
3354
3355 sum = 0;
3356 count = xmlTextWriterStartDTDElement(writer, name);
3357 if (count == -1)
3358 return -1;
3359 sum += count;
3360
Daniel Veillard1d211e22003-10-20 22:32:39 +00003361 count = xmlTextWriterWriteString(writer, content);
3362 if (count == -1)
3363 return -1;
3364 sum += count;
3365
3366 count = xmlTextWriterEndDTDElement(writer);
3367 if (count == -1)
3368 return -1;
3369 sum += count;
3370
3371 return sum;
3372}
3373
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003374/**
3375 * xmlTextWriterStartDTDAttlist:
3376 * @writer: the xmlTextWriterPtr
3377 * @name: the name of the DTD ATTLIST
3378 *
3379 * Start an xml DTD ATTLIST.
3380 *
3381 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3382 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003383int
3384xmlTextWriterStartDTDAttlist(xmlTextWriterPtr writer, const xmlChar * name)
3385{
3386 int count;
3387 int sum;
3388 xmlLinkPtr lk;
3389 xmlTextWriterStackEntry *p;
3390
3391 if (writer == NULL || name == NULL || *name == '\0')
3392 return -1;
3393
3394 sum = 0;
3395 lk = xmlListFront(writer->nodes);
3396 if (lk == 0) {
3397 return -1;
3398 }
3399
3400 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
Daniel Veillard500a1de2004-03-22 15:22:58 +00003401 if (p != 0) {
3402 switch (p->state) {
3403 case XML_TEXTWRITER_DTD:
3404 count = xmlOutputBufferWriteString(writer->out, " [");
3405 if (count < 0)
3406 return -1;
3407 sum += count;
3408 if (writer->indent) {
3409 count = xmlOutputBufferWriteString(writer->out, "\n");
3410 if (count < 0)
3411 return -1;
3412 sum += count;
3413 }
3414 p->state = XML_TEXTWRITER_DTD_TEXT;
3415 /* fallthrough */
3416 case XML_TEXTWRITER_DTD_TEXT:
3417 case XML_TEXTWRITER_NONE:
3418 break;
3419 default:
Daniel Veillard1d211e22003-10-20 22:32:39 +00003420 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00003421 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00003422 }
3423
3424 p = (xmlTextWriterStackEntry *)
3425 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3426 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003427 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003428 "xmlTextWriterStartDTDAttlist : out of memory!\n");
3429 return -1;
3430 }
3431
3432 p->name = xmlStrdup(name);
3433 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003434 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003435 "xmlTextWriterStartDTDAttlist : out of memory!\n");
3436 xmlFree(p);
3437 return -1;
3438 }
3439 p->state = XML_TEXTWRITER_DTD_ATTL;
3440
3441 xmlListPushFront(writer->nodes, p);
3442
Daniel Veillard500a1de2004-03-22 15:22:58 +00003443 if (writer->indent) {
3444 count = xmlTextWriterWriteIndent(writer);
3445 if (count < 0)
3446 return -1;
3447 sum += count;
3448 }
3449
Daniel Veillard1d211e22003-10-20 22:32:39 +00003450 count = xmlOutputBufferWriteString(writer->out, "<!ATTLIST ");
3451 if (count < 0)
3452 return -1;
3453 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +00003454 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003455 if (count < 0)
3456 return -1;
3457 sum += count;
3458
3459 return sum;
3460}
3461
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003462/**
Daniel Veillard500a1de2004-03-22 15:22:58 +00003463 * xmlTextWriterEndDTDAttlist:
3464 * @writer: the xmlTextWriterPtr
3465 *
3466 * End an xml DTD attribute list.
3467 *
3468 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3469 */
3470int
3471xmlTextWriterEndDTDAttlist(xmlTextWriterPtr writer)
3472{
3473 int count;
3474 int sum;
3475 xmlLinkPtr lk;
3476 xmlTextWriterStackEntry *p;
3477
3478 if (writer == NULL)
3479 return -1;
3480
3481 sum = 0;
3482 lk = xmlListFront(writer->nodes);
3483 if (lk == 0)
3484 return -1;
3485
3486 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3487 if (p == 0)
3488 return -1;
3489
3490 switch (p->state) {
3491 case XML_TEXTWRITER_DTD_ATTL:
3492 case XML_TEXTWRITER_DTD_ATTL_TEXT:
3493 count = xmlOutputBufferWriteString(writer->out, ">");
3494 if (count < 0)
3495 return -1;
3496 sum += count;
3497 break;
3498 default:
3499 return -1;
3500 }
3501
3502 if (writer->indent) {
3503 count = xmlOutputBufferWriteString(writer->out, "\n");
3504 if (count < 0)
3505 return -1;
3506 sum += count;
3507 }
3508
3509 xmlListPopFront(writer->nodes);
3510 return sum;
3511}
3512
3513/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003514 * xmlTextWriterWriteFormatDTDAttlist:
3515 * @writer: the xmlTextWriterPtr
3516 * @name: the name of the DTD ATTLIST
3517 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003518 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003519 *
3520 * Write a formatted DTD ATTLIST.
3521 *
3522 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3523 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00003524int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00003525xmlTextWriterWriteFormatDTDAttlist(xmlTextWriterPtr writer,
3526 const xmlChar * name,
3527 const char *format, ...)
3528{
3529 int rc;
3530 va_list ap;
3531
3532 va_start(ap, format);
3533
3534 rc = xmlTextWriterWriteVFormatDTDAttlist(writer, name, format, ap);
3535
3536 va_end(ap);
3537 return rc;
3538}
3539
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003540/**
3541 * xmlTextWriterWriteVFormatDTDAttlist:
3542 * @writer: the xmlTextWriterPtr
3543 * @name: the name of the DTD ATTLIST
3544 * @format: format string (see printf)
3545 * @argptr: pointer to the first member of the variable argument list.
3546 *
3547 * Write a formatted DTD ATTLIST.
3548 *
3549 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3550 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003551int
3552xmlTextWriterWriteVFormatDTDAttlist(xmlTextWriterPtr writer,
3553 const xmlChar * name,
3554 const char *format, va_list argptr)
3555{
3556 int rc;
3557 xmlChar *buf;
3558
3559 if (writer == NULL)
3560 return -1;
3561
3562 buf = xmlTextWriterVSprintf(format, argptr);
Daniel Veillardcb0ae192009-02-20 08:40:55 +00003563 if (buf == NULL)
3564 return -1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00003565
3566 rc = xmlTextWriterWriteDTDAttlist(writer, name, buf);
3567
3568 xmlFree(buf);
3569 return rc;
3570}
3571
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003572/**
3573 * xmlTextWriterWriteDTDAttlist:
3574 * @writer: the xmlTextWriterPtr
3575 * @name: the name of the DTD ATTLIST
3576 * @content: content of the ATTLIST
3577 *
3578 * Write a DTD ATTLIST.
3579 *
3580 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3581 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003582int
3583xmlTextWriterWriteDTDAttlist(xmlTextWriterPtr writer,
3584 const xmlChar * name, const xmlChar * content)
3585{
3586 int count;
3587 int sum;
3588
3589 if (content == NULL)
3590 return -1;
3591
3592 sum = 0;
3593 count = xmlTextWriterStartDTDAttlist(writer, name);
3594 if (count == -1)
3595 return -1;
3596 sum += count;
3597
Daniel Veillard1d211e22003-10-20 22:32:39 +00003598 count = xmlTextWriterWriteString(writer, content);
3599 if (count == -1)
3600 return -1;
3601 sum += count;
3602
3603 count = xmlTextWriterEndDTDAttlist(writer);
3604 if (count == -1)
3605 return -1;
3606 sum += count;
3607
3608 return sum;
3609}
3610
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003611/**
3612 * xmlTextWriterStartDTDEntity:
3613 * @writer: the xmlTextWriterPtr
3614 * @pe: TRUE if this is a parameter entity, FALSE if not
3615 * @name: the name of the DTD ATTLIST
3616 *
3617 * Start an xml DTD ATTLIST.
3618 *
3619 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3620 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003621int
3622xmlTextWriterStartDTDEntity(xmlTextWriterPtr writer,
3623 int pe, const xmlChar * name)
3624{
3625 int count;
3626 int sum;
3627 xmlLinkPtr lk;
3628 xmlTextWriterStackEntry *p;
3629
3630 if (writer == NULL || name == NULL || *name == '\0')
3631 return -1;
3632
3633 sum = 0;
3634 lk = xmlListFront(writer->nodes);
Daniel Veillard500a1de2004-03-22 15:22:58 +00003635 if (lk != 0) {
Daniel Veillard1d211e22003-10-20 22:32:39 +00003636
Daniel Veillard500a1de2004-03-22 15:22:58 +00003637 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3638 if (p != 0) {
3639 switch (p->state) {
3640 case XML_TEXTWRITER_DTD:
3641 count = xmlOutputBufferWriteString(writer->out, " [");
3642 if (count < 0)
3643 return -1;
3644 sum += count;
3645 if (writer->indent) {
3646 count =
3647 xmlOutputBufferWriteString(writer->out, "\n");
3648 if (count < 0)
3649 return -1;
3650 sum += count;
3651 }
3652 p->state = XML_TEXTWRITER_DTD_TEXT;
3653 /* fallthrough */
3654 case XML_TEXTWRITER_DTD_TEXT:
3655 case XML_TEXTWRITER_NONE:
3656 break;
3657 default:
3658 return -1;
3659 }
3660 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00003661 }
3662
3663 p = (xmlTextWriterStackEntry *)
3664 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3665 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003666 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003667 "xmlTextWriterStartDTDElement : out of memory!\n");
3668 return -1;
3669 }
3670
3671 p->name = xmlStrdup(name);
3672 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003673 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003674 "xmlTextWriterStartDTDElement : out of memory!\n");
3675 xmlFree(p);
3676 return -1;
3677 }
Daniel Veillard500a1de2004-03-22 15:22:58 +00003678
3679 if (pe != 0)
3680 p->state = XML_TEXTWRITER_DTD_PENT;
3681 else
3682 p->state = XML_TEXTWRITER_DTD_ENTY;
Daniel Veillard1d211e22003-10-20 22:32:39 +00003683
3684 xmlListPushFront(writer->nodes, p);
3685
Daniel Veillard500a1de2004-03-22 15:22:58 +00003686 if (writer->indent) {
3687 count = xmlTextWriterWriteIndent(writer);
3688 if (count < 0)
3689 return -1;
3690 sum += count;
3691 }
3692
Daniel Veillard1d211e22003-10-20 22:32:39 +00003693 count = xmlOutputBufferWriteString(writer->out, "<!ENTITY ");
3694 if (count < 0)
3695 return -1;
3696 sum += count;
3697
3698 if (pe != 0) {
Daniel Veillard500a1de2004-03-22 15:22:58 +00003699 count = xmlOutputBufferWriteString(writer->out, "% ");
Daniel Veillard1d211e22003-10-20 22:32:39 +00003700 if (count < 0)
3701 return -1;
3702 sum += count;
3703 }
3704
Daniel Veillardab69f362004-02-17 11:40:32 +00003705 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003706 if (count < 0)
3707 return -1;
3708 sum += count;
3709
3710 return sum;
3711}
3712
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003713/**
Daniel Veillard500a1de2004-03-22 15:22:58 +00003714 * xmlTextWriterEndDTDEntity:
3715 * @writer: the xmlTextWriterPtr
3716 *
3717 * End an xml DTD entity.
3718 *
3719 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3720 */
3721int
3722xmlTextWriterEndDTDEntity(xmlTextWriterPtr writer)
3723{
3724 int count;
3725 int sum;
3726 xmlLinkPtr lk;
3727 xmlTextWriterStackEntry *p;
3728
3729 if (writer == NULL)
3730 return -1;
3731
3732 sum = 0;
3733 lk = xmlListFront(writer->nodes);
3734 if (lk == 0)
3735 return -1;
3736
3737 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3738 if (p == 0)
3739 return -1;
3740
3741 switch (p->state) {
3742 case XML_TEXTWRITER_DTD_ENTY_TEXT:
3743 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3744 if (count < 0)
3745 return -1;
3746 sum += count;
3747 case XML_TEXTWRITER_DTD_ENTY:
3748 case XML_TEXTWRITER_DTD_PENT:
Daniel Veillard500a1de2004-03-22 15:22:58 +00003749 count = xmlOutputBufferWriteString(writer->out, ">");
3750 if (count < 0)
3751 return -1;
3752 sum += count;
3753 break;
3754 default:
3755 return -1;
3756 }
3757
3758 if (writer->indent) {
3759 count = xmlOutputBufferWriteString(writer->out, "\n");
3760 if (count < 0)
3761 return -1;
3762 sum += count;
3763 }
3764
3765 xmlListPopFront(writer->nodes);
3766 return sum;
3767}
3768
3769/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003770 * xmlTextWriterWriteFormatDTDInternalEntity:
3771 * @writer: the xmlTextWriterPtr
3772 * @pe: TRUE if this is a parameter entity, FALSE if not
3773 * @name: the name of the DTD entity
3774 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003775 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003776 *
3777 * Write a formatted DTD internal entity.
3778 *
3779 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3780 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00003781int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00003782xmlTextWriterWriteFormatDTDInternalEntity(xmlTextWriterPtr writer,
3783 int pe,
3784 const xmlChar * name,
3785 const char *format, ...)
3786{
3787 int rc;
3788 va_list ap;
3789
3790 va_start(ap, format);
3791
3792 rc = xmlTextWriterWriteVFormatDTDInternalEntity(writer, pe, name,
3793 format, ap);
3794
3795 va_end(ap);
3796 return rc;
3797}
3798
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003799/**
3800 * xmlTextWriterWriteVFormatDTDInternalEntity:
3801 * @writer: the xmlTextWriterPtr
3802 * @pe: TRUE if this is a parameter entity, FALSE if not
3803 * @name: the name of the DTD entity
3804 * @format: format string (see printf)
3805 * @argptr: pointer to the first member of the variable argument list.
3806 *
3807 * Write a formatted DTD internal entity.
3808 *
3809 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3810 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003811int
3812xmlTextWriterWriteVFormatDTDInternalEntity(xmlTextWriterPtr writer,
3813 int pe,
3814 const xmlChar * name,
3815 const char *format,
3816 va_list argptr)
3817{
3818 int rc;
3819 xmlChar *buf;
3820
3821 if (writer == NULL)
3822 return -1;
3823
3824 buf = xmlTextWriterVSprintf(format, argptr);
Daniel Veillardcb0ae192009-02-20 08:40:55 +00003825 if (buf == NULL)
3826 return -1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00003827
3828 rc = xmlTextWriterWriteDTDInternalEntity(writer, pe, name, buf);
3829
3830 xmlFree(buf);
3831 return rc;
3832}
3833
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003834/**
3835 * xmlTextWriterWriteDTDEntity:
3836 * @writer: the xmlTextWriterPtr
3837 * @pe: TRUE if this is a parameter entity, FALSE if not
3838 * @name: the name of the DTD entity
3839 * @pubid: the public identifier, which is an alternative to the system identifier
3840 * @sysid: the system identifier, which is the URI of the DTD
3841 * @ndataid: the xml notation name.
3842 * @content: content of the entity
3843 *
3844 * Write a DTD entity.
3845 *
3846 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3847 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003848int
3849xmlTextWriterWriteDTDEntity(xmlTextWriterPtr writer,
3850 int pe,
3851 const xmlChar * name,
3852 const xmlChar * pubid,
3853 const xmlChar * sysid,
3854 const xmlChar * ndataid,
3855 const xmlChar * content)
3856{
Daniel Veillard500a1de2004-03-22 15:22:58 +00003857 if ((content == NULL) && (pubid == NULL) && (sysid == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00003858 return -1;
3859 if ((pe != 0) && (ndataid != NULL))
3860 return -1;
3861
Daniel Veillard500a1de2004-03-22 15:22:58 +00003862 if ((pubid == NULL) && (sysid == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00003863 return xmlTextWriterWriteDTDInternalEntity(writer, pe, name,
3864 content);
3865
3866 return xmlTextWriterWriteDTDExternalEntity(writer, pe, name, pubid,
3867 sysid, ndataid);
3868}
3869
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003870/**
3871 * xmlTextWriterWriteDTDInternalEntity:
3872 * @writer: the xmlTextWriterPtr
3873 * @pe: TRUE if this is a parameter entity, FALSE if not
3874 * @name: the name of the DTD entity
3875 * @content: content of the entity
3876 *
3877 * Write a DTD internal entity.
3878 *
3879 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3880 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003881int
3882xmlTextWriterWriteDTDInternalEntity(xmlTextWriterPtr writer,
3883 int pe,
3884 const xmlChar * name,
3885 const xmlChar * content)
3886{
3887 int count;
3888 int sum;
3889
3890 if ((name == NULL) || (*name == '\0') || (content == NULL))
3891 return -1;
3892
3893 sum = 0;
3894 count = xmlTextWriterStartDTDEntity(writer, pe, name);
3895 if (count == -1)
3896 return -1;
3897 sum += count;
3898
Daniel Veillard1d211e22003-10-20 22:32:39 +00003899 count = xmlTextWriterWriteString(writer, content);
3900 if (count == -1)
3901 return -1;
3902 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00003903
3904 count = xmlTextWriterEndDTDEntity(writer);
3905 if (count == -1)
3906 return -1;
3907 sum += count;
3908
3909 return sum;
3910}
3911
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003912/**
3913 * xmlTextWriterWriteDTDExternalEntity:
3914 * @writer: the xmlTextWriterPtr
3915 * @pe: TRUE if this is a parameter entity, FALSE if not
3916 * @name: the name of the DTD entity
3917 * @pubid: the public identifier, which is an alternative to the system identifier
3918 * @sysid: the system identifier, which is the URI of the DTD
3919 * @ndataid: the xml notation name.
3920 *
Daniel Veillard500a1de2004-03-22 15:22:58 +00003921 * Write a DTD external entity. The entity must have been started with xmlTextWriterStartDTDEntity
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003922 *
3923 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3924 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003925int
3926xmlTextWriterWriteDTDExternalEntity(xmlTextWriterPtr writer,
3927 int pe,
3928 const xmlChar * name,
3929 const xmlChar * pubid,
3930 const xmlChar * sysid,
3931 const xmlChar * ndataid)
3932{
3933 int count;
3934 int sum;
3935
Daniel Veillard500a1de2004-03-22 15:22:58 +00003936 if (((pubid == NULL) && (sysid == NULL)))
Daniel Veillard1d211e22003-10-20 22:32:39 +00003937 return -1;
3938 if ((pe != 0) && (ndataid != NULL))
3939 return -1;
3940
3941 sum = 0;
3942 count = xmlTextWriterStartDTDEntity(writer, pe, name);
3943 if (count == -1)
3944 return -1;
3945 sum += count;
3946
Daniel Veillard500a1de2004-03-22 15:22:58 +00003947 count =
3948 xmlTextWriterWriteDTDExternalEntityContents(writer, pubid, sysid,
3949 ndataid);
3950 if (count < 0)
3951 return -1;
3952 sum += count;
3953
3954 count = xmlTextWriterEndDTDEntity(writer);
3955 if (count == -1)
3956 return -1;
3957 sum += count;
3958
3959 return sum;
3960}
3961
3962/**
3963 * xmlTextWriterWriteDTDExternalEntityContents:
3964 * @writer: the xmlTextWriterPtr
3965 * @pubid: the public identifier, which is an alternative to the system identifier
3966 * @sysid: the system identifier, which is the URI of the DTD
3967 * @ndataid: the xml notation name.
3968 *
3969 * Write the contents of a DTD external entity.
3970 *
3971 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3972 */
3973int
3974xmlTextWriterWriteDTDExternalEntityContents(xmlTextWriterPtr writer,
3975 const xmlChar * pubid,
3976 const xmlChar * sysid,
3977 const xmlChar * ndataid)
3978{
3979 int count;
3980 int sum;
3981 xmlLinkPtr lk;
3982 xmlTextWriterStackEntry *p;
3983
3984 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003985 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003986 "xmlTextWriterWriteDTDExternalEntityContents: xmlTextWriterPtr invalid!\n");
3987 return -1;
3988 }
3989
3990 sum = 0;
3991 lk = xmlListFront(writer->nodes);
3992 if (lk == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003993 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003994 "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n");
3995 return -1;
3996 }
3997
3998 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3999 if (p == 0)
4000 return -1;
4001
4002 switch (p->state) {
4003 case XML_TEXTWRITER_DTD_ENTY:
4004 break;
4005 case XML_TEXTWRITER_DTD_PENT:
4006 if (ndataid != NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004007 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00004008 "xmlTextWriterWriteDTDExternalEntityContents: notation not allowed with parameter entities!\n");
4009 return -1;
4010 }
4011 break;
4012 default:
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004013 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00004014 "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n");
4015 return -1;
4016 }
4017
Daniel Veillard1d211e22003-10-20 22:32:39 +00004018 if (pubid != 0) {
4019 if (sysid == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004020 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00004021 "xmlTextWriterWriteDTDExternalEntityContents: system identifier needed!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +00004022 return -1;
4023 }
4024
4025 count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
4026 if (count < 0)
4027 return -1;
4028 sum += count;
4029
4030 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4031 if (count < 0)
4032 return -1;
4033 sum += count;
4034
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004035 count =
4036 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004037 if (count < 0)
4038 return -1;
4039 sum += count;
4040
4041 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4042 if (count < 0)
4043 return -1;
4044 sum += count;
4045 }
4046
4047 if (sysid != 0) {
4048 if (pubid == 0) {
4049 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
4050 if (count < 0)
4051 return -1;
4052 sum += count;
4053 }
4054
4055 count = xmlOutputBufferWriteString(writer->out, " ");
4056 if (count < 0)
4057 return -1;
4058 sum += count;
4059
4060 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4061 if (count < 0)
4062 return -1;
4063 sum += count;
4064
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004065 count =
4066 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004067 if (count < 0)
4068 return -1;
4069 sum += count;
4070
4071 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4072 if (count < 0)
4073 return -1;
4074 sum += count;
4075 }
4076
4077 if (ndataid != NULL) {
4078 count = xmlOutputBufferWriteString(writer->out, " NDATA ");
4079 if (count < 0)
4080 return -1;
4081 sum += count;
4082
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004083 count =
4084 xmlOutputBufferWriteString(writer->out,
4085 (const char *) ndataid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004086 if (count < 0)
4087 return -1;
4088 sum += count;
4089 }
4090
Daniel Veillard1d211e22003-10-20 22:32:39 +00004091 return sum;
4092}
4093
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004094/**
4095 * xmlTextWriterWriteDTDNotation:
4096 * @writer: the xmlTextWriterPtr
4097 * @name: the name of the xml notation
4098 * @pubid: the public identifier, which is an alternative to the system identifier
4099 * @sysid: the system identifier, which is the URI of the DTD
4100 *
4101 * Write a DTD entity.
4102 *
4103 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
4104 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00004105int
4106xmlTextWriterWriteDTDNotation(xmlTextWriterPtr writer,
4107 const xmlChar * name,
4108 const xmlChar * pubid, const xmlChar * sysid)
4109{
4110 int count;
4111 int sum;
4112 xmlLinkPtr lk;
4113 xmlTextWriterStackEntry *p;
4114
4115 if (writer == NULL || name == NULL || *name == '\0')
4116 return -1;
4117
4118 sum = 0;
4119 lk = xmlListFront(writer->nodes);
4120 if (lk == 0) {
4121 return -1;
4122 }
4123
4124 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
Daniel Veillard500a1de2004-03-22 15:22:58 +00004125 if (p != 0) {
4126 switch (p->state) {
4127 case XML_TEXTWRITER_DTD:
4128 count = xmlOutputBufferWriteString(writer->out, " [");
4129 if (count < 0)
4130 return -1;
4131 sum += count;
4132 if (writer->indent) {
4133 count = xmlOutputBufferWriteString(writer->out, "\n");
4134 if (count < 0)
4135 return -1;
4136 sum += count;
4137 }
4138 p->state = XML_TEXTWRITER_DTD_TEXT;
4139 /* fallthrough */
4140 case XML_TEXTWRITER_DTD_TEXT:
4141 break;
4142 default:
4143 return -1;
4144 }
4145 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00004146
Daniel Veillard500a1de2004-03-22 15:22:58 +00004147 if (writer->indent) {
4148 count = xmlTextWriterWriteIndent(writer);
4149 if (count < 0)
Daniel Veillard1d211e22003-10-20 22:32:39 +00004150 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00004151 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00004152 }
4153
4154 count = xmlOutputBufferWriteString(writer->out, "<!NOTATION ");
4155 if (count < 0)
4156 return -1;
4157 sum += count;
4158 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
4159 if (count < 0)
4160 return -1;
4161 sum += count;
4162
4163 if (pubid != 0) {
4164 count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
4165 if (count < 0)
4166 return -1;
4167 sum += count;
4168 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4169 if (count < 0)
4170 return -1;
4171 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004172 count =
4173 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004174 if (count < 0)
4175 return -1;
4176 sum += count;
4177 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4178 if (count < 0)
4179 return -1;
4180 sum += count;
4181 }
4182
4183 if (sysid != 0) {
4184 if (pubid == 0) {
4185 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
4186 if (count < 0)
4187 return -1;
4188 sum += count;
4189 }
4190 count = xmlOutputBufferWriteString(writer->out, " ");
4191 if (count < 0)
4192 return -1;
4193 sum += count;
4194 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4195 if (count < 0)
4196 return -1;
4197 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004198 count =
4199 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004200 if (count < 0)
4201 return -1;
4202 sum += count;
4203 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4204 if (count < 0)
4205 return -1;
4206 sum += count;
4207 }
4208
4209 count = xmlOutputBufferWriteString(writer->out, ">");
4210 if (count < 0)
4211 return -1;
4212 sum += count;
4213
4214 return sum;
4215}
4216
4217/**
4218 * xmlTextWriterFlush:
4219 * @writer: the xmlTextWriterPtr
4220 *
4221 * Flush the output buffer.
4222 *
4223 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
4224 */
4225int
4226xmlTextWriterFlush(xmlTextWriterPtr writer)
4227{
4228 int count;
4229
4230 if (writer == NULL)
4231 return -1;
4232
4233 if (writer->out == NULL)
4234 count = 0;
4235 else
4236 count = xmlOutputBufferFlush(writer->out);
4237
4238 return count;
4239}
4240
4241/**
4242 * misc
4243 */
4244
4245/**
4246 * xmlFreeTextWriterStackEntry:
4247 * @lk: the xmlLinkPtr
4248 *
4249 * Free callback for the xmlList.
4250 */
4251static void
4252xmlFreeTextWriterStackEntry(xmlLinkPtr lk)
4253{
4254 xmlTextWriterStackEntry *p;
4255
4256 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
4257 if (p == 0)
4258 return;
4259
4260 if (p->name != 0)
4261 xmlFree(p->name);
4262 xmlFree(p);
4263}
4264
4265/**
4266 * xmlCmpTextWriterStackEntry:
4267 * @data0: the first data
4268 * @data1: the second data
4269 *
4270 * Compare callback for the xmlList.
4271 *
4272 * Returns -1, 0, 1
4273 */
4274static int
4275xmlCmpTextWriterStackEntry(const void *data0, const void *data1)
4276{
4277 xmlTextWriterStackEntry *p0;
4278 xmlTextWriterStackEntry *p1;
4279
4280 if (data0 == data1)
4281 return 0;
4282
4283 if (data0 == 0)
4284 return -1;
4285
4286 if (data1 == 0)
4287 return 1;
4288
4289 p0 = (xmlTextWriterStackEntry *) data0;
4290 p1 = (xmlTextWriterStackEntry *) data1;
4291
4292 return xmlStrcmp(p0->name, p1->name);
4293}
4294
4295/**
4296 * misc
4297 */
4298
4299/**
Rob Richardsb8769d62007-06-08 08:50:47 +00004300 * xmlTextWriterOutputNSDecl:
4301 * @writer: the xmlTextWriterPtr
4302 *
4303 * Output the current namespace declarations.
4304 */
4305static int
4306xmlTextWriterOutputNSDecl(xmlTextWriterPtr writer)
4307{
4308 xmlLinkPtr lk;
4309 xmlTextWriterNsStackEntry *np;
4310 int count;
4311 int sum;
4312
4313 sum = 0;
4314 while (!xmlListEmpty(writer->nsstack)) {
4315 xmlChar *namespaceURI = NULL;
4316 xmlChar *prefix = NULL;
4317
4318 lk = xmlListFront(writer->nsstack);
4319 np = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
4320
4321 if (np != 0) {
4322 namespaceURI = xmlStrdup(np->uri);
4323 prefix = xmlStrdup(np->prefix);
4324 }
4325
4326 xmlListPopFront(writer->nsstack);
4327
4328 if (np != 0) {
4329 count = xmlTextWriterWriteAttribute(writer, prefix, namespaceURI);
4330 xmlFree(namespaceURI);
4331 xmlFree(prefix);
4332
4333 if (count < 0) {
4334 xmlListDelete(writer->nsstack);
4335 writer->nsstack = NULL;
4336 return -1;
4337 }
4338 sum += count;
4339 }
4340 }
4341 return sum;
4342}
4343
4344/**
Daniel Veillard1d211e22003-10-20 22:32:39 +00004345 * xmlFreeTextWriterNsStackEntry:
4346 * @lk: the xmlLinkPtr
4347 *
4348 * Free callback for the xmlList.
4349 */
4350static void
4351xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk)
4352{
4353 xmlTextWriterNsStackEntry *p;
4354
4355 p = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
4356 if (p == 0)
4357 return;
4358
4359 if (p->prefix != 0)
4360 xmlFree(p->prefix);
4361 if (p->uri != 0)
4362 xmlFree(p->uri);
4363
4364 xmlFree(p);
4365}
4366
4367/**
4368 * xmlCmpTextWriterNsStackEntry:
4369 * @data0: the first data
4370 * @data1: the second data
4371 *
4372 * Compare callback for the xmlList.
4373 *
4374 * Returns -1, 0, 1
4375 */
4376static int
4377xmlCmpTextWriterNsStackEntry(const void *data0, const void *data1)
4378{
4379 xmlTextWriterNsStackEntry *p0;
4380 xmlTextWriterNsStackEntry *p1;
4381 int rc;
4382
4383 if (data0 == data1)
4384 return 0;
4385
4386 if (data0 == 0)
4387 return -1;
4388
4389 if (data1 == 0)
4390 return 1;
4391
4392 p0 = (xmlTextWriterNsStackEntry *) data0;
4393 p1 = (xmlTextWriterNsStackEntry *) data1;
4394
4395 rc = xmlStrcmp(p0->prefix, p1->prefix);
4396
Rob Richardsb8769d62007-06-08 08:50:47 +00004397 if ((rc != 0) || (p0->elem != p1->elem))
4398 rc = -1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00004399
4400 return rc;
4401}
4402
4403/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004404 * xmlTextWriterWriteDocCallback:
4405 * @context: the xmlBufferPtr
4406 * @str: the data to write
4407 * @len: the length of the data
4408 *
4409 * Write callback for the xmlOutputBuffer with target xmlBuffer
4410 *
4411 * Returns -1, 0, 1
4412 */
4413static int
4414xmlTextWriterWriteDocCallback(void *context, const xmlChar * str, int len)
4415{
4416 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context;
4417 int rc;
4418
Daniel Veillard1d913862003-11-21 00:28:39 +00004419 if ((rc = xmlParseChunk(ctxt, (const char *) str, len, 0)) != 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004420 xmlWriterErrMsgInt(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004421 "xmlTextWriterWriteDocCallback : XML error %d !\n",
4422 rc);
4423 return -1;
4424 }
4425
4426 return len;
4427}
4428
4429/**
4430 * xmlTextWriterCloseDocCallback:
4431 * @context: the xmlBufferPtr
4432 *
4433 * Close callback for the xmlOutputBuffer with target xmlBuffer
4434 *
4435 * Returns -1, 0, 1
4436 */
4437static int
4438xmlTextWriterCloseDocCallback(void *context)
4439{
4440 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context;
4441 int rc;
4442
4443 if ((rc = xmlParseChunk(ctxt, NULL, 0, 1)) != 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004444 xmlWriterErrMsgInt(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004445 "xmlTextWriterWriteDocCallback : XML error %d !\n",
4446 rc);
4447 return -1;
4448 }
4449
4450 return 0;
4451}
4452
4453/**
Daniel Veillard1d211e22003-10-20 22:32:39 +00004454 * xmlTextWriterVSprintf:
4455 * @format: see printf
4456 * @argptr: pointer to the first member of the variable argument list.
4457 *
4458 * Utility function for formatted output
4459 *
4460 * Returns a new xmlChar buffer with the data or NULL on error. This buffer must be freed.
4461 */
4462static xmlChar *
4463xmlTextWriterVSprintf(const char *format, va_list argptr)
4464{
4465 int size;
4466 int count;
4467 xmlChar *buf;
William M. Brackf4caa5e2005-10-20 09:04:05 +00004468 va_list locarg;
Daniel Veillard1d211e22003-10-20 22:32:39 +00004469
4470 size = BUFSIZ;
4471 buf = (xmlChar *) xmlMalloc(size);
4472 if (buf == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004473 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00004474 "xmlTextWriterVSprintf : out of memory!\n");
4475 return NULL;
4476 }
4477
William M. Brackf4caa5e2005-10-20 09:04:05 +00004478 VA_COPY(locarg, argptr);
4479 while (((count = vsnprintf((char *) buf, size, format, locarg)) < 0)
Daniel Veillard1d211e22003-10-20 22:32:39 +00004480 || (count == size - 1) || (count == size) || (count > size)) {
William M. Brackf4caa5e2005-10-20 09:04:05 +00004481 va_end(locarg);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004482 xmlFree(buf);
4483 size += BUFSIZ;
4484 buf = (xmlChar *) xmlMalloc(size);
4485 if (buf == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004486 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00004487 "xmlTextWriterVSprintf : out of memory!\n");
4488 return NULL;
4489 }
William M. Brackf4caa5e2005-10-20 09:04:05 +00004490 VA_COPY(locarg, argptr);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004491 }
William M. Brackf4caa5e2005-10-20 09:04:05 +00004492 va_end(locarg);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004493
4494 return buf;
4495}
4496
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004497/**
4498 * xmlTextWriterStartDocumentCallback:
4499 * @ctx: the user data (XML parser context)
4500 *
4501 * called at the start of document processing.
4502 */
4503static void
4504xmlTextWriterStartDocumentCallback(void *ctx)
4505{
4506 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
4507 xmlDocPtr doc;
4508
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004509 if (ctxt->html) {
4510#ifdef LIBXML_HTML_ENABLED
4511 if (ctxt->myDoc == NULL)
4512 ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
4513 if (ctxt->myDoc == NULL) {
4514 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
4515 ctxt->sax->error(ctxt->userData,
4516 "SAX.startDocument(): out of memory\n");
4517 ctxt->errNo = XML_ERR_NO_MEMORY;
4518 ctxt->instate = XML_PARSER_EOF;
4519 ctxt->disableSAX = 1;
4520 return;
4521 }
4522#else
Daniel Veillardd0cf7f62004-11-09 16:17:02 +00004523 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004524 "libxml2 built without HTML support\n");
4525 ctxt->errNo = XML_ERR_INTERNAL_ERROR;
4526 ctxt->instate = XML_PARSER_EOF;
4527 ctxt->disableSAX = 1;
4528 return;
4529#endif
4530 } else {
4531 doc = ctxt->myDoc;
4532 if (doc == NULL)
4533 doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
4534 if (doc != NULL) {
4535 if (doc->children == NULL) {
4536 if (ctxt->encoding != NULL)
4537 doc->encoding = xmlStrdup(ctxt->encoding);
4538 else
4539 doc->encoding = NULL;
4540 doc->standalone = ctxt->standalone;
4541 }
4542 } else {
4543 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
4544 ctxt->sax->error(ctxt->userData,
4545 "SAX.startDocument(): out of memory\n");
4546 ctxt->errNo = XML_ERR_NO_MEMORY;
4547 ctxt->instate = XML_PARSER_EOF;
4548 ctxt->disableSAX = 1;
4549 return;
4550 }
4551 }
4552 if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) &&
4553 (ctxt->input != NULL) && (ctxt->input->filename != NULL)) {
4554 ctxt->myDoc->URL =
4555 xmlCanonicPath((const xmlChar *) ctxt->input->filename);
4556 if (ctxt->myDoc->URL == NULL)
4557 ctxt->myDoc->URL =
4558 xmlStrdup((const xmlChar *) ctxt->input->filename);
4559 }
4560}
4561
Daniel Veillard2cca4462004-01-02 20:04:23 +00004562/**
4563 * xmlTextWriterSetIndent:
4564 * @writer: the xmlTextWriterPtr
4565 * @indent: do indentation?
4566 *
4567 * Set indentation output. indent = 0 do not indentation. indent > 0 do indentation.
4568 *
4569 * Returns -1 on error or 0 otherwise.
4570 */
4571int
Daniel Veillardab69f362004-02-17 11:40:32 +00004572xmlTextWriterSetIndent(xmlTextWriterPtr writer, int indent)
Daniel Veillard2cca4462004-01-02 20:04:23 +00004573{
Daniel Veillarde43cc572004-11-03 11:50:29 +00004574 if ((writer == NULL) || (indent < 0))
Daniel Veillardab69f362004-02-17 11:40:32 +00004575 return -1;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004576
Daniel Veillardab69f362004-02-17 11:40:32 +00004577 writer->indent = indent;
4578 writer->doindent = 1;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004579
Daniel Veillardab69f362004-02-17 11:40:32 +00004580 return 0;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004581}
4582
4583/**
4584 * xmlTextWriterSetIndentString:
4585 * @writer: the xmlTextWriterPtr
4586 * @str: the xmlChar string
4587 *
4588 * Set string indentation.
4589 *
4590 * Returns -1 on error or 0 otherwise.
4591 */
4592int
Daniel Veillardab69f362004-02-17 11:40:32 +00004593xmlTextWriterSetIndentString(xmlTextWriterPtr writer, const xmlChar * str)
Daniel Veillard2cca4462004-01-02 20:04:23 +00004594{
Daniel Veillarde43cc572004-11-03 11:50:29 +00004595 if ((writer == NULL) || (!str))
Daniel Veillardab69f362004-02-17 11:40:32 +00004596 return -1;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004597
Daniel Veillardab69f362004-02-17 11:40:32 +00004598 if (writer->ichar != NULL)
4599 xmlFree(writer->ichar);
4600 writer->ichar = xmlStrdup(str);
4601
4602 if (!writer->ichar)
4603 return -1;
4604 else
4605 return 0;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004606}
4607
4608/**
4609 * xmlTextWriterWriteIndent:
4610 * @writer: the xmlTextWriterPtr
4611 *
4612 * Write indent string.
4613 *
4614 * Returns -1 on error or the number of strings written.
Daniel Veillardab69f362004-02-17 11:40:32 +00004615 */
Daniel Veillard2cca4462004-01-02 20:04:23 +00004616static int
Daniel Veillardab69f362004-02-17 11:40:32 +00004617xmlTextWriterWriteIndent(xmlTextWriterPtr writer)
Daniel Veillard2cca4462004-01-02 20:04:23 +00004618{
Daniel Veillardab69f362004-02-17 11:40:32 +00004619 int lksize;
4620 int i;
4621 int ret;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004622
Daniel Veillardab69f362004-02-17 11:40:32 +00004623 lksize = xmlListSize(writer->nodes);
4624 if (lksize < 1)
4625 return (-1); /* list is empty */
4626 for (i = 0; i < (lksize - 1); i++) {
4627 ret = xmlOutputBufferWriteString(writer->out,
4628 (const char *) writer->ichar);
4629 if (ret == -1)
4630 return (-1);
4631 }
4632
4633 return (lksize - 1);
Daniel Veillard2cca4462004-01-02 20:04:23 +00004634}
4635
Daniel Veillard500a1de2004-03-22 15:22:58 +00004636/**
4637 * xmlTextWriterHandleStateDependencies:
4638 * @writer: the xmlTextWriterPtr
4639 * @p: the xmlTextWriterStackEntry
4640 *
4641 * Write state dependent strings.
4642 *
4643 * Returns -1 on error or the number of characters written.
4644 */
4645static int
4646xmlTextWriterHandleStateDependencies(xmlTextWriterPtr writer,
4647 xmlTextWriterStackEntry * p)
4648{
4649 int count;
4650 int sum;
4651 char extra[3];
4652
4653 if (writer == NULL)
4654 return -1;
4655
4656 if (p == NULL)
4657 return 0;
4658
4659 sum = 0;
4660 extra[0] = extra[1] = extra[2] = '\0';
4661 if (p != 0) {
4662 sum = 0;
4663 switch (p->state) {
4664 case XML_TEXTWRITER_NAME:
Rob Richardsb8769d62007-06-08 08:50:47 +00004665 /* Output namespace declarations */
4666 count = xmlTextWriterOutputNSDecl(writer);
4667 if (count < 0)
4668 return -1;
4669 sum += count;
Daniel Veillard500a1de2004-03-22 15:22:58 +00004670 extra[0] = '>';
4671 p->state = XML_TEXTWRITER_TEXT;
4672 break;
4673 case XML_TEXTWRITER_PI:
4674 extra[0] = ' ';
4675 p->state = XML_TEXTWRITER_PI_TEXT;
4676 break;
4677 case XML_TEXTWRITER_DTD:
4678 extra[0] = ' ';
4679 extra[1] = '[';
4680 p->state = XML_TEXTWRITER_DTD_TEXT;
4681 break;
4682 case XML_TEXTWRITER_DTD_ELEM:
4683 extra[0] = ' ';
4684 p->state = XML_TEXTWRITER_DTD_ELEM_TEXT;
4685 break;
4686 case XML_TEXTWRITER_DTD_ATTL:
4687 extra[0] = ' ';
4688 p->state = XML_TEXTWRITER_DTD_ATTL_TEXT;
4689 break;
4690 case XML_TEXTWRITER_DTD_ENTY:
4691 case XML_TEXTWRITER_DTD_PENT:
4692 extra[0] = ' ';
4693 extra[1] = writer->qchar;
4694 p->state = XML_TEXTWRITER_DTD_ENTY_TEXT;
4695 break;
4696 default:
4697 break;
4698 }
4699 }
4700
4701 if (*extra != '\0') {
4702 count = xmlOutputBufferWriteString(writer->out, extra);
4703 if (count < 0)
4704 return -1;
4705 sum += count;
4706 }
4707
4708 return sum;
4709}
4710
Daniel Veillard5d4644e2005-04-01 13:11:58 +00004711#define bottom_xmlwriter
4712#include "elfgcchack.h"
Daniel Veillard1d211e22003-10-20 22:32:39 +00004713#endif