blob: 2e67a4f9c7360fe43c123a0c06c093b8d7c18d38 [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);
100static void xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk);
101static int xmlCmpTextWriterNsStackEntry(const void *data0,
102 const void *data1);
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000103static int xmlTextWriterWriteDocCallback(void *context,
104 const xmlChar * str, int len);
105static int xmlTextWriterCloseDocCallback(void *context);
106
Daniel Veillard1d211e22003-10-20 22:32:39 +0000107static xmlChar *xmlTextWriterVSprintf(const char *format, va_list argptr);
108static int xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len,
109 const unsigned char *data);
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000110static void xmlTextWriterStartDocumentCallback(void *ctx);
Daniel Veillardab69f362004-02-17 11:40:32 +0000111static int xmlTextWriterWriteIndent(xmlTextWriterPtr writer);
Daniel Veillard500a1de2004-03-22 15:22:58 +0000112static int
113 xmlTextWriterHandleStateDependencies(xmlTextWriterPtr writer,
114 xmlTextWriterStackEntry * p);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000115
116/**
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000117 * xmlWriterErrMsg:
118 * @ctxt: a writer context
119 * @error: the error number
120 * @msg: the error message
121 *
122 * Handle a writer error
123 */
124static void
125xmlWriterErrMsg(xmlTextWriterPtr ctxt, xmlParserErrors error,
126 const char *msg)
127{
128 if (ctxt != NULL) {
129 __xmlRaiseError(NULL, NULL, NULL, ctxt->ctxt,
130 NULL, XML_FROM_WRITER, error, XML_ERR_FATAL,
131 NULL, 0, NULL, NULL, NULL, 0, 0, msg);
132 } else {
133 __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_WRITER, error,
134 XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, 0, 0, msg);
135 }
136}
137
138/**
139 * xmlWriterErrMsgInt:
140 * @ctxt: a writer context
141 * @error: the error number
142 * @msg: the error message
143 * @val: an int
144 *
145 * Handle a writer error
146 */
147static void
148xmlWriterErrMsgInt(xmlTextWriterPtr ctxt, xmlParserErrors error,
149 const char *msg, int val)
150{
151 if (ctxt != NULL) {
152 __xmlRaiseError(NULL, NULL, NULL, ctxt->ctxt,
153 NULL, XML_FROM_WRITER, error, XML_ERR_FATAL,
154 NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
155 } else {
156 __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_WRITER, error,
157 XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
158 }
159}
160
161/**
Daniel Veillard1d211e22003-10-20 22:32:39 +0000162 * xmlNewTextWriter:
163 * @out: an xmlOutputBufferPtr
164 *
165 * Create a new xmlNewTextWriter structure using an xmlOutputBufferPtr
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000166 * NOTE: the @out parameter will be deallocated when the writer is closed
167 * (if the call succeed.)
Daniel Veillard1d211e22003-10-20 22:32:39 +0000168 *
169 * Returns the new xmlTextWriterPtr or NULL in case of error
170 */
171xmlTextWriterPtr
172xmlNewTextWriter(xmlOutputBufferPtr out)
173{
174 xmlTextWriterPtr ret;
175
176 ret = (xmlTextWriterPtr) xmlMalloc(sizeof(xmlTextWriter));
177 if (ret == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000178 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000179 "xmlNewTextWriter : out of memory!\n");
180 return NULL;
181 }
182 memset(ret, 0, (size_t) sizeof(xmlTextWriter));
183
184 ret->nodes = xmlListCreate((xmlListDeallocator)
185 xmlFreeTextWriterStackEntry,
186 (xmlListDataCompare)
187 xmlCmpTextWriterStackEntry);
188 if (ret->nodes == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000189 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000190 "xmlNewTextWriter : out of memory!\n");
191 xmlFree(ret);
192 return NULL;
193 }
194
195 ret->nsstack = xmlListCreate((xmlListDeallocator)
196 xmlFreeTextWriterNsStackEntry,
197 (xmlListDataCompare)
198 xmlCmpTextWriterNsStackEntry);
199 if (ret->nsstack == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000200 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000201 "xmlNewTextWriter : out of memory!\n");
Daniel Veillard500a1de2004-03-22 15:22:58 +0000202 xmlListDelete(ret->nodes);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000203 xmlFree(ret);
204 return NULL;
205 }
206
207 ret->out = out;
Daniel Veillardab69f362004-02-17 11:40:32 +0000208 ret->ichar = xmlStrdup(BAD_CAST " ");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000209 ret->qchar = '"';
210
Daniel Veillard500a1de2004-03-22 15:22:58 +0000211 if (!ret->ichar) {
212 xmlListDelete(ret->nodes);
213 xmlListDelete(ret->nsstack);
214 xmlFree(ret);
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000215 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000216 "xmlNewTextWriter : out of memory!\n");
Daniel Veillardab69f362004-02-17 11:40:32 +0000217 return NULL;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000218 }
Rob Richards9db68f02006-08-16 22:48:51 +0000219
220 ret->doc = xmlNewDoc(NULL);
221
Daniel Veillarda521d282004-11-09 14:59:59 +0000222 ret->no_doc_free = 0;
Daniel Veillardab69f362004-02-17 11:40:32 +0000223
Daniel Veillard1d211e22003-10-20 22:32:39 +0000224 return ret;
225}
226
227/**
228 * xmlNewTextWriterFilename:
229 * @uri: the URI of the resource for the output
230 * @compression: compress the output?
231 *
232 * Create a new xmlNewTextWriter structure with @uri as output
233 *
234 * Returns the new xmlTextWriterPtr or NULL in case of error
235 */
236xmlTextWriterPtr
237xmlNewTextWriterFilename(const char *uri, int compression)
238{
239 xmlTextWriterPtr ret;
240 xmlOutputBufferPtr out;
241
242 out = xmlOutputBufferCreateFilename(uri, NULL, compression);
243 if (out == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000244 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000245 "xmlNewTextWriterFilename : out of memory!\n");
246 return NULL;
247 }
248
249 ret = xmlNewTextWriter(out);
250 if (ret == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000251 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000252 "xmlNewTextWriterFilename : out of memory!\n");
253 xmlOutputBufferClose(out);
254 return NULL;
255 }
256
Daniel Veillard2cca4462004-01-02 20:04:23 +0000257 ret->indent = 0;
258 ret->doindent = 0;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000259 return ret;
260}
261
262/**
263 * xmlNewTextWriterMemory:
264 * @buf: xmlBufferPtr
265 * @compression: compress the output?
266 *
267 * Create a new xmlNewTextWriter structure with @buf as output
268 * TODO: handle compression
269 *
270 * Returns the new xmlTextWriterPtr or NULL in case of error
271 */
272xmlTextWriterPtr
273xmlNewTextWriterMemory(xmlBufferPtr buf, int compression ATTRIBUTE_UNUSED)
274{
275 xmlTextWriterPtr ret;
276 xmlOutputBufferPtr out;
277
278/*::todo handle compression */
Rob Richardsa44f2342005-11-09 18:03:45 +0000279 out = xmlOutputBufferCreateBuffer(buf, NULL);
280
Daniel Veillard1d211e22003-10-20 22:32:39 +0000281 if (out == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000282 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000283 "xmlNewTextWriterMemory : out of memory!\n");
284 return NULL;
285 }
286
287 ret = xmlNewTextWriter(out);
288 if (ret == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000289 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000290 "xmlNewTextWriterMemory : out of memory!\n");
291 xmlOutputBufferClose(out);
292 return NULL;
293 }
294
295 return ret;
296}
297
298/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000299 * xmlNewTextWriterPushParser:
300 * @ctxt: xmlParserCtxtPtr to hold the new XML document tree
301 * @compression: compress the output?
302 *
303 * Create a new xmlNewTextWriter structure with @ctxt as output
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000304 * NOTE: the @ctxt context will be freed with the resulting writer
305 * (if the call succeeds).
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000306 * TODO: handle compression
307 *
308 * Returns the new xmlTextWriterPtr or NULL in case of error
309 */
310xmlTextWriterPtr
Daniel Veillard1d913862003-11-21 00:28:39 +0000311xmlNewTextWriterPushParser(xmlParserCtxtPtr ctxt,
312 int compression ATTRIBUTE_UNUSED)
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000313{
314 xmlTextWriterPtr ret;
315 xmlOutputBufferPtr out;
316
Daniel Veillard500a1de2004-03-22 15:22:58 +0000317 if (ctxt == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000318 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000319 "xmlNewTextWriterPushParser : invalid context!\n");
320 return NULL;
321 }
322
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000323 out = xmlOutputBufferCreateIO((xmlOutputWriteCallback)
324 xmlTextWriterWriteDocCallback,
325 (xmlOutputCloseCallback)
326 xmlTextWriterCloseDocCallback,
327 (void *) ctxt, NULL);
328 if (out == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000329 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000330 "xmlNewTextWriterPushParser : error at xmlOutputBufferCreateIO!\n");
331 return NULL;
332 }
333
334 ret = xmlNewTextWriter(out);
335 if (ret == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000336 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000337 "xmlNewTextWriterPushParser : error at xmlNewTextWriter!\n");
338 xmlOutputBufferClose(out);
339 return NULL;
340 }
341
Daniel Veillard20c5e782004-01-21 09:57:31 +0000342 ret->ctxt = ctxt;
343
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000344 return ret;
345}
346
347/**
348 * xmlNewTextWriterDoc:
349 * @doc: address of a xmlDocPtr to hold the new XML document tree
350 * @compression: compress the output?
351 *
352 * Create a new xmlNewTextWriter structure with @*doc as output
353 *
354 * Returns the new xmlTextWriterPtr or NULL in case of error
355 */
356xmlTextWriterPtr
357xmlNewTextWriterDoc(xmlDocPtr * doc, int compression)
358{
359 xmlTextWriterPtr ret;
360 xmlSAXHandler saxHandler;
361 xmlParserCtxtPtr ctxt;
362
363 memset(&saxHandler, '\0', sizeof(saxHandler));
364 xmlSAX2InitDefaultSAXHandler(&saxHandler, 1);
365 saxHandler.startDocument = xmlTextWriterStartDocumentCallback;
366 saxHandler.startElement = xmlSAX2StartElement;
367 saxHandler.endElement = xmlSAX2EndElement;
368
369 ctxt = xmlCreatePushParserCtxt(&saxHandler, NULL, NULL, 0, NULL);
370 if (ctxt == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000371 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000372 "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\n");
373 return NULL;
374 }
Daniel Veillard03a53c32004-10-26 16:06:51 +0000375 /*
376 * For some reason this seems to completely break if node names
377 * are interned.
378 */
379 ctxt->dictNames = 0;
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000380
Daniel Veillard1d913862003-11-21 00:28:39 +0000381 ctxt->myDoc = xmlNewDoc(BAD_CAST XML_DEFAULT_VERSION);
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000382 if (ctxt->myDoc == NULL) {
383 xmlFreeParserCtxt(ctxt);
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000384 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000385 "xmlNewTextWriterDoc : error at xmlNewDoc!\n");
386 return NULL;
387 }
388
389 ret = xmlNewTextWriterPushParser(ctxt, compression);
390 if (ret == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000391 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000392 "xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n");
393 return NULL;
394 }
395
Daniel Veillard500a1de2004-03-22 15:22:58 +0000396 xmlSetDocCompressMode(ctxt->myDoc, compression);
397
Daniel Veillarda521d282004-11-09 14:59:59 +0000398 if (doc != NULL) {
Daniel Veillard500a1de2004-03-22 15:22:58 +0000399 *doc = ctxt->myDoc;
Daniel Veillarda521d282004-11-09 14:59:59 +0000400 ret->no_doc_free = 1;
401 }
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000402
403 return ret;
404}
405
406/**
407 * xmlNewTextWriterTree:
408 * @doc: xmlDocPtr
409 * @node: xmlNodePtr or NULL for doc->children
410 * @compression: compress the output?
411 *
412 * Create a new xmlNewTextWriter structure with @doc as output
413 * starting at @node
414 *
415 * Returns the new xmlTextWriterPtr or NULL in case of error
416 */
417xmlTextWriterPtr
418xmlNewTextWriterTree(xmlDocPtr doc, xmlNodePtr node, int compression)
419{
420 xmlTextWriterPtr ret;
421 xmlSAXHandler saxHandler;
422 xmlParserCtxtPtr ctxt;
423
424 if (doc == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000425 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000426 "xmlNewTextWriterTree : invalid document tree!\n");
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000427 return NULL;
428 }
429
430 memset(&saxHandler, '\0', sizeof(saxHandler));
431 xmlSAX2InitDefaultSAXHandler(&saxHandler, 1);
432 saxHandler.startDocument = xmlTextWriterStartDocumentCallback;
433 saxHandler.startElement = xmlSAX2StartElement;
434 saxHandler.endElement = xmlSAX2EndElement;
435
436 ctxt = xmlCreatePushParserCtxt(&saxHandler, NULL, NULL, 0, NULL);
437 if (ctxt == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000438 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000439 "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\n");
440 return NULL;
441 }
Daniel Veillard03a53c32004-10-26 16:06:51 +0000442 /*
443 * For some reason this seems to completely break if node names
444 * are interned.
445 */
446 ctxt->dictNames = 0;
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000447
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000448 ret = xmlNewTextWriterPushParser(ctxt, compression);
449 if (ret == NULL) {
Daniel Veillard500a1de2004-03-22 15:22:58 +0000450 xmlFreeParserCtxt(ctxt);
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000451 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000452 "xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n");
453 return NULL;
454 }
455
Daniel Veillard500a1de2004-03-22 15:22:58 +0000456 ctxt->myDoc = doc;
457 ctxt->node = node;
Daniel Veillarda521d282004-11-09 14:59:59 +0000458 ret->no_doc_free = 1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000459
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000460 xmlSetDocCompressMode(doc, compression);
461
462 return ret;
463}
464
465/**
Daniel Veillard1d211e22003-10-20 22:32:39 +0000466 * xmlFreeTextWriter:
467 * @writer: the xmlTextWriterPtr
468 *
469 * Deallocate all the resources associated to the writer
470 */
471void
472xmlFreeTextWriter(xmlTextWriterPtr writer)
473{
474 if (writer == NULL)
475 return;
476
477 if (writer->out != NULL)
478 xmlOutputBufferClose(writer->out);
479
480 if (writer->nodes != NULL)
481 xmlListDelete(writer->nodes);
482
483 if (writer->nsstack != NULL)
484 xmlListDelete(writer->nsstack);
485
Daniel Veillarda521d282004-11-09 14:59:59 +0000486 if (writer->ctxt != NULL) {
487 if ((writer->ctxt->myDoc != NULL) && (writer->no_doc_free == 0)) {
488 xmlFreeDoc(writer->ctxt->myDoc);
489 writer->ctxt->myDoc = NULL;
490 }
Daniel Veillard20c5e782004-01-21 09:57:31 +0000491 xmlFreeParserCtxt(writer->ctxt);
Daniel Veillarda521d282004-11-09 14:59:59 +0000492 }
Daniel Veillard20c5e782004-01-21 09:57:31 +0000493
Rob Richards9db68f02006-08-16 22:48:51 +0000494 if (writer->doc != NULL)
495 xmlFreeDoc(writer->doc);
496
Daniel Veillard4773df22004-01-23 13:15:13 +0000497 if (writer->ichar != NULL)
498 xmlFree(writer->ichar);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000499 xmlFree(writer);
500}
501
502/**
503 * xmlTextWriterStartDocument:
504 * @writer: the xmlTextWriterPtr
505 * @version: the xml version ("1.0") or NULL for default ("1.0")
506 * @encoding: the encoding or NULL for default
507 * @standalone: "yes" or "no" or NULL for default
508 *
509 * Start a new xml document
510 *
511 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
512 */
513int
514xmlTextWriterStartDocument(xmlTextWriterPtr writer, const char *version,
515 const char *encoding, const char *standalone)
516{
517 int count;
518 int sum;
519 xmlLinkPtr lk;
520 xmlCharEncodingHandlerPtr encoder;
521
Daniel Veillard500a1de2004-03-22 15:22:58 +0000522 if ((writer == NULL) || (writer->out == NULL)) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000523 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000524 "xmlTextWriterStartDocument : invalid writer!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000525 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000526 }
Daniel Veillard1d211e22003-10-20 22:32:39 +0000527
528 lk = xmlListFront(writer->nodes);
529 if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000530 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000531 "xmlTextWriterStartDocument : not allowed in this context!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000532 return -1;
533 }
534
535 encoder = NULL;
536 if (encoding != NULL) {
537 encoder = xmlFindCharEncodingHandler(encoding);
538 if (encoder == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000539 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000540 "xmlTextWriterStartDocument : out of memory!\n");
541 return -1;
542 }
543 }
544
545 writer->out->encoder = encoder;
546 if (encoder != NULL) {
547 writer->out->conv = xmlBufferCreateSize(4000);
548 xmlCharEncOutFunc(encoder, writer->out->conv, NULL);
Rob Richards9db68f02006-08-16 22:48:51 +0000549 if ((writer->doc != NULL) && (writer->doc->encoding == NULL))
550 writer->doc->encoding = xmlStrdup((xmlChar *)writer->out->encoder->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000551 } else
552 writer->out->conv = NULL;
553
554 sum = 0;
555 count = xmlOutputBufferWriteString(writer->out, "<?xml version=");
556 if (count < 0)
557 return -1;
558 sum += count;
559 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
560 if (count < 0)
561 return -1;
562 sum += count;
563 if (version != 0)
564 count = xmlOutputBufferWriteString(writer->out, version);
565 else
566 count = xmlOutputBufferWriteString(writer->out, "1.0");
567 if (count < 0)
568 return -1;
569 sum += count;
570 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
571 if (count < 0)
572 return -1;
573 sum += count;
574 if (writer->out->encoder != 0) {
575 count = xmlOutputBufferWriteString(writer->out, " encoding=");
576 if (count < 0)
577 return -1;
578 sum += count;
579 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
580 if (count < 0)
581 return -1;
582 sum += count;
583 count =
584 xmlOutputBufferWriteString(writer->out,
585 writer->out->encoder->name);
586 if (count < 0)
587 return -1;
588 sum += count;
589 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
590 if (count < 0)
591 return -1;
592 sum += count;
593 }
594
595 if (standalone != 0) {
596 count = xmlOutputBufferWriteString(writer->out, " standalone=");
597 if (count < 0)
598 return -1;
599 sum += count;
600 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
601 if (count < 0)
602 return -1;
603 sum += count;
604 count = xmlOutputBufferWriteString(writer->out, standalone);
605 if (count < 0)
606 return -1;
607 sum += count;
608 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
609 if (count < 0)
610 return -1;
611 sum += count;
612 }
613
614 count = xmlOutputBufferWriteString(writer->out, "?>\n");
615 if (count < 0)
616 return -1;
617 sum += count;
618
619 return sum;
620}
621
622/**
623 * xmlTextWriterEndDocument:
624 * @writer: the xmlTextWriterPtr
625 *
626 * End an xml document. All open elements are closed
627 *
628 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
629 */
630int
631xmlTextWriterEndDocument(xmlTextWriterPtr writer)
632{
633 int count;
634 int sum;
635 xmlLinkPtr lk;
636 xmlTextWriterStackEntry *p;
637
Daniel Veillard500a1de2004-03-22 15:22:58 +0000638 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000639 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000640 "xmlTextWriterEndDocument : invalid writer!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000641 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000642 }
Daniel Veillard1d211e22003-10-20 22:32:39 +0000643
644 sum = 0;
645 while ((lk = xmlListFront(writer->nodes)) != NULL) {
646 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
647 if (p == 0)
648 break;
649 switch (p->state) {
650 case XML_TEXTWRITER_NAME:
651 case XML_TEXTWRITER_ATTRIBUTE:
652 case XML_TEXTWRITER_TEXT:
653 count = xmlTextWriterEndElement(writer);
654 if (count < 0)
655 return -1;
656 sum += count;
657 break;
658 case XML_TEXTWRITER_PI:
659 case XML_TEXTWRITER_PI_TEXT:
660 count = xmlTextWriterEndPI(writer);
661 if (count < 0)
662 return -1;
663 sum += count;
664 break;
665 case XML_TEXTWRITER_CDATA:
666 count = xmlTextWriterEndCDATA(writer);
667 if (count < 0)
668 return -1;
669 sum += count;
670 break;
671 case XML_TEXTWRITER_DTD:
Daniel Veillard500a1de2004-03-22 15:22:58 +0000672 case XML_TEXTWRITER_DTD_TEXT:
673 case XML_TEXTWRITER_DTD_ELEM:
674 case XML_TEXTWRITER_DTD_ELEM_TEXT:
675 case XML_TEXTWRITER_DTD_ATTL:
676 case XML_TEXTWRITER_DTD_ATTL_TEXT:
677 case XML_TEXTWRITER_DTD_ENTY:
678 case XML_TEXTWRITER_DTD_ENTY_TEXT:
679 case XML_TEXTWRITER_DTD_PENT:
Daniel Veillard1d211e22003-10-20 22:32:39 +0000680 count = xmlTextWriterEndDTD(writer);
681 if (count < 0)
682 return -1;
683 sum += count;
684 break;
Daniel Veillardab69f362004-02-17 11:40:32 +0000685 case XML_TEXTWRITER_COMMENT:
686 count = xmlTextWriterEndComment(writer);
687 if (count < 0)
688 return -1;
689 sum += count;
690 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000691 default:
Daniel Veillardab69f362004-02-17 11:40:32 +0000692 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000693 }
694 }
695
Daniel Veillard2cca4462004-01-02 20:04:23 +0000696 if (!writer->indent) {
Daniel Veillardab69f362004-02-17 11:40:32 +0000697 count = xmlOutputBufferWriteString(writer->out, "\n");
698 if (count < 0)
699 return -1;
700 sum += count;
701 }
702 return sum;
703}
704
Daniel Veillardab69f362004-02-17 11:40:32 +0000705/**
706 * xmlTextWriterStartComment:
707 * @writer: the xmlTextWriterPtr
708 *
709 * Start an xml comment.
710 *
711 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
712 */
713int
714xmlTextWriterStartComment(xmlTextWriterPtr writer)
715{
716 int count;
717 int sum;
718 xmlLinkPtr lk;
719 xmlTextWriterStackEntry *p;
720
Daniel Veillard500a1de2004-03-22 15:22:58 +0000721 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000722 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000723 "xmlTextWriterStartComment : invalid writer!\n");
Daniel Veillardab69f362004-02-17 11:40:32 +0000724 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000725 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000726
727 sum = 0;
728 lk = xmlListFront(writer->nodes);
729 if (lk != 0) {
730 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
731 if (p != 0) {
732 switch (p->state) {
733 case XML_TEXTWRITER_TEXT:
734 case XML_TEXTWRITER_NONE:
735 break;
736 case XML_TEXTWRITER_NAME:
737 count = xmlOutputBufferWriteString(writer->out, ">");
738 if (count < 0)
739 return -1;
740 sum += count;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000741 if (writer->indent) {
742 count =
743 xmlOutputBufferWriteString(writer->out, "\n");
744 if (count < 0)
745 return -1;
746 sum += count;
747 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000748 p->state = XML_TEXTWRITER_TEXT;
749 break;
750 default:
751 return -1;
752 }
753 }
754 }
755
756 p = (xmlTextWriterStackEntry *)
757 xmlMalloc(sizeof(xmlTextWriterStackEntry));
758 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000759 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillardab69f362004-02-17 11:40:32 +0000760 "xmlTextWriterStartElement : out of memory!\n");
761 return -1;
762 }
763
Daniel Veillard75e389d2005-07-29 22:02:24 +0000764 p->name = NULL;
Daniel Veillardab69f362004-02-17 11:40:32 +0000765 p->state = XML_TEXTWRITER_COMMENT;
766
767 xmlListPushFront(writer->nodes, p);
768
769 if (writer->indent) {
Daniel Veillardab69f362004-02-17 11:40:32 +0000770 count = xmlTextWriterWriteIndent(writer);
771 if (count < 0)
772 return -1;
773 sum += count;
774 }
775
776 count = xmlOutputBufferWriteString(writer->out, "<!--");
777 if (count < 0)
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000778 return -1;
779 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +0000780
781 return sum;
782}
783
784/**
785 * xmlTextWriterEndComment:
786 * @writer: the xmlTextWriterPtr
787 *
788 * End the current xml coment.
789 *
790 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
791 */
792int
793xmlTextWriterEndComment(xmlTextWriterPtr writer)
794{
795 int count;
796 int sum;
797 xmlLinkPtr lk;
798 xmlTextWriterStackEntry *p;
799
Daniel Veillard500a1de2004-03-22 15:22:58 +0000800 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000801 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000802 "xmlTextWriterEndComment : invalid writer!\n");
Daniel Veillardab69f362004-02-17 11:40:32 +0000803 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000804 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000805
806 lk = xmlListFront(writer->nodes);
Daniel Veillard500a1de2004-03-22 15:22:58 +0000807 if (lk == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000808 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000809 "xmlTextWriterEndComment : not allowed in this context!\n");
Daniel Veillardab69f362004-02-17 11:40:32 +0000810 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000811 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000812
813 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
814 if (p == 0)
815 return -1;
816
817 sum = 0;
818 switch (p->state) {
819 case XML_TEXTWRITER_COMMENT:
820 count = xmlOutputBufferWriteString(writer->out, "-->");
821 if (count < 0)
822 return -1;
823 sum += count;
824 break;
825 default:
826 return -1;
Daniel Veillard2cca4462004-01-02 20:04:23 +0000827 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000828
829 if (writer->indent) {
830 count = xmlOutputBufferWriteString(writer->out, "\n");
831 if (count < 0)
832 return -1;
833 sum += count;
834 }
835
836 xmlListPopFront(writer->nodes);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000837 return sum;
838}
839
840/**
841 * xmlTextWriterWriteFormatComment:
842 * @writer: the xmlTextWriterPtr
843 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +0000844 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +0000845 *
846 * Write an xml comment.
847 *
848 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
849 */
Daniel Veillardffa3c742005-07-21 13:24:09 +0000850int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +0000851xmlTextWriterWriteFormatComment(xmlTextWriterPtr writer,
852 const char *format, ...)
853{
854 int rc;
855 va_list ap;
856
857 va_start(ap, format);
858
859 rc = xmlTextWriterWriteVFormatComment(writer, format, ap);
860
861 va_end(ap);
862 return rc;
863}
864
865/**
866 * xmlTextWriterWriteVFormatComment:
867 * @writer: the xmlTextWriterPtr
868 * @format: format string (see printf)
869 * @argptr: pointer to the first member of the variable argument list.
870 *
871 * Write an xml comment.
872 *
873 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
874 */
875int
876xmlTextWriterWriteVFormatComment(xmlTextWriterPtr writer,
877 const char *format, va_list argptr)
878{
879 int rc;
880 xmlChar *buf;
881
Daniel Veillard500a1de2004-03-22 15:22:58 +0000882 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000883 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000884 "xmlTextWriterWriteVFormatComment : invalid writer!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000885 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000886 }
Daniel Veillard1d211e22003-10-20 22:32:39 +0000887
888 buf = xmlTextWriterVSprintf(format, argptr);
889 if (buf == 0)
890 return 0;
891
892 rc = xmlTextWriterWriteComment(writer, buf);
893
894 xmlFree(buf);
895 return rc;
896}
897
898/**
899 * xmlTextWriterWriteComment:
900 * @writer: the xmlTextWriterPtr
901 * @content: comment string
902 *
903 * Write an xml comment.
904 *
905 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
906 */
907int
908xmlTextWriterWriteComment(xmlTextWriterPtr writer, const xmlChar * content)
909{
910 int count;
911 int sum;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000912
913 sum = 0;
Daniel Veillardab69f362004-02-17 11:40:32 +0000914 count = xmlTextWriterStartComment(writer);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000915 if (count < 0)
916 return -1;
917 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +0000918 count = xmlTextWriterWriteString(writer, content);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000919 if (count < 0)
920 return -1;
921 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +0000922 count = xmlTextWriterEndComment(writer);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000923 if (count < 0)
924 return -1;
925 sum += count;
926
927 return sum;
928}
929
930/**
931 * xmlTextWriterStartElement:
932 * @writer: the xmlTextWriterPtr
933 * @name: element name
934 *
935 * Start an xml element.
936 *
937 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
938 */
939int
940xmlTextWriterStartElement(xmlTextWriterPtr writer, const xmlChar * name)
941{
942 int count;
943 int sum;
944 xmlLinkPtr lk;
945 xmlTextWriterStackEntry *p;
946
947 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
948 return -1;
949
950 sum = 0;
951 lk = xmlListFront(writer->nodes);
952 if (lk != 0) {
953 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
954 if (p != 0) {
955 switch (p->state) {
956 case XML_TEXTWRITER_PI:
957 case XML_TEXTWRITER_PI_TEXT:
958 return -1;
959 case XML_TEXTWRITER_NONE:
960 break;
Daniel Veillard614fdc12005-02-23 14:05:37 +0000961 case XML_TEXTWRITER_ATTRIBUTE:
962 count = xmlTextWriterEndAttribute(writer);
963 if (count < 0)
964 return -1;
965 sum += count;
966 /* fallthrough */
Daniel Veillard1d211e22003-10-20 22:32:39 +0000967 case XML_TEXTWRITER_NAME:
968 count = xmlOutputBufferWriteString(writer->out, ">");
969 if (count < 0)
970 return -1;
971 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +0000972 if (writer->indent)
973 count =
974 xmlOutputBufferWriteString(writer->out, "\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000975 p->state = XML_TEXTWRITER_TEXT;
976 break;
Daniel Veillardab69f362004-02-17 11:40:32 +0000977 default:
978 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000979 }
980 }
981 }
982
983 p = (xmlTextWriterStackEntry *)
984 xmlMalloc(sizeof(xmlTextWriterStackEntry));
985 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000986 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000987 "xmlTextWriterStartElement : out of memory!\n");
988 return -1;
989 }
990
991 p->name = xmlStrdup(name);
992 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000993 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000994 "xmlTextWriterStartElement : out of memory!\n");
995 xmlFree(p);
996 return -1;
997 }
998 p->state = XML_TEXTWRITER_NAME;
999
1000 xmlListPushFront(writer->nodes, p);
1001
Daniel Veillardab69f362004-02-17 11:40:32 +00001002 if (writer->indent) {
1003 count = xmlTextWriterWriteIndent(writer);
1004 sum += count;
Daniel Veillard2cca4462004-01-02 20:04:23 +00001005 }
1006
Daniel Veillard1d211e22003-10-20 22:32:39 +00001007 count = xmlOutputBufferWriteString(writer->out, "<");
1008 if (count < 0)
1009 return -1;
1010 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00001011 count =
1012 xmlOutputBufferWriteString(writer->out, (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001013 if (count < 0)
1014 return -1;
1015 sum += count;
1016
1017 return sum;
1018}
1019
1020/**
1021 * xmlTextWriterStartElementNS:
1022 * @writer: the xmlTextWriterPtr
1023 * @prefix: namespace prefix or NULL
1024 * @name: element local name
1025 * @namespaceURI: namespace URI or NULL
1026 *
1027 * Start an xml element with namespace support.
1028 *
1029 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1030 */
1031int
1032xmlTextWriterStartElementNS(xmlTextWriterPtr writer,
1033 const xmlChar * prefix, const xmlChar * name,
1034 const xmlChar * namespaceURI)
1035{
1036 int count;
1037 int sum;
1038 xmlChar *buf;
1039
1040 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1041 return -1;
1042
Daniel Veillard75e389d2005-07-29 22:02:24 +00001043 buf = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001044 if (prefix != 0) {
1045 buf = xmlStrdup(prefix);
1046 buf = xmlStrcat(buf, BAD_CAST ":");
1047 }
1048 buf = xmlStrcat(buf, name);
1049
1050 sum = 0;
1051 count = xmlTextWriterStartElement(writer, buf);
1052 xmlFree(buf);
1053 if (count < 0)
1054 return -1;
1055 sum += count;
1056
1057 if (namespaceURI != 0) {
1058 buf = xmlStrdup(BAD_CAST "xmlns");
1059 if (prefix != 0) {
1060 buf = xmlStrcat(buf, BAD_CAST ":");
1061 buf = xmlStrcat(buf, prefix);
1062 }
1063
1064 count = xmlTextWriterWriteAttribute(writer, buf, namespaceURI);
1065 xmlFree(buf);
1066 if (count < 0)
1067 return -1;
1068 sum += count;
1069 }
1070
1071 return sum;
1072}
1073
1074/**
1075 * xmlTextWriterEndElement:
1076 * @writer: the xmlTextWriterPtr
1077 *
1078 * End the current xml element.
1079 *
1080 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1081 */
1082int
1083xmlTextWriterEndElement(xmlTextWriterPtr writer)
1084{
1085 int count;
1086 int sum;
1087 xmlLinkPtr lk;
1088 xmlTextWriterStackEntry *p;
1089
1090 if (writer == NULL)
1091 return -1;
1092
1093 lk = xmlListFront(writer->nodes);
1094 if (lk == 0)
1095 return -1;
1096
1097 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1098 if (p == 0)
1099 return -1;
1100
1101 sum = 0;
1102 switch (p->state) {
1103 case XML_TEXTWRITER_ATTRIBUTE:
1104 count = xmlTextWriterEndAttribute(writer);
1105 if (count < 0)
1106 return -1;
1107 sum += count;
1108 /* fallthrough */
1109 case XML_TEXTWRITER_NAME:
Daniel Veillardab69f362004-02-17 11:40:32 +00001110 if (writer->indent) /* next element needs indent */
1111 writer->doindent = 1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001112 count = xmlOutputBufferWriteString(writer->out, "/>");
1113 if (count < 0)
1114 return -1;
1115 sum += count;
1116 break;
1117 case XML_TEXTWRITER_TEXT:
Daniel Veillardab69f362004-02-17 11:40:32 +00001118 if ((writer->indent) && (writer->doindent)) {
1119 count = xmlTextWriterWriteIndent(writer);
1120 sum += count;
1121 writer->doindent = 1;
1122 } else
1123 writer->doindent = 1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001124 count = xmlOutputBufferWriteString(writer->out, "</");
1125 if (count < 0)
1126 return -1;
1127 sum += count;
1128 count = xmlOutputBufferWriteString(writer->out,
Daniel Veillardab69f362004-02-17 11:40:32 +00001129 (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001130 if (count < 0)
1131 return -1;
1132 sum += count;
1133 count = xmlOutputBufferWriteString(writer->out, ">");
1134 if (count < 0)
1135 return -1;
1136 sum += count;
1137 break;
1138 default:
1139 return -1;
1140 }
1141
Daniel Veillard2cca4462004-01-02 20:04:23 +00001142 if (writer->indent) {
Daniel Veillardab69f362004-02-17 11:40:32 +00001143 count = xmlOutputBufferWriteString(writer->out, "\n");
1144 sum += count;
Daniel Veillard2cca4462004-01-02 20:04:23 +00001145 }
1146
Daniel Veillard1d211e22003-10-20 22:32:39 +00001147 xmlListPopFront(writer->nodes);
1148 return sum;
1149}
1150
1151/**
1152 * xmlTextWriterFullEndElement:
1153 * @writer: the xmlTextWriterPtr
1154 *
1155 * End the current xml element. Writes an end tag even if the element is empty
1156 *
1157 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1158 */
1159int
1160xmlTextWriterFullEndElement(xmlTextWriterPtr writer)
1161{
1162 int count;
1163 int sum;
1164 xmlLinkPtr lk;
1165 xmlTextWriterStackEntry *p;
1166
1167 if (writer == NULL)
1168 return -1;
1169
1170 lk = xmlListFront(writer->nodes);
1171 if (lk == 0)
1172 return -1;
1173
1174 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1175 if (p == 0)
1176 return -1;
1177
1178 sum = 0;
1179 switch (p->state) {
1180 case XML_TEXTWRITER_ATTRIBUTE:
1181 count = xmlTextWriterEndAttribute(writer);
1182 if (count < 0)
1183 return -1;
1184 sum += count;
1185 /* fallthrough */
1186 case XML_TEXTWRITER_NAME:
1187 count = xmlOutputBufferWriteString(writer->out, ">");
1188 if (count < 0)
1189 return -1;
1190 sum += count;
1191 /* fallthrough */
1192 case XML_TEXTWRITER_TEXT:
1193 count = xmlOutputBufferWriteString(writer->out, "</");
1194 if (count < 0)
1195 return -1;
1196 sum += count;
1197 count = xmlOutputBufferWriteString(writer->out,
Daniel Veillardab69f362004-02-17 11:40:32 +00001198 (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001199 if (count < 0)
1200 return -1;
1201 sum += count;
1202 count = xmlOutputBufferWriteString(writer->out, ">");
1203 if (count < 0)
1204 return -1;
1205 sum += count;
1206 break;
1207 default:
1208 return -1;
1209 }
1210
1211 xmlListPopFront(writer->nodes);
1212 return sum;
1213}
1214
1215/**
1216 * xmlTextWriterWriteFormatRaw:
1217 * @writer: the xmlTextWriterPtr
1218 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001219 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001220 *
1221 * Write a formatted raw xml text.
1222 *
1223 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1224 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00001225int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00001226xmlTextWriterWriteFormatRaw(xmlTextWriterPtr writer, const char *format,
1227 ...)
1228{
1229 int rc;
1230 va_list ap;
1231
1232 va_start(ap, format);
1233
1234 rc = xmlTextWriterWriteVFormatRaw(writer, format, ap);
1235
1236 va_end(ap);
1237 return rc;
1238}
1239
1240/**
1241 * xmlTextWriterWriteVFormatRaw:
1242 * @writer: the xmlTextWriterPtr
1243 * @format: format string (see printf)
1244 * @argptr: pointer to the first member of the variable argument list.
1245 *
1246 * Write a formatted raw xml text.
1247 *
1248 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1249 */
1250int
1251xmlTextWriterWriteVFormatRaw(xmlTextWriterPtr writer, const char *format,
1252 va_list argptr)
1253{
1254 int rc;
1255 xmlChar *buf;
1256
1257 if (writer == NULL)
1258 return -1;
1259
1260 buf = xmlTextWriterVSprintf(format, argptr);
1261 if (buf == 0)
1262 return 0;
1263
1264 rc = xmlTextWriterWriteRaw(writer, buf);
1265
1266 xmlFree(buf);
1267 return rc;
1268}
1269
1270/**
Daniel Veillard1e906612003-12-05 14:57:46 +00001271 * xmlTextWriterWriteRawLen:
Daniel Veillard1d211e22003-10-20 22:32:39 +00001272 * @writer: the xmlTextWriterPtr
1273 * @content: text string
1274 * @len: length of the text string
1275 *
1276 * Write an xml text.
1277 * TODO: what about entities and special chars??
1278 *
1279 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1280 */
1281int
1282xmlTextWriterWriteRawLen(xmlTextWriterPtr writer, const xmlChar * content,
1283 int len)
1284{
1285 int count;
1286 int sum;
1287 xmlLinkPtr lk;
1288 xmlTextWriterStackEntry *p;
1289
Daniel Veillard500a1de2004-03-22 15:22:58 +00001290 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00001291 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00001292 "xmlTextWriterWriteRawLen : invalid writer!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +00001293 return -1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001294 }
1295
Daniel Veillarde43cc572004-11-03 11:50:29 +00001296 if ((content == NULL) || (len < 0)) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00001297 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00001298 "xmlTextWriterWriteRawLen : invalid content!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +00001299 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001300 }
1301
1302 sum = 0;
1303 lk = xmlListFront(writer->nodes);
1304 if (lk != 0) {
1305 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1306 count = xmlTextWriterHandleStateDependencies(writer, p);
1307 if (count < 0)
1308 return -1;
1309 sum += count;
1310 }
1311
1312 if (writer->indent)
1313 writer->doindent = 0;
1314
1315 if (content != NULL) {
1316 count =
1317 xmlOutputBufferWrite(writer->out, len, (const char *) content);
1318 if (count < 0)
1319 return -1;
1320 sum += count;
1321 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001322
1323 return sum;
1324}
1325
1326/**
1327 * xmlTextWriterWriteRaw:
1328 * @writer: the xmlTextWriterPtr
1329 * @content: text string
1330 *
1331 * Write a raw xml text.
1332 *
1333 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1334 */
1335int
1336xmlTextWriterWriteRaw(xmlTextWriterPtr writer, const xmlChar * content)
1337{
1338 return xmlTextWriterWriteRawLen(writer, content, xmlStrlen(content));
1339}
1340
1341/**
1342 * xmlTextWriterWriteFormatString:
1343 * @writer: the xmlTextWriterPtr
1344 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001345 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001346 *
1347 * Write a formatted xml text.
1348 *
1349 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1350 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00001351int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00001352xmlTextWriterWriteFormatString(xmlTextWriterPtr writer, const char *format,
1353 ...)
1354{
1355 int rc;
1356 va_list ap;
1357
Daniel Veillarde43cc572004-11-03 11:50:29 +00001358 if ((writer == NULL) || (format == NULL))
1359 return -1;
1360
Daniel Veillard1d211e22003-10-20 22:32:39 +00001361 va_start(ap, format);
1362
1363 rc = xmlTextWriterWriteVFormatString(writer, format, ap);
1364
1365 va_end(ap);
1366 return rc;
1367}
1368
1369/**
1370 * xmlTextWriterWriteVFormatString:
1371 * @writer: the xmlTextWriterPtr
1372 * @format: format string (see printf)
1373 * @argptr: pointer to the first member of the variable argument list.
1374 *
1375 * Write a formatted xml text.
1376 *
1377 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1378 */
1379int
1380xmlTextWriterWriteVFormatString(xmlTextWriterPtr writer,
1381 const char *format, va_list argptr)
1382{
1383 int rc;
1384 xmlChar *buf;
1385
Daniel Veillarde43cc572004-11-03 11:50:29 +00001386 if ((writer == NULL) || (format == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00001387 return -1;
1388
1389 buf = xmlTextWriterVSprintf(format, argptr);
1390 if (buf == 0)
1391 return 0;
1392
1393 rc = xmlTextWriterWriteString(writer, buf);
1394
1395 xmlFree(buf);
1396 return rc;
1397}
1398
1399/**
1400 * xmlTextWriterWriteString:
1401 * @writer: the xmlTextWriterPtr
1402 * @content: text string
1403 *
1404 * Write an xml text.
1405 *
1406 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1407 */
1408int
1409xmlTextWriterWriteString(xmlTextWriterPtr writer, const xmlChar * content)
1410{
Daniel Veillard500a1de2004-03-22 15:22:58 +00001411 int count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001412 int sum;
1413 xmlLinkPtr lk;
1414 xmlTextWriterStackEntry *p;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001415 xmlChar *buf;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001416
Daniel Veillarde43cc572004-11-03 11:50:29 +00001417 if ((writer == NULL) || (content == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00001418 return -1;
1419
Daniel Veillard1d211e22003-10-20 22:32:39 +00001420 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001421 buf = (xmlChar *) content;
1422 lk = xmlListFront(writer->nodes);
1423 if (lk != 0) {
1424 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1425 if (p != 0) {
1426 switch (p->state) {
1427 case XML_TEXTWRITER_NAME:
1428 case XML_TEXTWRITER_TEXT:
Daniel Veillard62040be2004-05-17 03:17:26 +00001429#if 0
1430 buf = NULL;
1431 xmlOutputBufferWriteEscape(writer->out, content, NULL);
1432#endif
Daniel Veillard500a1de2004-03-22 15:22:58 +00001433 buf = xmlEncodeSpecialChars(NULL, content);
1434 break;
1435 case XML_TEXTWRITER_ATTRIBUTE:
1436 buf = NULL;
Rob Richards9db68f02006-08-16 22:48:51 +00001437 xmlAttrSerializeTxtContent(writer->out->buffer, writer->doc,
Daniel Veillard500a1de2004-03-22 15:22:58 +00001438 NULL, content);
1439 break;
William M. Brack87640d52004-04-17 14:58:15 +00001440 default:
1441 break;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001442 }
1443 }
1444 }
1445
1446 if (buf != NULL) {
1447 count = xmlTextWriterWriteRaw(writer, buf);
1448 if (count < 0)
Daniel Veillard1d211e22003-10-20 22:32:39 +00001449 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001450 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001451
Daniel Veillard500a1de2004-03-22 15:22:58 +00001452 if (buf != content) /* buf was allocated by us, so free it */
1453 xmlFree(buf);
William M. Bracka9c612c2004-02-01 10:04:05 +00001454 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001455
1456 return sum;
1457}
1458
1459/**
1460 * xmlOutputBufferWriteBase64:
1461 * @out: the xmlOutputBufferPtr
1462 * @data: binary data
1463 * @len: the number of bytes to encode
1464 *
1465 * Write base64 encoded data to an xmlOutputBuffer.
1466 * Adapted from John Walker's base64.c (http://www.fourmilab.ch/).
1467 *
1468 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1469 */
1470static int
1471xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len,
1472 const unsigned char *data)
1473{
1474 static unsigned char dtable[64] =
William M. Brack47a31882004-09-11 16:09:09 +00001475 {'A','B','C','D','E','F','G','H','I','J','K','L','M',
1476 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
1477 'a','b','c','d','e','f','g','h','i','j','k','l','m',
1478 'n','o','p','q','r','s','t','u','v','w','x','y','z',
1479 '0','1','2','3','4','5','6','7','8','9','+','/'};
1480
Daniel Veillard1d211e22003-10-20 22:32:39 +00001481 int i;
1482 int linelen;
1483 int count;
1484 int sum;
1485
Daniel Veillarde43cc572004-11-03 11:50:29 +00001486 if ((out == NULL) || (len < 0) || (data == NULL))
1487 return(-1);
1488
Daniel Veillard1d211e22003-10-20 22:32:39 +00001489 linelen = 0;
1490 sum = 0;
1491
1492 i = 0;
1493 while (1) {
1494 unsigned char igroup[3];
1495 unsigned char ogroup[4];
1496 int c;
1497 int n;
1498
1499 igroup[0] = igroup[1] = igroup[2] = 0;
1500 for (n = 0; n < 3 && i < len; n++, i++) {
1501 c = data[i];
1502 igroup[n] = (unsigned char) c;
1503 }
1504
1505 if (n > 0) {
1506 ogroup[0] = dtable[igroup[0] >> 2];
1507 ogroup[1] = dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)];
1508 ogroup[2] =
1509 dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)];
1510 ogroup[3] = dtable[igroup[2] & 0x3F];
1511
1512 if (n < 3) {
1513 ogroup[3] = '=';
1514 if (n < 2) {
1515 ogroup[2] = '=';
1516 }
1517 }
1518
1519 if (linelen >= B64LINELEN) {
1520 count = xmlOutputBufferWrite(out, 2, B64CRLF);
1521 if (count == -1)
1522 return -1;
1523 sum += count;
1524 linelen = 0;
1525 }
1526 count = xmlOutputBufferWrite(out, 4, (const char *) ogroup);
1527 if (count == -1)
1528 return -1;
1529 sum += count;
1530
1531 linelen += 4;
1532 }
Daniel Veillard929714b2003-10-22 12:34:36 +00001533
1534 if (i >= len)
1535 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001536 }
1537
Daniel Veillard1d211e22003-10-20 22:32:39 +00001538 return sum;
1539}
1540
1541/**
1542 * xmlTextWriterWriteBase64:
1543 * @writer: the xmlTextWriterPtr
1544 * @data: binary data
1545 * @start: the position within the data of the first byte to encode
1546 * @len: the number of bytes to encode
1547 *
1548 * Write an base64 encoded xml text.
1549 *
1550 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1551 */
1552int
Daniel Veillardab69f362004-02-17 11:40:32 +00001553xmlTextWriterWriteBase64(xmlTextWriterPtr writer, const char *data,
Daniel Veillard1d211e22003-10-20 22:32:39 +00001554 int start, int len)
1555{
1556 int count;
1557 int sum;
1558 xmlLinkPtr lk;
1559 xmlTextWriterStackEntry *p;
1560
Daniel Veillarde43cc572004-11-03 11:50:29 +00001561 if ((writer == NULL) || (data == NULL) || (start < 0) || (len < 0))
Daniel Veillard1d211e22003-10-20 22:32:39 +00001562 return -1;
1563
Daniel Veillard1d211e22003-10-20 22:32:39 +00001564 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001565 lk = xmlListFront(writer->nodes);
1566 if (lk != 0) {
1567 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1568 if (p != 0) {
1569 count = xmlTextWriterHandleStateDependencies(writer, p);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001570 if (count < 0)
1571 return -1;
1572 sum += count;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001573 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001574 }
1575
Daniel Veillardab69f362004-02-17 11:40:32 +00001576 if (writer->indent)
1577 writer->doindent = 0;
1578
Daniel Veillard1d211e22003-10-20 22:32:39 +00001579 count =
1580 xmlOutputBufferWriteBase64(writer->out, len,
1581 (unsigned char *) data + start);
1582 if (count < 0)
1583 return -1;
1584 sum += count;
1585
1586 return sum;
1587}
1588
1589/**
1590 * xmlOutputBufferWriteBinHex:
1591 * @out: the xmlOutputBufferPtr
1592 * @data: binary data
1593 * @len: the number of bytes to encode
1594 *
1595 * Write hqx encoded data to an xmlOutputBuffer.
1596 * ::todo
1597 *
William M. Brack47a31882004-09-11 16:09:09 +00001598 * Returns the bytes written (may be 0 because of buffering)
1599 * or -1 in case of error
Daniel Veillard1d211e22003-10-20 22:32:39 +00001600 */
1601static int
Daniel Veillardab69f362004-02-17 11:40:32 +00001602xmlOutputBufferWriteBinHex(xmlOutputBufferPtr out,
1603 int len, const unsigned char *data)
Daniel Veillard1d211e22003-10-20 22:32:39 +00001604{
Daniel Veillardab69f362004-02-17 11:40:32 +00001605 int count;
1606 int sum;
William M. Brack47a31882004-09-11 16:09:09 +00001607 static char hex[16] =
1608 {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
Daniel Veillardab69f362004-02-17 11:40:32 +00001609 int i;
1610
Daniel Veillarde43cc572004-11-03 11:50:29 +00001611 if ((out == NULL) || (data == NULL) || (len < 0)) {
Daniel Veillardab69f362004-02-17 11:40:32 +00001612 return -1;
1613 }
1614
1615 sum = 0;
1616 for (i = 0; i < len; i++) {
1617 count =
1618 xmlOutputBufferWrite(out, 1,
1619 (const char *) &hex[data[i] >> 4]);
1620 if (count == -1)
1621 return -1;
1622 sum += count;
1623 count =
1624 xmlOutputBufferWrite(out, 1,
1625 (const char *) &hex[data[i] & 0xF]);
1626 if (count == -1)
1627 return -1;
1628 sum += count;
1629 }
1630
1631 return sum;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001632}
1633
1634/**
1635 * xmlTextWriterWriteBinHex:
1636 * @writer: the xmlTextWriterPtr
1637 * @data: binary data
1638 * @start: the position within the data of the first byte to encode
1639 * @len: the number of bytes to encode
1640 *
1641 * Write a BinHex encoded xml text.
1642 *
1643 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1644 */
1645int
Daniel Veillardab69f362004-02-17 11:40:32 +00001646xmlTextWriterWriteBinHex(xmlTextWriterPtr writer, const char *data,
Daniel Veillard1d211e22003-10-20 22:32:39 +00001647 int start, int len)
1648{
1649 int count;
1650 int sum;
1651 xmlLinkPtr lk;
1652 xmlTextWriterStackEntry *p;
1653
Daniel Veillarde43cc572004-11-03 11:50:29 +00001654 if ((writer == NULL) || (data == NULL) || (start < 0) || (len < 0))
Daniel Veillard1d211e22003-10-20 22:32:39 +00001655 return -1;
1656
Daniel Veillard1d211e22003-10-20 22:32:39 +00001657 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001658 lk = xmlListFront(writer->nodes);
1659 if (lk != 0) {
1660 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1661 if (p != 0) {
1662 count = xmlTextWriterHandleStateDependencies(writer, p);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001663 if (count < 0)
1664 return -1;
1665 sum += count;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001666 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001667 }
1668
Daniel Veillardab69f362004-02-17 11:40:32 +00001669 if (writer->indent)
1670 writer->doindent = 0;
1671
Daniel Veillard1d211e22003-10-20 22:32:39 +00001672 count =
1673 xmlOutputBufferWriteBinHex(writer->out, len,
1674 (unsigned char *) data + start);
1675 if (count < 0)
1676 return -1;
1677 sum += count;
1678
1679 return sum;
1680}
1681
1682/**
1683 * xmlTextWriterStartAttribute:
1684 * @writer: the xmlTextWriterPtr
1685 * @name: element name
1686 *
1687 * Start an xml attribute.
1688 *
1689 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1690 */
1691int
1692xmlTextWriterStartAttribute(xmlTextWriterPtr writer, const xmlChar * name)
1693{
1694 int count;
1695 int sum;
1696 xmlLinkPtr lk;
1697 xmlTextWriterStackEntry *p;
1698
1699 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1700 return -1;
1701
1702 sum = 0;
1703 lk = xmlListFront(writer->nodes);
1704 if (lk == 0)
1705 return -1;
1706
1707 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1708 if (p == 0)
1709 return -1;
1710
1711 switch (p->state) {
1712 case XML_TEXTWRITER_ATTRIBUTE:
1713 count = xmlTextWriterEndAttribute(writer);
1714 if (count < 0)
1715 return -1;
1716 sum += count;
1717 /* fallthrough */
1718 case XML_TEXTWRITER_NAME:
1719 count = xmlOutputBufferWriteString(writer->out, " ");
1720 if (count < 0)
1721 return -1;
1722 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00001723 count =
1724 xmlOutputBufferWriteString(writer->out,
1725 (const char *) name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001726 if (count < 0)
1727 return -1;
1728 sum += count;
1729 count = xmlOutputBufferWriteString(writer->out, "=");
1730 if (count < 0)
1731 return -1;
1732 sum += count;
1733 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
1734 if (count < 0)
1735 return -1;
1736 sum += count;
1737 p->state = XML_TEXTWRITER_ATTRIBUTE;
1738 break;
1739 default:
1740 return -1;
1741 }
1742
1743 return sum;
1744}
1745
1746/**
1747 * xmlTextWriterStartAttributeNS:
1748 * @writer: the xmlTextWriterPtr
1749 * @prefix: namespace prefix or NULL
1750 * @name: element local name
1751 * @namespaceURI: namespace URI or NULL
1752 *
1753 * Start an xml attribute with namespace support.
1754 *
1755 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1756 */
1757int
1758xmlTextWriterStartAttributeNS(xmlTextWriterPtr writer,
1759 const xmlChar * prefix, const xmlChar * name,
1760 const xmlChar * namespaceURI)
1761{
1762 int count;
1763 int sum;
1764 xmlChar *buf;
1765 xmlTextWriterNsStackEntry *p;
1766
1767 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1768 return -1;
1769
Daniel Veillard75e389d2005-07-29 22:02:24 +00001770 buf = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001771 if (prefix != 0) {
1772 buf = xmlStrdup(prefix);
1773 buf = xmlStrcat(buf, BAD_CAST ":");
1774 }
1775 buf = xmlStrcat(buf, name);
1776
1777 sum = 0;
1778 count = xmlTextWriterStartAttribute(writer, buf);
1779 xmlFree(buf);
1780 if (count < 0)
1781 return -1;
1782 sum += count;
1783
1784 if (namespaceURI != 0) {
1785 buf = xmlStrdup(BAD_CAST "xmlns");
1786 if (prefix != 0) {
1787 buf = xmlStrcat(buf, BAD_CAST ":");
1788 buf = xmlStrcat(buf, prefix);
1789 }
1790
1791 p = (xmlTextWriterNsStackEntry *)
1792 xmlMalloc(sizeof(xmlTextWriterNsStackEntry));
1793 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00001794 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00001795 "xmlTextWriterStartAttributeNS : out of memory!\n");
1796 return -1;
1797 }
1798
1799 p->prefix = buf;
1800 p->uri = xmlStrdup(namespaceURI);
1801 if (p->uri == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00001802 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00001803 "xmlTextWriterStartAttributeNS : out of memory!\n");
1804 xmlFree(p);
1805 return -1;
1806 }
1807 p->elem = xmlListFront(writer->nodes);
1808
1809 xmlListPushFront(writer->nsstack, p);
1810 }
1811
1812 return sum;
1813}
1814
1815/**
1816 * xmlTextWriterEndAttribute:
1817 * @writer: the xmlTextWriterPtr
1818 *
1819 * End the current xml element.
1820 *
1821 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1822 */
1823int
1824xmlTextWriterEndAttribute(xmlTextWriterPtr writer)
1825{
1826 int count;
1827 int sum;
1828 xmlLinkPtr lk;
1829 xmlTextWriterStackEntry *p;
1830 xmlTextWriterNsStackEntry *np;
1831
1832 if (writer == NULL)
1833 return -1;
1834
1835 lk = xmlListFront(writer->nodes);
1836 if (lk == 0) {
1837 xmlListDelete(writer->nsstack);
Daniel Veillarde43cc572004-11-03 11:50:29 +00001838 writer->nsstack = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001839 return -1;
1840 }
1841
1842 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1843 if (p == 0) {
1844 xmlListDelete(writer->nsstack);
Daniel Veillarde43cc572004-11-03 11:50:29 +00001845 writer->nsstack = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001846 return -1;
1847 }
1848
1849 sum = 0;
1850 switch (p->state) {
1851 case XML_TEXTWRITER_ATTRIBUTE:
1852 p->state = XML_TEXTWRITER_NAME;
1853
1854 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
1855 if (count < 0) {
1856 xmlListDelete(writer->nsstack);
Daniel Veillarde43cc572004-11-03 11:50:29 +00001857 writer->nsstack = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001858 return -1;
1859 }
1860 sum += count;
1861
1862 while (!xmlListEmpty(writer->nsstack)) {
Daniel Veillardbd8fb0a2005-02-21 13:49:46 +00001863 xmlChar *namespaceURI = NULL;
1864 xmlChar *prefix = NULL;
1865
Daniel Veillard1d211e22003-10-20 22:32:39 +00001866 lk = xmlListFront(writer->nsstack);
1867 np = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
Daniel Veillardbd8fb0a2005-02-21 13:49:46 +00001868
1869 if (np != 0) {
Daniel Veillard614fdc12005-02-23 14:05:37 +00001870 namespaceURI = xmlStrdup(np->uri);
1871 prefix = xmlStrdup(np->prefix);
Daniel Veillardbd8fb0a2005-02-21 13:49:46 +00001872 }
1873
1874 xmlListPopFront(writer->nsstack);
1875
Daniel Veillard1d211e22003-10-20 22:32:39 +00001876 if (np != 0) {
1877 count =
Daniel Veillardbd8fb0a2005-02-21 13:49:46 +00001878 xmlTextWriterWriteAttribute(writer, prefix,
1879 namespaceURI);
1880 xmlFree(namespaceURI);
1881 xmlFree(prefix);
1882
Daniel Veillard1d211e22003-10-20 22:32:39 +00001883 if (count < 0) {
1884 xmlListDelete(writer->nsstack);
Daniel Veillarde43cc572004-11-03 11:50:29 +00001885 writer->nsstack = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001886 return -1;
1887 }
1888 sum += count;
1889 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001890 }
1891 break;
1892
1893 default:
1894 xmlListClear(writer->nsstack);
1895 return -1;
1896 }
1897
1898 return sum;
1899}
1900
1901/**
1902 * xmlTextWriterWriteFormatAttribute:
1903 * @writer: the xmlTextWriterPtr
1904 * @name: attribute name
1905 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001906 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001907 *
1908 * Write a formatted xml attribute.
1909 *
1910 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1911 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00001912int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00001913xmlTextWriterWriteFormatAttribute(xmlTextWriterPtr writer,
1914 const xmlChar * name, const char *format,
1915 ...)
1916{
1917 int rc;
1918 va_list ap;
1919
1920 va_start(ap, format);
1921
1922 rc = xmlTextWriterWriteVFormatAttribute(writer, name, format, ap);
1923
1924 va_end(ap);
1925 return rc;
1926}
1927
1928/**
1929 * xmlTextWriterWriteVFormatAttribute:
1930 * @writer: the xmlTextWriterPtr
1931 * @name: attribute name
1932 * @format: format string (see printf)
1933 * @argptr: pointer to the first member of the variable argument list.
1934 *
1935 * Write a formatted xml attribute.
1936 *
1937 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1938 */
1939int
1940xmlTextWriterWriteVFormatAttribute(xmlTextWriterPtr writer,
1941 const xmlChar * name,
1942 const char *format, va_list argptr)
1943{
1944 int rc;
1945 xmlChar *buf;
1946
1947 if (writer == NULL)
1948 return -1;
1949
1950 buf = xmlTextWriterVSprintf(format, argptr);
1951 if (buf == 0)
1952 return 0;
1953
1954 rc = xmlTextWriterWriteAttribute(writer, name, buf);
1955
1956 xmlFree(buf);
1957 return rc;
1958}
1959
1960/**
1961 * xmlTextWriterWriteAttribute:
1962 * @writer: the xmlTextWriterPtr
1963 * @name: attribute name
1964 * @content: attribute content
1965 *
1966 * Write an xml attribute.
1967 *
1968 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1969 */
1970int
1971xmlTextWriterWriteAttribute(xmlTextWriterPtr writer, const xmlChar * name,
1972 const xmlChar * content)
1973{
1974 int count;
1975 int sum;
1976
1977 sum = 0;
1978 count = xmlTextWriterStartAttribute(writer, name);
1979 if (count < 0)
1980 return -1;
1981 sum += count;
1982 count = xmlTextWriterWriteString(writer, content);
1983 if (count < 0)
1984 return -1;
1985 sum += count;
1986 count = xmlTextWriterEndAttribute(writer);
1987 if (count < 0)
1988 return -1;
1989 sum += count;
1990
1991 return sum;
1992}
1993
1994/**
1995 * xmlTextWriterWriteFormatAttributeNS:
1996 * @writer: the xmlTextWriterPtr
1997 * @prefix: namespace prefix
1998 * @name: attribute local name
1999 * @namespaceURI: namespace URI
2000 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002001 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002002 *
2003 * Write a formatted xml attribute.with namespace support
2004 *
2005 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2006 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00002007int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00002008xmlTextWriterWriteFormatAttributeNS(xmlTextWriterPtr writer,
2009 const xmlChar * prefix,
2010 const xmlChar * name,
2011 const xmlChar * namespaceURI,
2012 const char *format, ...)
2013{
2014 int rc;
2015 va_list ap;
2016
2017 va_start(ap, format);
2018
2019 rc = xmlTextWriterWriteVFormatAttributeNS(writer, prefix, name,
2020 namespaceURI, format, ap);
2021
2022 va_end(ap);
2023 return rc;
2024}
2025
2026/**
2027 * xmlTextWriterWriteVFormatAttributeNS:
2028 * @writer: the xmlTextWriterPtr
2029 * @prefix: namespace prefix
2030 * @name: attribute local name
2031 * @namespaceURI: namespace URI
2032 * @format: format string (see printf)
2033 * @argptr: pointer to the first member of the variable argument list.
2034 *
2035 * Write a formatted xml attribute.with namespace support
2036 *
2037 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2038 */
2039int
2040xmlTextWriterWriteVFormatAttributeNS(xmlTextWriterPtr writer,
2041 const xmlChar * prefix,
2042 const xmlChar * name,
2043 const xmlChar * namespaceURI,
2044 const char *format, va_list argptr)
2045{
2046 int rc;
2047 xmlChar *buf;
2048
2049 if (writer == NULL)
2050 return -1;
2051
2052 buf = xmlTextWriterVSprintf(format, argptr);
2053 if (buf == 0)
2054 return 0;
2055
2056 rc = xmlTextWriterWriteAttributeNS(writer, prefix, name, namespaceURI,
2057 buf);
2058
2059 xmlFree(buf);
2060 return rc;
2061}
2062
2063/**
2064 * xmlTextWriterWriteAttributeNS:
2065 * @writer: the xmlTextWriterPtr
2066 * @prefix: namespace prefix
2067 * @name: attribute local name
2068 * @namespaceURI: namespace URI
2069 * @content: attribute content
2070 *
2071 * Write an xml attribute.
2072 *
2073 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2074 */
2075int
2076xmlTextWriterWriteAttributeNS(xmlTextWriterPtr writer,
2077 const xmlChar * prefix, const xmlChar * name,
2078 const xmlChar * namespaceURI,
2079 const xmlChar * content)
2080{
2081 int count;
2082 int sum;
2083 xmlChar *buf;
2084
2085 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
2086 return -1;
2087
Daniel Veillard75e389d2005-07-29 22:02:24 +00002088 buf = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002089 if (prefix != NULL) {
2090 buf = xmlStrdup(prefix);
2091 buf = xmlStrcat(buf, BAD_CAST ":");
2092 }
2093 buf = xmlStrcat(buf, name);
2094
2095 sum = 0;
2096 count = xmlTextWriterWriteAttribute(writer, buf, content);
2097 xmlFree(buf);
2098 if (count < 0)
2099 return -1;
2100 sum += count;
2101
2102 if (namespaceURI != NULL) {
Daniel Veillard75e389d2005-07-29 22:02:24 +00002103 buf = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002104 buf = xmlStrdup(BAD_CAST "xmlns");
2105 if (prefix != NULL) {
2106 buf = xmlStrcat(buf, BAD_CAST ":");
2107 buf = xmlStrcat(buf, prefix);
2108 }
2109 count = xmlTextWriterWriteAttribute(writer, buf, namespaceURI);
2110 xmlFree(buf);
2111 if (count < 0)
2112 return -1;
2113 sum += count;
2114 }
2115 return sum;
2116}
2117
2118/**
2119 * xmlTextWriterWriteFormatElement:
2120 * @writer: the xmlTextWriterPtr
2121 * @name: element name
2122 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002123 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002124 *
2125 * Write a formatted xml element.
2126 *
2127 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2128 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00002129int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00002130xmlTextWriterWriteFormatElement(xmlTextWriterPtr writer,
2131 const xmlChar * name, const char *format,
2132 ...)
2133{
2134 int rc;
2135 va_list ap;
2136
2137 va_start(ap, format);
2138
2139 rc = xmlTextWriterWriteVFormatElement(writer, name, format, ap);
2140
2141 va_end(ap);
2142 return rc;
2143}
2144
2145/**
2146 * xmlTextWriterWriteVFormatElement:
2147 * @writer: the xmlTextWriterPtr
2148 * @name: element name
2149 * @format: format string (see printf)
2150 * @argptr: pointer to the first member of the variable argument list.
2151 *
2152 * Write a formatted xml element.
2153 *
2154 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2155 */
2156int
2157xmlTextWriterWriteVFormatElement(xmlTextWriterPtr writer,
2158 const xmlChar * name, const char *format,
2159 va_list argptr)
2160{
2161 int rc;
2162 xmlChar *buf;
2163
2164 if (writer == NULL)
2165 return -1;
2166
2167 buf = xmlTextWriterVSprintf(format, argptr);
2168 if (buf == 0)
2169 return 0;
2170
2171 rc = xmlTextWriterWriteElement(writer, name, buf);
2172
2173 xmlFree(buf);
2174 return rc;
2175}
2176
2177/**
2178 * xmlTextWriterWriteElement:
2179 * @writer: the xmlTextWriterPtr
2180 * @name: element name
2181 * @content: element content
2182 *
2183 * Write an xml element.
2184 *
2185 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2186 */
2187int
2188xmlTextWriterWriteElement(xmlTextWriterPtr writer, const xmlChar * name,
2189 const xmlChar * content)
2190{
2191 int count;
2192 int sum;
2193
2194 sum = 0;
2195 count = xmlTextWriterStartElement(writer, name);
2196 if (count == -1)
2197 return -1;
2198 sum += count;
2199 count = xmlTextWriterWriteString(writer, content);
2200 if (count == -1)
2201 return -1;
2202 sum += count;
2203 count = xmlTextWriterEndElement(writer);
2204 if (count == -1)
2205 return -1;
2206 sum += count;
2207
2208 return sum;
2209}
2210
2211/**
2212 * xmlTextWriterWriteFormatElementNS:
2213 * @writer: the xmlTextWriterPtr
2214 * @prefix: namespace prefix
2215 * @name: element local name
2216 * @namespaceURI: namespace URI
2217 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002218 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002219 *
2220 * Write a formatted xml element with namespace support.
2221 *
2222 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2223 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00002224int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00002225xmlTextWriterWriteFormatElementNS(xmlTextWriterPtr writer,
2226 const xmlChar * prefix,
2227 const xmlChar * name,
2228 const xmlChar * namespaceURI,
2229 const char *format, ...)
2230{
2231 int rc;
2232 va_list ap;
2233
2234 va_start(ap, format);
2235
2236 rc = xmlTextWriterWriteVFormatElementNS(writer, prefix, name,
2237 namespaceURI, format, ap);
2238
2239 va_end(ap);
2240 return rc;
2241}
2242
2243/**
2244 * xmlTextWriterWriteVFormatElementNS:
2245 * @writer: the xmlTextWriterPtr
2246 * @prefix: namespace prefix
2247 * @name: element local name
2248 * @namespaceURI: namespace URI
2249 * @format: format string (see printf)
2250 * @argptr: pointer to the first member of the variable argument list.
2251 *
2252 * Write a formatted xml element with namespace support.
2253 *
2254 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2255 */
2256int
2257xmlTextWriterWriteVFormatElementNS(xmlTextWriterPtr writer,
2258 const xmlChar * prefix,
2259 const xmlChar * name,
2260 const xmlChar * namespaceURI,
2261 const char *format, va_list argptr)
2262{
2263 int rc;
2264 xmlChar *buf;
2265
2266 if (writer == NULL)
2267 return -1;
2268
2269 buf = xmlTextWriterVSprintf(format, argptr);
2270 if (buf == 0)
2271 return 0;
2272
2273 rc = xmlTextWriterWriteElementNS(writer, prefix, name, namespaceURI,
2274 buf);
2275
2276 xmlFree(buf);
2277 return rc;
2278}
2279
2280/**
2281 * xmlTextWriterWriteElementNS:
2282 * @writer: the xmlTextWriterPtr
2283 * @prefix: namespace prefix
2284 * @name: element local name
2285 * @namespaceURI: namespace URI
2286 * @content: element content
2287 *
2288 * Write an xml element with namespace support.
2289 *
2290 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2291 */
2292int
2293xmlTextWriterWriteElementNS(xmlTextWriterPtr writer,
2294 const xmlChar * prefix, const xmlChar * name,
2295 const xmlChar * namespaceURI,
2296 const xmlChar * content)
2297{
2298 int count;
2299 int sum;
2300
2301 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
2302 return -1;
2303
2304 sum = 0;
2305 count =
2306 xmlTextWriterStartElementNS(writer, prefix, name, namespaceURI);
2307 if (count < 0)
2308 return -1;
2309 sum += count;
2310 count = xmlTextWriterWriteString(writer, content);
2311 if (count == -1)
2312 return -1;
2313 sum += count;
2314 count = xmlTextWriterEndElement(writer);
2315 if (count == -1)
2316 return -1;
2317 sum += count;
2318
2319 return sum;
2320}
2321
2322/**
2323 * xmlTextWriterStartPI:
2324 * @writer: the xmlTextWriterPtr
2325 * @target: PI target
2326 *
2327 * Start an xml PI.
2328 *
2329 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2330 */
2331int
2332xmlTextWriterStartPI(xmlTextWriterPtr writer, const xmlChar * target)
2333{
2334 int count;
2335 int sum;
2336 xmlLinkPtr lk;
2337 xmlTextWriterStackEntry *p;
2338
2339 if ((writer == NULL) || (target == NULL) || (*target == '\0'))
2340 return -1;
2341
2342 if (xmlStrcasecmp(target, (const xmlChar *) "xml") == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002343 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002344 "xmlTextWriterStartPI : target name [Xx][Mm][Ll] is reserved for xml standardization!\n");
2345 return -1;
2346 }
2347
2348 sum = 0;
2349 lk = xmlListFront(writer->nodes);
2350 if (lk != 0) {
2351 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2352 if (p != 0) {
2353 switch (p->state) {
2354 case XML_TEXTWRITER_ATTRIBUTE:
2355 count = xmlTextWriterEndAttribute(writer);
2356 if (count < 0)
2357 return -1;
2358 sum += count;
2359 /* fallthrough */
2360 case XML_TEXTWRITER_NAME:
2361 count = xmlOutputBufferWriteString(writer->out, ">");
2362 if (count < 0)
2363 return -1;
2364 sum += count;
2365 p->state = XML_TEXTWRITER_TEXT;
2366 break;
Daniel Veillardab69f362004-02-17 11:40:32 +00002367 case XML_TEXTWRITER_NONE:
2368 case XML_TEXTWRITER_TEXT:
2369 case XML_TEXTWRITER_DTD:
2370 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002371 case XML_TEXTWRITER_PI:
2372 case XML_TEXTWRITER_PI_TEXT:
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002373 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002374 "xmlTextWriterStartPI : nested PI!\n");
2375 return -1;
2376 default:
2377 return -1;
2378 }
2379 }
2380 }
2381
2382 p = (xmlTextWriterStackEntry *)
2383 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2384 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002385 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002386 "xmlTextWriterStartPI : out of memory!\n");
2387 return -1;
2388 }
2389
2390 p->name = xmlStrdup(target);
2391 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002392 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002393 "xmlTextWriterStartPI : out of memory!\n");
2394 xmlFree(p);
2395 return -1;
2396 }
2397 p->state = XML_TEXTWRITER_PI;
2398
2399 xmlListPushFront(writer->nodes, p);
2400
2401 count = xmlOutputBufferWriteString(writer->out, "<?");
2402 if (count < 0)
2403 return -1;
2404 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002405 count =
2406 xmlOutputBufferWriteString(writer->out, (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002407 if (count < 0)
2408 return -1;
2409 sum += count;
2410
2411 return sum;
2412}
2413
2414/**
2415 * xmlTextWriterEndPI:
2416 * @writer: the xmlTextWriterPtr
2417 *
2418 * End the current xml PI.
2419 *
2420 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2421 */
2422int
2423xmlTextWriterEndPI(xmlTextWriterPtr writer)
2424{
2425 int count;
2426 int sum;
2427 xmlLinkPtr lk;
2428 xmlTextWriterStackEntry *p;
2429
2430 if (writer == NULL)
2431 return -1;
2432
2433 lk = xmlListFront(writer->nodes);
2434 if (lk == 0)
2435 return 0;
2436
2437 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2438 if (p == 0)
2439 return 0;
2440
2441 sum = 0;
2442 switch (p->state) {
2443 case XML_TEXTWRITER_PI:
2444 case XML_TEXTWRITER_PI_TEXT:
2445 count = xmlOutputBufferWriteString(writer->out, "?>");
2446 if (count < 0)
2447 return -1;
2448 sum += count;
2449 break;
2450 default:
2451 return -1;
2452 }
2453
Daniel Veillard02c1f232006-04-27 08:10:25 +00002454 if (writer->indent) {
2455 count = xmlOutputBufferWriteString(writer->out, "\n");
2456 if (count < 0)
2457 return -1;
2458 sum += count;
2459 }
2460
Daniel Veillard1d211e22003-10-20 22:32:39 +00002461 xmlListPopFront(writer->nodes);
2462 return sum;
2463}
2464
2465/**
2466 * xmlTextWriterWriteFormatPI:
2467 * @writer: the xmlTextWriterPtr
2468 * @target: PI target
2469 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002470 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002471 *
2472 * Write a formatted PI.
2473 *
2474 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2475 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00002476int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00002477xmlTextWriterWriteFormatPI(xmlTextWriterPtr writer, const xmlChar * target,
2478 const char *format, ...)
2479{
2480 int rc;
2481 va_list ap;
2482
2483 va_start(ap, format);
2484
2485 rc = xmlTextWriterWriteVFormatPI(writer, target, format, ap);
2486
2487 va_end(ap);
2488 return rc;
2489}
2490
2491/**
2492 * xmlTextWriterWriteVFormatPI:
2493 * @writer: the xmlTextWriterPtr
2494 * @target: PI target
2495 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002496 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00002497 *
2498 * Write a formatted xml PI.
2499 *
2500 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2501 */
2502int
2503xmlTextWriterWriteVFormatPI(xmlTextWriterPtr writer,
2504 const xmlChar * target, const char *format,
2505 va_list argptr)
2506{
2507 int rc;
2508 xmlChar *buf;
2509
2510 if (writer == NULL)
2511 return -1;
2512
2513 buf = xmlTextWriterVSprintf(format, argptr);
2514 if (buf == 0)
2515 return 0;
2516
2517 rc = xmlTextWriterWritePI(writer, target, buf);
2518
2519 xmlFree(buf);
2520 return rc;
2521}
2522
2523/**
2524 * xmlTextWriterWritePI:
2525 * @writer: the xmlTextWriterPtr
2526 * @target: PI target
2527 * @content: PI content
2528 *
2529 * Write an xml PI.
2530 *
2531 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2532 */
2533int
2534xmlTextWriterWritePI(xmlTextWriterPtr writer, const xmlChar * target,
2535 const xmlChar * content)
2536{
2537 int count;
2538 int sum;
2539
2540 sum = 0;
2541 count = xmlTextWriterStartPI(writer, target);
2542 if (count == -1)
2543 return -1;
2544 sum += count;
2545 if (content != 0) {
2546 count = xmlTextWriterWriteString(writer, content);
2547 if (count == -1)
2548 return -1;
2549 sum += count;
2550 }
2551 count = xmlTextWriterEndPI(writer);
2552 if (count == -1)
2553 return -1;
2554 sum += count;
2555
2556 return sum;
2557}
2558
2559/**
2560 * xmlTextWriterStartCDATA:
2561 * @writer: the xmlTextWriterPtr
2562 *
2563 * Start an xml CDATA section.
2564 *
2565 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2566 */
2567int
2568xmlTextWriterStartCDATA(xmlTextWriterPtr writer)
2569{
2570 int count;
2571 int sum;
2572 xmlLinkPtr lk;
2573 xmlTextWriterStackEntry *p;
2574
2575 if (writer == NULL)
2576 return -1;
2577
2578 sum = 0;
2579 lk = xmlListFront(writer->nodes);
2580 if (lk != 0) {
2581 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2582 if (p != 0) {
2583 switch (p->state) {
2584 case XML_TEXTWRITER_NONE:
2585 case XML_TEXTWRITER_PI:
2586 case XML_TEXTWRITER_PI_TEXT:
2587 break;
2588 case XML_TEXTWRITER_ATTRIBUTE:
2589 count = xmlTextWriterEndAttribute(writer);
2590 if (count < 0)
2591 return -1;
2592 sum += count;
2593 /* fallthrough */
2594 case XML_TEXTWRITER_NAME:
2595 count = xmlOutputBufferWriteString(writer->out, ">");
2596 if (count < 0)
2597 return -1;
2598 sum += count;
2599 p->state = XML_TEXTWRITER_TEXT;
2600 break;
2601 case XML_TEXTWRITER_CDATA:
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002602 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002603 "xmlTextWriterStartCDATA : CDATA not allowed in this context!\n");
2604 return -1;
2605 default:
2606 return -1;
2607 }
2608 }
2609 }
2610
2611 p = (xmlTextWriterStackEntry *)
2612 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2613 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002614 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002615 "xmlTextWriterStartCDATA : out of memory!\n");
2616 return -1;
2617 }
2618
Daniel Veillard75e389d2005-07-29 22:02:24 +00002619 p->name = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002620 p->state = XML_TEXTWRITER_CDATA;
2621
2622 xmlListPushFront(writer->nodes, p);
2623
2624 count = xmlOutputBufferWriteString(writer->out, "<![CDATA[");
2625 if (count < 0)
2626 return -1;
2627 sum += count;
2628
2629 return sum;
2630}
2631
2632/**
2633 * xmlTextWriterEndCDATA:
2634 * @writer: the xmlTextWriterPtr
2635 *
2636 * End an xml CDATA section.
2637 *
2638 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2639 */
2640int
2641xmlTextWriterEndCDATA(xmlTextWriterPtr writer)
2642{
2643 int count;
2644 int sum;
2645 xmlLinkPtr lk;
2646 xmlTextWriterStackEntry *p;
2647
2648 if (writer == NULL)
2649 return -1;
2650
2651 lk = xmlListFront(writer->nodes);
2652 if (lk == 0)
2653 return -1;
2654
2655 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2656 if (p == 0)
2657 return -1;
2658
2659 sum = 0;
2660 switch (p->state) {
2661 case XML_TEXTWRITER_CDATA:
2662 count = xmlOutputBufferWriteString(writer->out, "]]>");
2663 if (count < 0)
2664 return -1;
2665 sum += count;
2666 break;
2667 default:
2668 return -1;
2669 }
2670
2671 xmlListPopFront(writer->nodes);
2672 return sum;
2673}
2674
2675/**
2676 * xmlTextWriterWriteFormatCDATA:
2677 * @writer: the xmlTextWriterPtr
2678 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002679 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002680 *
2681 * Write a formatted xml CDATA.
2682 *
2683 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2684 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00002685int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00002686xmlTextWriterWriteFormatCDATA(xmlTextWriterPtr writer, const char *format,
2687 ...)
2688{
2689 int rc;
2690 va_list ap;
2691
2692 va_start(ap, format);
2693
2694 rc = xmlTextWriterWriteVFormatCDATA(writer, format, ap);
2695
2696 va_end(ap);
2697 return rc;
2698}
2699
2700/**
2701 * xmlTextWriterWriteVFormatCDATA:
2702 * @writer: the xmlTextWriterPtr
2703 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002704 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00002705 *
2706 * Write a formatted xml CDATA.
2707 *
2708 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2709 */
2710int
2711xmlTextWriterWriteVFormatCDATA(xmlTextWriterPtr writer, const char *format,
2712 va_list argptr)
2713{
2714 int rc;
2715 xmlChar *buf;
2716
2717 if (writer == NULL)
2718 return -1;
2719
2720 buf = xmlTextWriterVSprintf(format, argptr);
2721 if (buf == 0)
2722 return 0;
2723
2724 rc = xmlTextWriterWriteCDATA(writer, buf);
2725
2726 xmlFree(buf);
2727 return rc;
2728}
2729
2730/**
2731 * xmlTextWriterWriteCDATA:
2732 * @writer: the xmlTextWriterPtr
2733 * @content: CDATA content
2734 *
2735 * Write an xml CDATA.
2736 *
2737 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2738 */
2739int
2740xmlTextWriterWriteCDATA(xmlTextWriterPtr writer, const xmlChar * content)
2741{
2742 int count;
2743 int sum;
2744
2745 sum = 0;
2746 count = xmlTextWriterStartCDATA(writer);
2747 if (count == -1)
2748 return -1;
2749 sum += count;
2750 if (content != 0) {
2751 count = xmlTextWriterWriteString(writer, content);
2752 if (count == -1)
2753 return -1;
2754 sum += count;
2755 }
2756 count = xmlTextWriterEndCDATA(writer);
2757 if (count == -1)
2758 return -1;
2759 sum += count;
2760
2761 return sum;
2762}
2763
2764/**
2765 * xmlTextWriterStartDTD:
2766 * @writer: the xmlTextWriterPtr
2767 * @name: the name of the DTD
2768 * @pubid: the public identifier, which is an alternative to the system identifier
2769 * @sysid: the system identifier, which is the URI of the DTD
2770 *
2771 * Start an xml DTD.
2772 *
2773 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2774 */
2775int
2776xmlTextWriterStartDTD(xmlTextWriterPtr writer,
2777 const xmlChar * name,
2778 const xmlChar * pubid, const xmlChar * sysid)
2779{
2780 int count;
2781 int sum;
2782 xmlLinkPtr lk;
2783 xmlTextWriterStackEntry *p;
2784
2785 if (writer == NULL || name == NULL || *name == '\0')
2786 return -1;
2787
2788 sum = 0;
2789 lk = xmlListFront(writer->nodes);
Daniel Veillardab69f362004-02-17 11:40:32 +00002790 if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002791 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002792 "xmlTextWriterStartDTD : DTD allowed only in prolog!\n");
2793 return -1;
2794 }
2795
2796 p = (xmlTextWriterStackEntry *)
2797 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2798 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002799 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002800 "xmlTextWriterStartDTD : out of memory!\n");
2801 return -1;
2802 }
2803
2804 p->name = xmlStrdup(name);
2805 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002806 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002807 "xmlTextWriterStartDTD : out of memory!\n");
2808 xmlFree(p);
2809 return -1;
2810 }
2811 p->state = XML_TEXTWRITER_DTD;
2812
2813 xmlListPushFront(writer->nodes, p);
2814
2815 count = xmlOutputBufferWriteString(writer->out, "<!DOCTYPE ");
2816 if (count < 0)
2817 return -1;
2818 sum += count;
2819 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
2820 if (count < 0)
2821 return -1;
2822 sum += count;
2823
2824 if (pubid != 0) {
2825 if (sysid == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002826 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002827 "xmlTextWriterStartDTD : system identifier needed!\n");
2828 return -1;
2829 }
2830
Daniel Veillard500a1de2004-03-22 15:22:58 +00002831 if (writer->indent)
2832 count = xmlOutputBufferWrite(writer->out, 1, "\n");
2833 else
2834 count = xmlOutputBufferWrite(writer->out, 1, " ");
2835 if (count < 0)
2836 return -1;
2837 sum += count;
2838
2839 count = xmlOutputBufferWriteString(writer->out, "PUBLIC ");
2840 if (count < 0)
2841 return -1;
2842 sum += count;
2843
2844 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002845 if (count < 0)
2846 return -1;
2847 sum += count;
2848
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002849 count =
2850 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002851 if (count < 0)
2852 return -1;
2853 sum += count;
2854
Daniel Veillard500a1de2004-03-22 15:22:58 +00002855 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002856 if (count < 0)
2857 return -1;
2858 sum += count;
2859 }
2860
2861 if (sysid != 0) {
2862 if (pubid == 0) {
Daniel Veillard500a1de2004-03-22 15:22:58 +00002863 if (writer->indent)
2864 count = xmlOutputBufferWrite(writer->out, 1, "\n");
2865 else
2866 count = xmlOutputBufferWrite(writer->out, 1, " ");
2867 if (count < 0)
2868 return -1;
2869 sum += count;
2870 count = xmlOutputBufferWriteString(writer->out, "SYSTEM ");
2871 if (count < 0)
2872 return -1;
2873 sum += count;
Rob Richardsffe47fe2005-12-09 17:52:21 +00002874 } else {
2875 if (writer->indent)
Daniel Veillard500a1de2004-03-22 15:22:58 +00002876 count = xmlOutputBufferWriteString(writer->out, "\n ");
Rob Richardsffe47fe2005-12-09 17:52:21 +00002877 else
2878 count = xmlOutputBufferWrite(writer->out, 1, " ");
Daniel Veillard1d211e22003-10-20 22:32:39 +00002879 if (count < 0)
2880 return -1;
2881 sum += count;
2882 }
2883
Daniel Veillard500a1de2004-03-22 15:22:58 +00002884 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002885 if (count < 0)
2886 return -1;
2887 sum += count;
2888
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002889 count =
2890 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002891 if (count < 0)
2892 return -1;
2893 sum += count;
2894
Daniel Veillard500a1de2004-03-22 15:22:58 +00002895 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002896 if (count < 0)
2897 return -1;
2898 sum += count;
2899 }
2900
2901 return sum;
2902}
2903
2904/**
2905 * xmlTextWriterEndDTD:
2906 * @writer: the xmlTextWriterPtr
2907 *
2908 * End an xml DTD.
2909 *
2910 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2911 */
2912int
2913xmlTextWriterEndDTD(xmlTextWriterPtr writer)
2914{
Daniel Veillard500a1de2004-03-22 15:22:58 +00002915 int loop;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002916 int count;
2917 int sum;
2918 xmlLinkPtr lk;
2919 xmlTextWriterStackEntry *p;
2920
2921 if (writer == NULL)
2922 return -1;
2923
2924 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00002925 loop = 1;
2926 while (loop) {
2927 lk = xmlListFront(writer->nodes);
2928 if (lk == NULL)
Daniel Veillard1d211e22003-10-20 22:32:39 +00002929 break;
Daniel Veillard500a1de2004-03-22 15:22:58 +00002930 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2931 if (p == 0)
2932 break;
2933 switch (p->state) {
2934 case XML_TEXTWRITER_DTD_TEXT:
2935 count = xmlOutputBufferWriteString(writer->out, "]");
2936 if (count < 0)
2937 return -1;
2938 sum += count;
2939 /* fallthrough */
2940 case XML_TEXTWRITER_DTD:
2941 count = xmlOutputBufferWriteString(writer->out, ">");
2942
2943 if (writer->indent) {
2944 if (count < 0)
2945 return -1;
2946 sum += count;
2947 count = xmlOutputBufferWriteString(writer->out, "\n");
2948 }
2949
2950 xmlListPopFront(writer->nodes);
2951 break;
2952 case XML_TEXTWRITER_DTD_ELEM:
2953 case XML_TEXTWRITER_DTD_ELEM_TEXT:
2954 count = xmlTextWriterEndDTDElement(writer);
2955 break;
2956 case XML_TEXTWRITER_DTD_ATTL:
2957 case XML_TEXTWRITER_DTD_ATTL_TEXT:
2958 count = xmlTextWriterEndDTDAttlist(writer);
2959 break;
2960 case XML_TEXTWRITER_DTD_ENTY:
2961 case XML_TEXTWRITER_DTD_PENT:
2962 case XML_TEXTWRITER_DTD_ENTY_TEXT:
2963 count = xmlTextWriterEndDTDEntity(writer);
2964 break;
2965 case XML_TEXTWRITER_COMMENT:
2966 count = xmlTextWriterEndComment(writer);
2967 break;
2968 default:
2969 loop = 0;
2970 continue;
2971 }
2972
2973 if (count < 0)
Daniel Veillard1d211e22003-10-20 22:32:39 +00002974 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00002975 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002976 }
2977
Daniel Veillard1d211e22003-10-20 22:32:39 +00002978 return sum;
2979}
2980
2981/**
2982 * xmlTextWriterWriteFormatDTD:
2983 * @writer: the xmlTextWriterPtr
2984 * @name: the name of the DTD
2985 * @pubid: the public identifier, which is an alternative to the system identifier
2986 * @sysid: the system identifier, which is the URI of the DTD
2987 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002988 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002989 *
2990 * Write a DTD with a formatted markup declarations part.
2991 *
2992 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2993 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00002994int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00002995xmlTextWriterWriteFormatDTD(xmlTextWriterPtr writer,
2996 const xmlChar * name,
2997 const xmlChar * pubid,
2998 const xmlChar * sysid, const char *format, ...)
2999{
3000 int rc;
3001 va_list ap;
3002
3003 va_start(ap, format);
3004
3005 rc = xmlTextWriterWriteVFormatDTD(writer, name, pubid, sysid, format,
3006 ap);
3007
3008 va_end(ap);
3009 return rc;
3010}
3011
3012/**
3013 * xmlTextWriterWriteVFormatDTD:
3014 * @writer: the xmlTextWriterPtr
3015 * @name: the name of the DTD
3016 * @pubid: the public identifier, which is an alternative to the system identifier
3017 * @sysid: the system identifier, which is the URI of the DTD
3018 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003019 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00003020 *
3021 * Write a DTD with a formatted markup declarations part.
3022 *
3023 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3024 */
3025int
3026xmlTextWriterWriteVFormatDTD(xmlTextWriterPtr writer,
3027 const xmlChar * name,
3028 const xmlChar * pubid,
3029 const xmlChar * sysid,
3030 const char *format, va_list argptr)
3031{
3032 int rc;
3033 xmlChar *buf;
3034
3035 if (writer == NULL)
3036 return -1;
3037
3038 buf = xmlTextWriterVSprintf(format, argptr);
3039 if (buf == 0)
3040 return 0;
3041
3042 rc = xmlTextWriterWriteDTD(writer, name, pubid, sysid, buf);
3043
3044 xmlFree(buf);
3045 return rc;
3046}
3047
3048/**
3049 * xmlTextWriterWriteDTD:
3050 * @writer: the xmlTextWriterPtr
3051 * @name: the name of the DTD
3052 * @pubid: the public identifier, which is an alternative to the system identifier
3053 * @sysid: the system identifier, which is the URI of the DTD
William M. Brackb1d53162003-11-18 06:54:40 +00003054 * @subset: string content of the DTD
Daniel Veillard1d211e22003-10-20 22:32:39 +00003055 *
3056 * Write a DTD.
3057 *
3058 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3059 */
3060int
3061xmlTextWriterWriteDTD(xmlTextWriterPtr writer,
3062 const xmlChar * name,
3063 const xmlChar * pubid,
3064 const xmlChar * sysid, const xmlChar * subset)
3065{
3066 int count;
3067 int sum;
3068
3069 sum = 0;
3070 count = xmlTextWriterStartDTD(writer, name, pubid, sysid);
3071 if (count == -1)
3072 return -1;
3073 sum += count;
3074 if (subset != 0) {
3075 count = xmlTextWriterWriteString(writer, subset);
3076 if (count == -1)
3077 return -1;
3078 sum += count;
3079 }
3080 count = xmlTextWriterEndDTD(writer);
3081 if (count == -1)
3082 return -1;
3083 sum += count;
3084
3085 return sum;
3086}
3087
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003088/**
3089 * xmlTextWriterStartDTDElement:
3090 * @writer: the xmlTextWriterPtr
3091 * @name: the name of the DTD element
3092 *
3093 * Start an xml DTD element.
3094 *
3095 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3096 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003097int
3098xmlTextWriterStartDTDElement(xmlTextWriterPtr writer, const xmlChar * name)
3099{
3100 int count;
3101 int sum;
3102 xmlLinkPtr lk;
3103 xmlTextWriterStackEntry *p;
3104
3105 if (writer == NULL || name == NULL || *name == '\0')
3106 return -1;
3107
3108 sum = 0;
3109 lk = xmlListFront(writer->nodes);
3110 if (lk == 0) {
3111 return -1;
3112 }
3113
3114 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
Daniel Veillard500a1de2004-03-22 15:22:58 +00003115 if (p != 0) {
3116 switch (p->state) {
3117 case XML_TEXTWRITER_DTD:
3118 count = xmlOutputBufferWriteString(writer->out, " [");
3119 if (count < 0)
3120 return -1;
3121 sum += count;
3122 if (writer->indent) {
3123 count = xmlOutputBufferWriteString(writer->out, "\n");
3124 if (count < 0)
3125 return -1;
3126 sum += count;
3127 }
3128 p->state = XML_TEXTWRITER_DTD_TEXT;
3129 /* fallthrough */
3130 case XML_TEXTWRITER_DTD_TEXT:
3131 case XML_TEXTWRITER_NONE:
3132 break;
3133 default:
Daniel Veillard1d211e22003-10-20 22:32:39 +00003134 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00003135 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00003136 }
3137
3138 p = (xmlTextWriterStackEntry *)
3139 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3140 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003141 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003142 "xmlTextWriterStartDTDElement : out of memory!\n");
3143 return -1;
3144 }
3145
3146 p->name = xmlStrdup(name);
3147 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003148 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003149 "xmlTextWriterStartDTDElement : out of memory!\n");
3150 xmlFree(p);
3151 return -1;
3152 }
3153 p->state = XML_TEXTWRITER_DTD_ELEM;
3154
3155 xmlListPushFront(writer->nodes, p);
3156
Daniel Veillard500a1de2004-03-22 15:22:58 +00003157 if (writer->indent) {
3158 count = xmlTextWriterWriteIndent(writer);
3159 if (count < 0)
3160 return -1;
3161 sum += count;
3162 }
3163
Daniel Veillard1d211e22003-10-20 22:32:39 +00003164 count = xmlOutputBufferWriteString(writer->out, "<!ELEMENT ");
3165 if (count < 0)
3166 return -1;
3167 sum += count;
3168 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
3169 if (count < 0)
3170 return -1;
3171 sum += count;
3172
3173 return sum;
3174}
3175
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003176/**
Daniel Veillard500a1de2004-03-22 15:22:58 +00003177 * xmlTextWriterEndDTDElement:
3178 * @writer: the xmlTextWriterPtr
3179 *
3180 * End an xml DTD element.
3181 *
3182 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3183 */
3184int
3185xmlTextWriterEndDTDElement(xmlTextWriterPtr writer)
3186{
3187 int count;
3188 int sum;
3189 xmlLinkPtr lk;
3190 xmlTextWriterStackEntry *p;
3191
3192 if (writer == NULL)
3193 return -1;
3194
3195 sum = 0;
3196 lk = xmlListFront(writer->nodes);
3197 if (lk == 0)
3198 return -1;
3199
3200 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3201 if (p == 0)
3202 return -1;
3203
3204 switch (p->state) {
3205 case XML_TEXTWRITER_DTD_ELEM:
3206 case XML_TEXTWRITER_DTD_ELEM_TEXT:
3207 count = xmlOutputBufferWriteString(writer->out, ">");
3208 if (count < 0)
3209 return -1;
3210 sum += count;
3211 break;
3212 default:
3213 return -1;
3214 }
3215
3216 if (writer->indent) {
3217 count = xmlOutputBufferWriteString(writer->out, "\n");
3218 if (count < 0)
3219 return -1;
3220 sum += count;
3221 }
3222
3223 xmlListPopFront(writer->nodes);
3224 return sum;
3225}
3226
3227/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003228 * xmlTextWriterWriteFormatDTDElement:
3229 * @writer: the xmlTextWriterPtr
3230 * @name: the name of the DTD element
3231 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003232 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003233 *
3234 * Write a formatted DTD element.
3235 *
3236 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3237 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00003238int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00003239xmlTextWriterWriteFormatDTDElement(xmlTextWriterPtr writer,
3240 const xmlChar * name,
3241 const char *format, ...)
3242{
3243 int rc;
3244 va_list ap;
3245
3246 va_start(ap, format);
3247
3248 rc = xmlTextWriterWriteVFormatDTDElement(writer, name, format, ap);
3249
3250 va_end(ap);
3251 return rc;
3252}
3253
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003254/**
3255 * xmlTextWriterWriteVFormatDTDElement:
3256 * @writer: the xmlTextWriterPtr
3257 * @name: the name of the DTD element
3258 * @format: format string (see printf)
3259 * @argptr: pointer to the first member of the variable argument list.
3260 *
3261 * Write a formatted DTD element.
3262 *
3263 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3264 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003265int
3266xmlTextWriterWriteVFormatDTDElement(xmlTextWriterPtr writer,
3267 const xmlChar * name,
3268 const char *format, va_list argptr)
3269{
3270 int rc;
3271 xmlChar *buf;
3272
3273 if (writer == NULL)
3274 return -1;
3275
3276 buf = xmlTextWriterVSprintf(format, argptr);
3277 if (buf == 0)
3278 return 0;
3279
3280 rc = xmlTextWriterWriteDTDElement(writer, name, buf);
3281
3282 xmlFree(buf);
3283 return rc;
3284}
3285
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003286/**
3287 * xmlTextWriterWriteDTDElement:
3288 * @writer: the xmlTextWriterPtr
3289 * @name: the name of the DTD element
3290 * @content: content of the element
3291 *
3292 * Write a DTD element.
3293 *
3294 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3295 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003296int
3297xmlTextWriterWriteDTDElement(xmlTextWriterPtr writer,
3298 const xmlChar * name, const xmlChar * content)
3299{
3300 int count;
3301 int sum;
3302
3303 if (content == NULL)
3304 return -1;
3305
3306 sum = 0;
3307 count = xmlTextWriterStartDTDElement(writer, name);
3308 if (count == -1)
3309 return -1;
3310 sum += count;
3311
Daniel Veillard1d211e22003-10-20 22:32:39 +00003312 count = xmlTextWriterWriteString(writer, content);
3313 if (count == -1)
3314 return -1;
3315 sum += count;
3316
3317 count = xmlTextWriterEndDTDElement(writer);
3318 if (count == -1)
3319 return -1;
3320 sum += count;
3321
3322 return sum;
3323}
3324
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003325/**
3326 * xmlTextWriterStartDTDAttlist:
3327 * @writer: the xmlTextWriterPtr
3328 * @name: the name of the DTD ATTLIST
3329 *
3330 * Start an xml DTD ATTLIST.
3331 *
3332 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3333 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003334int
3335xmlTextWriterStartDTDAttlist(xmlTextWriterPtr writer, const xmlChar * name)
3336{
3337 int count;
3338 int sum;
3339 xmlLinkPtr lk;
3340 xmlTextWriterStackEntry *p;
3341
3342 if (writer == NULL || name == NULL || *name == '\0')
3343 return -1;
3344
3345 sum = 0;
3346 lk = xmlListFront(writer->nodes);
3347 if (lk == 0) {
3348 return -1;
3349 }
3350
3351 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
Daniel Veillard500a1de2004-03-22 15:22:58 +00003352 if (p != 0) {
3353 switch (p->state) {
3354 case XML_TEXTWRITER_DTD:
3355 count = xmlOutputBufferWriteString(writer->out, " [");
3356 if (count < 0)
3357 return -1;
3358 sum += count;
3359 if (writer->indent) {
3360 count = xmlOutputBufferWriteString(writer->out, "\n");
3361 if (count < 0)
3362 return -1;
3363 sum += count;
3364 }
3365 p->state = XML_TEXTWRITER_DTD_TEXT;
3366 /* fallthrough */
3367 case XML_TEXTWRITER_DTD_TEXT:
3368 case XML_TEXTWRITER_NONE:
3369 break;
3370 default:
Daniel Veillard1d211e22003-10-20 22:32:39 +00003371 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00003372 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00003373 }
3374
3375 p = (xmlTextWriterStackEntry *)
3376 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3377 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003378 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003379 "xmlTextWriterStartDTDAttlist : out of memory!\n");
3380 return -1;
3381 }
3382
3383 p->name = xmlStrdup(name);
3384 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003385 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003386 "xmlTextWriterStartDTDAttlist : out of memory!\n");
3387 xmlFree(p);
3388 return -1;
3389 }
3390 p->state = XML_TEXTWRITER_DTD_ATTL;
3391
3392 xmlListPushFront(writer->nodes, p);
3393
Daniel Veillard500a1de2004-03-22 15:22:58 +00003394 if (writer->indent) {
3395 count = xmlTextWriterWriteIndent(writer);
3396 if (count < 0)
3397 return -1;
3398 sum += count;
3399 }
3400
Daniel Veillard1d211e22003-10-20 22:32:39 +00003401 count = xmlOutputBufferWriteString(writer->out, "<!ATTLIST ");
3402 if (count < 0)
3403 return -1;
3404 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +00003405 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003406 if (count < 0)
3407 return -1;
3408 sum += count;
3409
3410 return sum;
3411}
3412
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003413/**
Daniel Veillard500a1de2004-03-22 15:22:58 +00003414 * xmlTextWriterEndDTDAttlist:
3415 * @writer: the xmlTextWriterPtr
3416 *
3417 * End an xml DTD attribute list.
3418 *
3419 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3420 */
3421int
3422xmlTextWriterEndDTDAttlist(xmlTextWriterPtr writer)
3423{
3424 int count;
3425 int sum;
3426 xmlLinkPtr lk;
3427 xmlTextWriterStackEntry *p;
3428
3429 if (writer == NULL)
3430 return -1;
3431
3432 sum = 0;
3433 lk = xmlListFront(writer->nodes);
3434 if (lk == 0)
3435 return -1;
3436
3437 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3438 if (p == 0)
3439 return -1;
3440
3441 switch (p->state) {
3442 case XML_TEXTWRITER_DTD_ATTL:
3443 case XML_TEXTWRITER_DTD_ATTL_TEXT:
3444 count = xmlOutputBufferWriteString(writer->out, ">");
3445 if (count < 0)
3446 return -1;
3447 sum += count;
3448 break;
3449 default:
3450 return -1;
3451 }
3452
3453 if (writer->indent) {
3454 count = xmlOutputBufferWriteString(writer->out, "\n");
3455 if (count < 0)
3456 return -1;
3457 sum += count;
3458 }
3459
3460 xmlListPopFront(writer->nodes);
3461 return sum;
3462}
3463
3464/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003465 * xmlTextWriterWriteFormatDTDAttlist:
3466 * @writer: the xmlTextWriterPtr
3467 * @name: the name of the DTD ATTLIST
3468 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003469 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003470 *
3471 * Write a formatted DTD ATTLIST.
3472 *
3473 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3474 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00003475int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00003476xmlTextWriterWriteFormatDTDAttlist(xmlTextWriterPtr writer,
3477 const xmlChar * name,
3478 const char *format, ...)
3479{
3480 int rc;
3481 va_list ap;
3482
3483 va_start(ap, format);
3484
3485 rc = xmlTextWriterWriteVFormatDTDAttlist(writer, name, format, ap);
3486
3487 va_end(ap);
3488 return rc;
3489}
3490
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003491/**
3492 * xmlTextWriterWriteVFormatDTDAttlist:
3493 * @writer: the xmlTextWriterPtr
3494 * @name: the name of the DTD ATTLIST
3495 * @format: format string (see printf)
3496 * @argptr: pointer to the first member of the variable argument list.
3497 *
3498 * Write a formatted DTD ATTLIST.
3499 *
3500 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3501 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003502int
3503xmlTextWriterWriteVFormatDTDAttlist(xmlTextWriterPtr writer,
3504 const xmlChar * name,
3505 const char *format, va_list argptr)
3506{
3507 int rc;
3508 xmlChar *buf;
3509
3510 if (writer == NULL)
3511 return -1;
3512
3513 buf = xmlTextWriterVSprintf(format, argptr);
3514 if (buf == 0)
3515 return 0;
3516
3517 rc = xmlTextWriterWriteDTDAttlist(writer, name, buf);
3518
3519 xmlFree(buf);
3520 return rc;
3521}
3522
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003523/**
3524 * xmlTextWriterWriteDTDAttlist:
3525 * @writer: the xmlTextWriterPtr
3526 * @name: the name of the DTD ATTLIST
3527 * @content: content of the ATTLIST
3528 *
3529 * Write a DTD ATTLIST.
3530 *
3531 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3532 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003533int
3534xmlTextWriterWriteDTDAttlist(xmlTextWriterPtr writer,
3535 const xmlChar * name, const xmlChar * content)
3536{
3537 int count;
3538 int sum;
3539
3540 if (content == NULL)
3541 return -1;
3542
3543 sum = 0;
3544 count = xmlTextWriterStartDTDAttlist(writer, name);
3545 if (count == -1)
3546 return -1;
3547 sum += count;
3548
Daniel Veillard1d211e22003-10-20 22:32:39 +00003549 count = xmlTextWriterWriteString(writer, content);
3550 if (count == -1)
3551 return -1;
3552 sum += count;
3553
3554 count = xmlTextWriterEndDTDAttlist(writer);
3555 if (count == -1)
3556 return -1;
3557 sum += count;
3558
3559 return sum;
3560}
3561
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003562/**
3563 * xmlTextWriterStartDTDEntity:
3564 * @writer: the xmlTextWriterPtr
3565 * @pe: TRUE if this is a parameter entity, FALSE if not
3566 * @name: the name of the DTD ATTLIST
3567 *
3568 * Start an xml DTD ATTLIST.
3569 *
3570 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3571 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003572int
3573xmlTextWriterStartDTDEntity(xmlTextWriterPtr writer,
3574 int pe, const xmlChar * name)
3575{
3576 int count;
3577 int sum;
3578 xmlLinkPtr lk;
3579 xmlTextWriterStackEntry *p;
3580
3581 if (writer == NULL || name == NULL || *name == '\0')
3582 return -1;
3583
3584 sum = 0;
3585 lk = xmlListFront(writer->nodes);
Daniel Veillard500a1de2004-03-22 15:22:58 +00003586 if (lk != 0) {
Daniel Veillard1d211e22003-10-20 22:32:39 +00003587
Daniel Veillard500a1de2004-03-22 15:22:58 +00003588 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3589 if (p != 0) {
3590 switch (p->state) {
3591 case XML_TEXTWRITER_DTD:
3592 count = xmlOutputBufferWriteString(writer->out, " [");
3593 if (count < 0)
3594 return -1;
3595 sum += count;
3596 if (writer->indent) {
3597 count =
3598 xmlOutputBufferWriteString(writer->out, "\n");
3599 if (count < 0)
3600 return -1;
3601 sum += count;
3602 }
3603 p->state = XML_TEXTWRITER_DTD_TEXT;
3604 /* fallthrough */
3605 case XML_TEXTWRITER_DTD_TEXT:
3606 case XML_TEXTWRITER_NONE:
3607 break;
3608 default:
3609 return -1;
3610 }
3611 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00003612 }
3613
3614 p = (xmlTextWriterStackEntry *)
3615 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3616 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003617 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003618 "xmlTextWriterStartDTDElement : out of memory!\n");
3619 return -1;
3620 }
3621
3622 p->name = xmlStrdup(name);
3623 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003624 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003625 "xmlTextWriterStartDTDElement : out of memory!\n");
3626 xmlFree(p);
3627 return -1;
3628 }
Daniel Veillard500a1de2004-03-22 15:22:58 +00003629
3630 if (pe != 0)
3631 p->state = XML_TEXTWRITER_DTD_PENT;
3632 else
3633 p->state = XML_TEXTWRITER_DTD_ENTY;
Daniel Veillard1d211e22003-10-20 22:32:39 +00003634
3635 xmlListPushFront(writer->nodes, p);
3636
Daniel Veillard500a1de2004-03-22 15:22:58 +00003637 if (writer->indent) {
3638 count = xmlTextWriterWriteIndent(writer);
3639 if (count < 0)
3640 return -1;
3641 sum += count;
3642 }
3643
Daniel Veillard1d211e22003-10-20 22:32:39 +00003644 count = xmlOutputBufferWriteString(writer->out, "<!ENTITY ");
3645 if (count < 0)
3646 return -1;
3647 sum += count;
3648
3649 if (pe != 0) {
Daniel Veillard500a1de2004-03-22 15:22:58 +00003650 count = xmlOutputBufferWriteString(writer->out, "% ");
Daniel Veillard1d211e22003-10-20 22:32:39 +00003651 if (count < 0)
3652 return -1;
3653 sum += count;
3654 }
3655
Daniel Veillardab69f362004-02-17 11:40:32 +00003656 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003657 if (count < 0)
3658 return -1;
3659 sum += count;
3660
3661 return sum;
3662}
3663
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003664/**
Daniel Veillard500a1de2004-03-22 15:22:58 +00003665 * xmlTextWriterEndDTDEntity:
3666 * @writer: the xmlTextWriterPtr
3667 *
3668 * End an xml DTD entity.
3669 *
3670 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3671 */
3672int
3673xmlTextWriterEndDTDEntity(xmlTextWriterPtr writer)
3674{
3675 int count;
3676 int sum;
3677 xmlLinkPtr lk;
3678 xmlTextWriterStackEntry *p;
3679
3680 if (writer == NULL)
3681 return -1;
3682
3683 sum = 0;
3684 lk = xmlListFront(writer->nodes);
3685 if (lk == 0)
3686 return -1;
3687
3688 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3689 if (p == 0)
3690 return -1;
3691
3692 switch (p->state) {
3693 case XML_TEXTWRITER_DTD_ENTY_TEXT:
3694 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3695 if (count < 0)
3696 return -1;
3697 sum += count;
3698 case XML_TEXTWRITER_DTD_ENTY:
3699 case XML_TEXTWRITER_DTD_PENT:
Daniel Veillard500a1de2004-03-22 15:22:58 +00003700 count = xmlOutputBufferWriteString(writer->out, ">");
3701 if (count < 0)
3702 return -1;
3703 sum += count;
3704 break;
3705 default:
3706 return -1;
3707 }
3708
3709 if (writer->indent) {
3710 count = xmlOutputBufferWriteString(writer->out, "\n");
3711 if (count < 0)
3712 return -1;
3713 sum += count;
3714 }
3715
3716 xmlListPopFront(writer->nodes);
3717 return sum;
3718}
3719
3720/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003721 * xmlTextWriterWriteFormatDTDInternalEntity:
3722 * @writer: the xmlTextWriterPtr
3723 * @pe: TRUE if this is a parameter entity, FALSE if not
3724 * @name: the name of the DTD entity
3725 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003726 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003727 *
3728 * Write a formatted DTD internal entity.
3729 *
3730 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3731 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00003732int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00003733xmlTextWriterWriteFormatDTDInternalEntity(xmlTextWriterPtr writer,
3734 int pe,
3735 const xmlChar * name,
3736 const char *format, ...)
3737{
3738 int rc;
3739 va_list ap;
3740
3741 va_start(ap, format);
3742
3743 rc = xmlTextWriterWriteVFormatDTDInternalEntity(writer, pe, name,
3744 format, ap);
3745
3746 va_end(ap);
3747 return rc;
3748}
3749
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003750/**
3751 * xmlTextWriterWriteVFormatDTDInternalEntity:
3752 * @writer: the xmlTextWriterPtr
3753 * @pe: TRUE if this is a parameter entity, FALSE if not
3754 * @name: the name of the DTD entity
3755 * @format: format string (see printf)
3756 * @argptr: pointer to the first member of the variable argument list.
3757 *
3758 * Write a formatted DTD internal entity.
3759 *
3760 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3761 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003762int
3763xmlTextWriterWriteVFormatDTDInternalEntity(xmlTextWriterPtr writer,
3764 int pe,
3765 const xmlChar * name,
3766 const char *format,
3767 va_list argptr)
3768{
3769 int rc;
3770 xmlChar *buf;
3771
3772 if (writer == NULL)
3773 return -1;
3774
3775 buf = xmlTextWriterVSprintf(format, argptr);
3776 if (buf == 0)
3777 return 0;
3778
3779 rc = xmlTextWriterWriteDTDInternalEntity(writer, pe, name, buf);
3780
3781 xmlFree(buf);
3782 return rc;
3783}
3784
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003785/**
3786 * xmlTextWriterWriteDTDEntity:
3787 * @writer: the xmlTextWriterPtr
3788 * @pe: TRUE if this is a parameter entity, FALSE if not
3789 * @name: the name of the DTD entity
3790 * @pubid: the public identifier, which is an alternative to the system identifier
3791 * @sysid: the system identifier, which is the URI of the DTD
3792 * @ndataid: the xml notation name.
3793 * @content: content of the entity
3794 *
3795 * Write a DTD entity.
3796 *
3797 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3798 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003799int
3800xmlTextWriterWriteDTDEntity(xmlTextWriterPtr writer,
3801 int pe,
3802 const xmlChar * name,
3803 const xmlChar * pubid,
3804 const xmlChar * sysid,
3805 const xmlChar * ndataid,
3806 const xmlChar * content)
3807{
Daniel Veillard500a1de2004-03-22 15:22:58 +00003808 if ((content == NULL) && (pubid == NULL) && (sysid == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00003809 return -1;
3810 if ((pe != 0) && (ndataid != NULL))
3811 return -1;
3812
Daniel Veillard500a1de2004-03-22 15:22:58 +00003813 if ((pubid == NULL) && (sysid == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00003814 return xmlTextWriterWriteDTDInternalEntity(writer, pe, name,
3815 content);
3816
3817 return xmlTextWriterWriteDTDExternalEntity(writer, pe, name, pubid,
3818 sysid, ndataid);
3819}
3820
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003821/**
3822 * xmlTextWriterWriteDTDInternalEntity:
3823 * @writer: the xmlTextWriterPtr
3824 * @pe: TRUE if this is a parameter entity, FALSE if not
3825 * @name: the name of the DTD entity
3826 * @content: content of the entity
3827 *
3828 * Write a DTD internal entity.
3829 *
3830 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3831 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003832int
3833xmlTextWriterWriteDTDInternalEntity(xmlTextWriterPtr writer,
3834 int pe,
3835 const xmlChar * name,
3836 const xmlChar * content)
3837{
3838 int count;
3839 int sum;
3840
3841 if ((name == NULL) || (*name == '\0') || (content == NULL))
3842 return -1;
3843
3844 sum = 0;
3845 count = xmlTextWriterStartDTDEntity(writer, pe, name);
3846 if (count == -1)
3847 return -1;
3848 sum += count;
3849
Daniel Veillard1d211e22003-10-20 22:32:39 +00003850 count = xmlTextWriterWriteString(writer, content);
3851 if (count == -1)
3852 return -1;
3853 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00003854
3855 count = xmlTextWriterEndDTDEntity(writer);
3856 if (count == -1)
3857 return -1;
3858 sum += count;
3859
3860 return sum;
3861}
3862
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003863/**
3864 * xmlTextWriterWriteDTDExternalEntity:
3865 * @writer: the xmlTextWriterPtr
3866 * @pe: TRUE if this is a parameter entity, FALSE if not
3867 * @name: the name of the DTD entity
3868 * @pubid: the public identifier, which is an alternative to the system identifier
3869 * @sysid: the system identifier, which is the URI of the DTD
3870 * @ndataid: the xml notation name.
3871 *
Daniel Veillard500a1de2004-03-22 15:22:58 +00003872 * Write a DTD external entity. The entity must have been started with xmlTextWriterStartDTDEntity
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003873 *
3874 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3875 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003876int
3877xmlTextWriterWriteDTDExternalEntity(xmlTextWriterPtr writer,
3878 int pe,
3879 const xmlChar * name,
3880 const xmlChar * pubid,
3881 const xmlChar * sysid,
3882 const xmlChar * ndataid)
3883{
3884 int count;
3885 int sum;
3886
Daniel Veillard500a1de2004-03-22 15:22:58 +00003887 if (((pubid == NULL) && (sysid == NULL)))
Daniel Veillard1d211e22003-10-20 22:32:39 +00003888 return -1;
3889 if ((pe != 0) && (ndataid != NULL))
3890 return -1;
3891
3892 sum = 0;
3893 count = xmlTextWriterStartDTDEntity(writer, pe, name);
3894 if (count == -1)
3895 return -1;
3896 sum += count;
3897
Daniel Veillard500a1de2004-03-22 15:22:58 +00003898 count =
3899 xmlTextWriterWriteDTDExternalEntityContents(writer, pubid, sysid,
3900 ndataid);
3901 if (count < 0)
3902 return -1;
3903 sum += count;
3904
3905 count = xmlTextWriterEndDTDEntity(writer);
3906 if (count == -1)
3907 return -1;
3908 sum += count;
3909
3910 return sum;
3911}
3912
3913/**
3914 * xmlTextWriterWriteDTDExternalEntityContents:
3915 * @writer: the xmlTextWriterPtr
3916 * @pubid: the public identifier, which is an alternative to the system identifier
3917 * @sysid: the system identifier, which is the URI of the DTD
3918 * @ndataid: the xml notation name.
3919 *
3920 * Write the contents of a DTD external entity.
3921 *
3922 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3923 */
3924int
3925xmlTextWriterWriteDTDExternalEntityContents(xmlTextWriterPtr writer,
3926 const xmlChar * pubid,
3927 const xmlChar * sysid,
3928 const xmlChar * ndataid)
3929{
3930 int count;
3931 int sum;
3932 xmlLinkPtr lk;
3933 xmlTextWriterStackEntry *p;
3934
3935 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003936 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003937 "xmlTextWriterWriteDTDExternalEntityContents: xmlTextWriterPtr invalid!\n");
3938 return -1;
3939 }
3940
3941 sum = 0;
3942 lk = xmlListFront(writer->nodes);
3943 if (lk == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003944 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003945 "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n");
3946 return -1;
3947 }
3948
3949 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3950 if (p == 0)
3951 return -1;
3952
3953 switch (p->state) {
3954 case XML_TEXTWRITER_DTD_ENTY:
3955 break;
3956 case XML_TEXTWRITER_DTD_PENT:
3957 if (ndataid != NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003958 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003959 "xmlTextWriterWriteDTDExternalEntityContents: notation not allowed with parameter entities!\n");
3960 return -1;
3961 }
3962 break;
3963 default:
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003964 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003965 "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n");
3966 return -1;
3967 }
3968
Daniel Veillard1d211e22003-10-20 22:32:39 +00003969 if (pubid != 0) {
3970 if (sysid == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003971 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003972 "xmlTextWriterWriteDTDExternalEntityContents: system identifier needed!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +00003973 return -1;
3974 }
3975
3976 count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
3977 if (count < 0)
3978 return -1;
3979 sum += count;
3980
3981 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3982 if (count < 0)
3983 return -1;
3984 sum += count;
3985
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003986 count =
3987 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003988 if (count < 0)
3989 return -1;
3990 sum += count;
3991
3992 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3993 if (count < 0)
3994 return -1;
3995 sum += count;
3996 }
3997
3998 if (sysid != 0) {
3999 if (pubid == 0) {
4000 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
4001 if (count < 0)
4002 return -1;
4003 sum += count;
4004 }
4005
4006 count = xmlOutputBufferWriteString(writer->out, " ");
4007 if (count < 0)
4008 return -1;
4009 sum += count;
4010
4011 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4012 if (count < 0)
4013 return -1;
4014 sum += count;
4015
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004016 count =
4017 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004018 if (count < 0)
4019 return -1;
4020 sum += count;
4021
4022 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4023 if (count < 0)
4024 return -1;
4025 sum += count;
4026 }
4027
4028 if (ndataid != NULL) {
4029 count = xmlOutputBufferWriteString(writer->out, " NDATA ");
4030 if (count < 0)
4031 return -1;
4032 sum += count;
4033
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004034 count =
4035 xmlOutputBufferWriteString(writer->out,
4036 (const char *) ndataid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004037 if (count < 0)
4038 return -1;
4039 sum += count;
4040 }
4041
Daniel Veillard1d211e22003-10-20 22:32:39 +00004042 return sum;
4043}
4044
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004045/**
4046 * xmlTextWriterWriteDTDNotation:
4047 * @writer: the xmlTextWriterPtr
4048 * @name: the name of the xml notation
4049 * @pubid: the public identifier, which is an alternative to the system identifier
4050 * @sysid: the system identifier, which is the URI of the DTD
4051 *
4052 * Write a DTD entity.
4053 *
4054 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
4055 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00004056int
4057xmlTextWriterWriteDTDNotation(xmlTextWriterPtr writer,
4058 const xmlChar * name,
4059 const xmlChar * pubid, const xmlChar * sysid)
4060{
4061 int count;
4062 int sum;
4063 xmlLinkPtr lk;
4064 xmlTextWriterStackEntry *p;
4065
4066 if (writer == NULL || name == NULL || *name == '\0')
4067 return -1;
4068
4069 sum = 0;
4070 lk = xmlListFront(writer->nodes);
4071 if (lk == 0) {
4072 return -1;
4073 }
4074
4075 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
Daniel Veillard500a1de2004-03-22 15:22:58 +00004076 if (p != 0) {
4077 switch (p->state) {
4078 case XML_TEXTWRITER_DTD:
4079 count = xmlOutputBufferWriteString(writer->out, " [");
4080 if (count < 0)
4081 return -1;
4082 sum += count;
4083 if (writer->indent) {
4084 count = xmlOutputBufferWriteString(writer->out, "\n");
4085 if (count < 0)
4086 return -1;
4087 sum += count;
4088 }
4089 p->state = XML_TEXTWRITER_DTD_TEXT;
4090 /* fallthrough */
4091 case XML_TEXTWRITER_DTD_TEXT:
4092 break;
4093 default:
4094 return -1;
4095 }
4096 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00004097
Daniel Veillard500a1de2004-03-22 15:22:58 +00004098 if (writer->indent) {
4099 count = xmlTextWriterWriteIndent(writer);
4100 if (count < 0)
Daniel Veillard1d211e22003-10-20 22:32:39 +00004101 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00004102 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00004103 }
4104
4105 count = xmlOutputBufferWriteString(writer->out, "<!NOTATION ");
4106 if (count < 0)
4107 return -1;
4108 sum += count;
4109 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
4110 if (count < 0)
4111 return -1;
4112 sum += count;
4113
4114 if (pubid != 0) {
4115 count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
4116 if (count < 0)
4117 return -1;
4118 sum += count;
4119 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4120 if (count < 0)
4121 return -1;
4122 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004123 count =
4124 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004125 if (count < 0)
4126 return -1;
4127 sum += count;
4128 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4129 if (count < 0)
4130 return -1;
4131 sum += count;
4132 }
4133
4134 if (sysid != 0) {
4135 if (pubid == 0) {
4136 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
4137 if (count < 0)
4138 return -1;
4139 sum += count;
4140 }
4141 count = xmlOutputBufferWriteString(writer->out, " ");
4142 if (count < 0)
4143 return -1;
4144 sum += count;
4145 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4146 if (count < 0)
4147 return -1;
4148 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004149 count =
4150 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004151 if (count < 0)
4152 return -1;
4153 sum += count;
4154 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4155 if (count < 0)
4156 return -1;
4157 sum += count;
4158 }
4159
4160 count = xmlOutputBufferWriteString(writer->out, ">");
4161 if (count < 0)
4162 return -1;
4163 sum += count;
4164
4165 return sum;
4166}
4167
4168/**
4169 * xmlTextWriterFlush:
4170 * @writer: the xmlTextWriterPtr
4171 *
4172 * Flush the output buffer.
4173 *
4174 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
4175 */
4176int
4177xmlTextWriterFlush(xmlTextWriterPtr writer)
4178{
4179 int count;
4180
4181 if (writer == NULL)
4182 return -1;
4183
4184 if (writer->out == NULL)
4185 count = 0;
4186 else
4187 count = xmlOutputBufferFlush(writer->out);
4188
4189 return count;
4190}
4191
4192/**
4193 * misc
4194 */
4195
4196/**
4197 * xmlFreeTextWriterStackEntry:
4198 * @lk: the xmlLinkPtr
4199 *
4200 * Free callback for the xmlList.
4201 */
4202static void
4203xmlFreeTextWriterStackEntry(xmlLinkPtr lk)
4204{
4205 xmlTextWriterStackEntry *p;
4206
4207 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
4208 if (p == 0)
4209 return;
4210
4211 if (p->name != 0)
4212 xmlFree(p->name);
4213 xmlFree(p);
4214}
4215
4216/**
4217 * xmlCmpTextWriterStackEntry:
4218 * @data0: the first data
4219 * @data1: the second data
4220 *
4221 * Compare callback for the xmlList.
4222 *
4223 * Returns -1, 0, 1
4224 */
4225static int
4226xmlCmpTextWriterStackEntry(const void *data0, const void *data1)
4227{
4228 xmlTextWriterStackEntry *p0;
4229 xmlTextWriterStackEntry *p1;
4230
4231 if (data0 == data1)
4232 return 0;
4233
4234 if (data0 == 0)
4235 return -1;
4236
4237 if (data1 == 0)
4238 return 1;
4239
4240 p0 = (xmlTextWriterStackEntry *) data0;
4241 p1 = (xmlTextWriterStackEntry *) data1;
4242
4243 return xmlStrcmp(p0->name, p1->name);
4244}
4245
4246/**
4247 * misc
4248 */
4249
4250/**
4251 * xmlFreeTextWriterNsStackEntry:
4252 * @lk: the xmlLinkPtr
4253 *
4254 * Free callback for the xmlList.
4255 */
4256static void
4257xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk)
4258{
4259 xmlTextWriterNsStackEntry *p;
4260
4261 p = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
4262 if (p == 0)
4263 return;
4264
4265 if (p->prefix != 0)
4266 xmlFree(p->prefix);
4267 if (p->uri != 0)
4268 xmlFree(p->uri);
4269
4270 xmlFree(p);
4271}
4272
4273/**
4274 * xmlCmpTextWriterNsStackEntry:
4275 * @data0: the first data
4276 * @data1: the second data
4277 *
4278 * Compare callback for the xmlList.
4279 *
4280 * Returns -1, 0, 1
4281 */
4282static int
4283xmlCmpTextWriterNsStackEntry(const void *data0, const void *data1)
4284{
4285 xmlTextWriterNsStackEntry *p0;
4286 xmlTextWriterNsStackEntry *p1;
4287 int rc;
4288
4289 if (data0 == data1)
4290 return 0;
4291
4292 if (data0 == 0)
4293 return -1;
4294
4295 if (data1 == 0)
4296 return 1;
4297
4298 p0 = (xmlTextWriterNsStackEntry *) data0;
4299 p1 = (xmlTextWriterNsStackEntry *) data1;
4300
4301 rc = xmlStrcmp(p0->prefix, p1->prefix);
4302
4303 if (rc == 0)
4304 rc = p0->elem == p1->elem;
4305
4306 return rc;
4307}
4308
4309/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004310 * xmlTextWriterWriteDocCallback:
4311 * @context: the xmlBufferPtr
4312 * @str: the data to write
4313 * @len: the length of the data
4314 *
4315 * Write callback for the xmlOutputBuffer with target xmlBuffer
4316 *
4317 * Returns -1, 0, 1
4318 */
4319static int
4320xmlTextWriterWriteDocCallback(void *context, const xmlChar * str, int len)
4321{
4322 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context;
4323 int rc;
4324
Daniel Veillard1d913862003-11-21 00:28:39 +00004325 if ((rc = xmlParseChunk(ctxt, (const char *) str, len, 0)) != 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004326 xmlWriterErrMsgInt(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004327 "xmlTextWriterWriteDocCallback : XML error %d !\n",
4328 rc);
4329 return -1;
4330 }
4331
4332 return len;
4333}
4334
4335/**
4336 * xmlTextWriterCloseDocCallback:
4337 * @context: the xmlBufferPtr
4338 *
4339 * Close callback for the xmlOutputBuffer with target xmlBuffer
4340 *
4341 * Returns -1, 0, 1
4342 */
4343static int
4344xmlTextWriterCloseDocCallback(void *context)
4345{
4346 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context;
4347 int rc;
4348
4349 if ((rc = xmlParseChunk(ctxt, NULL, 0, 1)) != 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004350 xmlWriterErrMsgInt(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004351 "xmlTextWriterWriteDocCallback : XML error %d !\n",
4352 rc);
4353 return -1;
4354 }
4355
4356 return 0;
4357}
4358
4359/**
Daniel Veillard1d211e22003-10-20 22:32:39 +00004360 * xmlTextWriterVSprintf:
4361 * @format: see printf
4362 * @argptr: pointer to the first member of the variable argument list.
4363 *
4364 * Utility function for formatted output
4365 *
4366 * Returns a new xmlChar buffer with the data or NULL on error. This buffer must be freed.
4367 */
4368static xmlChar *
4369xmlTextWriterVSprintf(const char *format, va_list argptr)
4370{
4371 int size;
4372 int count;
4373 xmlChar *buf;
William M. Brackf4caa5e2005-10-20 09:04:05 +00004374 va_list locarg;
Daniel Veillard1d211e22003-10-20 22:32:39 +00004375
4376 size = BUFSIZ;
4377 buf = (xmlChar *) xmlMalloc(size);
4378 if (buf == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004379 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00004380 "xmlTextWriterVSprintf : out of memory!\n");
4381 return NULL;
4382 }
4383
William M. Brackf4caa5e2005-10-20 09:04:05 +00004384 VA_COPY(locarg, argptr);
4385 while (((count = vsnprintf((char *) buf, size, format, locarg)) < 0)
Daniel Veillard1d211e22003-10-20 22:32:39 +00004386 || (count == size - 1) || (count == size) || (count > size)) {
William M. Brackf4caa5e2005-10-20 09:04:05 +00004387 va_end(locarg);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004388 xmlFree(buf);
4389 size += BUFSIZ;
4390 buf = (xmlChar *) xmlMalloc(size);
4391 if (buf == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004392 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00004393 "xmlTextWriterVSprintf : out of memory!\n");
4394 return NULL;
4395 }
William M. Brackf4caa5e2005-10-20 09:04:05 +00004396 VA_COPY(locarg, argptr);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004397 }
William M. Brackf4caa5e2005-10-20 09:04:05 +00004398 va_end(locarg);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004399
4400 return buf;
4401}
4402
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004403/**
4404 * xmlTextWriterStartDocumentCallback:
4405 * @ctx: the user data (XML parser context)
4406 *
4407 * called at the start of document processing.
4408 */
4409static void
4410xmlTextWriterStartDocumentCallback(void *ctx)
4411{
4412 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
4413 xmlDocPtr doc;
4414
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004415 if (ctxt->html) {
4416#ifdef LIBXML_HTML_ENABLED
4417 if (ctxt->myDoc == NULL)
4418 ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
4419 if (ctxt->myDoc == NULL) {
4420 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
4421 ctxt->sax->error(ctxt->userData,
4422 "SAX.startDocument(): out of memory\n");
4423 ctxt->errNo = XML_ERR_NO_MEMORY;
4424 ctxt->instate = XML_PARSER_EOF;
4425 ctxt->disableSAX = 1;
4426 return;
4427 }
4428#else
Daniel Veillardd0cf7f62004-11-09 16:17:02 +00004429 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004430 "libxml2 built without HTML support\n");
4431 ctxt->errNo = XML_ERR_INTERNAL_ERROR;
4432 ctxt->instate = XML_PARSER_EOF;
4433 ctxt->disableSAX = 1;
4434 return;
4435#endif
4436 } else {
4437 doc = ctxt->myDoc;
4438 if (doc == NULL)
4439 doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
4440 if (doc != NULL) {
4441 if (doc->children == NULL) {
4442 if (ctxt->encoding != NULL)
4443 doc->encoding = xmlStrdup(ctxt->encoding);
4444 else
4445 doc->encoding = NULL;
4446 doc->standalone = ctxt->standalone;
4447 }
4448 } else {
4449 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
4450 ctxt->sax->error(ctxt->userData,
4451 "SAX.startDocument(): out of memory\n");
4452 ctxt->errNo = XML_ERR_NO_MEMORY;
4453 ctxt->instate = XML_PARSER_EOF;
4454 ctxt->disableSAX = 1;
4455 return;
4456 }
4457 }
4458 if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) &&
4459 (ctxt->input != NULL) && (ctxt->input->filename != NULL)) {
4460 ctxt->myDoc->URL =
4461 xmlCanonicPath((const xmlChar *) ctxt->input->filename);
4462 if (ctxt->myDoc->URL == NULL)
4463 ctxt->myDoc->URL =
4464 xmlStrdup((const xmlChar *) ctxt->input->filename);
4465 }
4466}
4467
Daniel Veillard2cca4462004-01-02 20:04:23 +00004468/**
4469 * xmlTextWriterSetIndent:
4470 * @writer: the xmlTextWriterPtr
4471 * @indent: do indentation?
4472 *
4473 * Set indentation output. indent = 0 do not indentation. indent > 0 do indentation.
4474 *
4475 * Returns -1 on error or 0 otherwise.
4476 */
4477int
Daniel Veillardab69f362004-02-17 11:40:32 +00004478xmlTextWriterSetIndent(xmlTextWriterPtr writer, int indent)
Daniel Veillard2cca4462004-01-02 20:04:23 +00004479{
Daniel Veillarde43cc572004-11-03 11:50:29 +00004480 if ((writer == NULL) || (indent < 0))
Daniel Veillardab69f362004-02-17 11:40:32 +00004481 return -1;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004482
Daniel Veillardab69f362004-02-17 11:40:32 +00004483 writer->indent = indent;
4484 writer->doindent = 1;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004485
Daniel Veillardab69f362004-02-17 11:40:32 +00004486 return 0;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004487}
4488
4489/**
4490 * xmlTextWriterSetIndentString:
4491 * @writer: the xmlTextWriterPtr
4492 * @str: the xmlChar string
4493 *
4494 * Set string indentation.
4495 *
4496 * Returns -1 on error or 0 otherwise.
4497 */
4498int
Daniel Veillardab69f362004-02-17 11:40:32 +00004499xmlTextWriterSetIndentString(xmlTextWriterPtr writer, const xmlChar * str)
Daniel Veillard2cca4462004-01-02 20:04:23 +00004500{
Daniel Veillarde43cc572004-11-03 11:50:29 +00004501 if ((writer == NULL) || (!str))
Daniel Veillardab69f362004-02-17 11:40:32 +00004502 return -1;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004503
Daniel Veillardab69f362004-02-17 11:40:32 +00004504 if (writer->ichar != NULL)
4505 xmlFree(writer->ichar);
4506 writer->ichar = xmlStrdup(str);
4507
4508 if (!writer->ichar)
4509 return -1;
4510 else
4511 return 0;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004512}
4513
4514/**
4515 * xmlTextWriterWriteIndent:
4516 * @writer: the xmlTextWriterPtr
4517 *
4518 * Write indent string.
4519 *
4520 * Returns -1 on error or the number of strings written.
Daniel Veillardab69f362004-02-17 11:40:32 +00004521 */
Daniel Veillard2cca4462004-01-02 20:04:23 +00004522static int
Daniel Veillardab69f362004-02-17 11:40:32 +00004523xmlTextWriterWriteIndent(xmlTextWriterPtr writer)
Daniel Veillard2cca4462004-01-02 20:04:23 +00004524{
Daniel Veillardab69f362004-02-17 11:40:32 +00004525 int lksize;
4526 int i;
4527 int ret;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004528
Daniel Veillardab69f362004-02-17 11:40:32 +00004529 lksize = xmlListSize(writer->nodes);
4530 if (lksize < 1)
4531 return (-1); /* list is empty */
4532 for (i = 0; i < (lksize - 1); i++) {
4533 ret = xmlOutputBufferWriteString(writer->out,
4534 (const char *) writer->ichar);
4535 if (ret == -1)
4536 return (-1);
4537 }
4538
4539 return (lksize - 1);
Daniel Veillard2cca4462004-01-02 20:04:23 +00004540}
4541
Daniel Veillard500a1de2004-03-22 15:22:58 +00004542/**
4543 * xmlTextWriterHandleStateDependencies:
4544 * @writer: the xmlTextWriterPtr
4545 * @p: the xmlTextWriterStackEntry
4546 *
4547 * Write state dependent strings.
4548 *
4549 * Returns -1 on error or the number of characters written.
4550 */
4551static int
4552xmlTextWriterHandleStateDependencies(xmlTextWriterPtr writer,
4553 xmlTextWriterStackEntry * p)
4554{
4555 int count;
4556 int sum;
4557 char extra[3];
4558
4559 if (writer == NULL)
4560 return -1;
4561
4562 if (p == NULL)
4563 return 0;
4564
4565 sum = 0;
4566 extra[0] = extra[1] = extra[2] = '\0';
4567 if (p != 0) {
4568 sum = 0;
4569 switch (p->state) {
4570 case XML_TEXTWRITER_NAME:
4571 extra[0] = '>';
4572 p->state = XML_TEXTWRITER_TEXT;
4573 break;
4574 case XML_TEXTWRITER_PI:
4575 extra[0] = ' ';
4576 p->state = XML_TEXTWRITER_PI_TEXT;
4577 break;
4578 case XML_TEXTWRITER_DTD:
4579 extra[0] = ' ';
4580 extra[1] = '[';
4581 p->state = XML_TEXTWRITER_DTD_TEXT;
4582 break;
4583 case XML_TEXTWRITER_DTD_ELEM:
4584 extra[0] = ' ';
4585 p->state = XML_TEXTWRITER_DTD_ELEM_TEXT;
4586 break;
4587 case XML_TEXTWRITER_DTD_ATTL:
4588 extra[0] = ' ';
4589 p->state = XML_TEXTWRITER_DTD_ATTL_TEXT;
4590 break;
4591 case XML_TEXTWRITER_DTD_ENTY:
4592 case XML_TEXTWRITER_DTD_PENT:
4593 extra[0] = ' ';
4594 extra[1] = writer->qchar;
4595 p->state = XML_TEXTWRITER_DTD_ENTY_TEXT;
4596 break;
4597 default:
4598 break;
4599 }
4600 }
4601
4602 if (*extra != '\0') {
4603 count = xmlOutputBufferWriteString(writer->out, extra);
4604 if (count < 0)
4605 return -1;
4606 sum += count;
4607 }
4608
4609 return sum;
4610}
4611
Daniel Veillard5d4644e2005-04-01 13:11:58 +00004612#define bottom_xmlwriter
4613#include "elfgcchack.h"
Daniel Veillard1d211e22003-10-20 22:32:39 +00004614#endif