blob: 43934b36ba5badf4ff89f3e6dcec81d2c1a3ef14 [file] [log] [blame]
Daniel Veillard5841f0e2003-11-20 11:59:09 +00001
Daniel Veillard1d211e22003-10-20 22:32:39 +00002/*
3 * xmlwriter.c: XML text writer implementation
4 *
5 * For license and disclaimer see the license and disclaimer of
6 * libxml2.
7 *
8 * alfred@mickautsch.de
9 */
10
Igor Zlatkovicb23de5a2003-11-27 18:36:46 +000011#define IN_LIBXML
Daniel Veillard1d211e22003-10-20 22:32:39 +000012#include <string.h>
Daniel Veillard1d211e22003-10-20 22:32:39 +000013
14#include "libxml.h"
15#include <libxml/xmlmemory.h>
16#include <libxml/parser.h>
Daniel Veillard5841f0e2003-11-20 11:59:09 +000017#include <libxml/uri.h>
18#include <libxml/HTMLtree.h>
Daniel Veillard1d211e22003-10-20 22:32:39 +000019
20#ifdef LIBXML_WRITER_ENABLED
21
22#include <libxml/xmlwriter.h>
23
24#define B64LINELEN 72
25#define B64CRLF "\r\n"
26
27/*
William M. Brackf4caa5e2005-10-20 09:04:05 +000028 * The following VA_COPY was coded following an example in
29 * the Samba project. It may not be sufficient for some
30 * esoteric implementations of va_list (i.e. it may need
31 * something involving a memcpy) but (hopefully) will be
32 * sufficient for libxml2.
33 */
34#ifndef VA_COPY
35 #ifdef HAVE_VA_COPY
36 #define VA_COPY(dest, src) va_copy(dest, src)
37 #else
38 #ifdef HAVE___VA_COPY
39 #define VA_COPY(dest,src) __va_copy(dest, src)
40 #else
41 #define VA_COPY(dest,src) (dest) = (src)
42 #endif
43 #endif
44#endif
45
46/*
Daniel Veillard1d211e22003-10-20 22:32:39 +000047 * Types are kept private
48 */
49typedef enum {
50 XML_TEXTWRITER_NONE = 0,
51 XML_TEXTWRITER_NAME,
52 XML_TEXTWRITER_ATTRIBUTE,
53 XML_TEXTWRITER_TEXT,
54 XML_TEXTWRITER_PI,
55 XML_TEXTWRITER_PI_TEXT,
56 XML_TEXTWRITER_CDATA,
57 XML_TEXTWRITER_DTD,
58 XML_TEXTWRITER_DTD_TEXT,
59 XML_TEXTWRITER_DTD_ELEM,
Daniel Veillard500a1de2004-03-22 15:22:58 +000060 XML_TEXTWRITER_DTD_ELEM_TEXT,
Daniel Veillard1d211e22003-10-20 22:32:39 +000061 XML_TEXTWRITER_DTD_ATTL,
Daniel Veillard500a1de2004-03-22 15:22:58 +000062 XML_TEXTWRITER_DTD_ATTL_TEXT,
63 XML_TEXTWRITER_DTD_ENTY, /* entity */
64 XML_TEXTWRITER_DTD_ENTY_TEXT,
65 XML_TEXTWRITER_DTD_PENT, /* parameter entity */
William M. Brack87640d52004-04-17 14:58:15 +000066 XML_TEXTWRITER_COMMENT
Daniel Veillard1d211e22003-10-20 22:32:39 +000067} xmlTextWriterState;
68
69typedef struct _xmlTextWriterStackEntry xmlTextWriterStackEntry;
70
71struct _xmlTextWriterStackEntry {
72 xmlChar *name;
73 xmlTextWriterState state;
74};
75
76typedef struct _xmlTextWriterNsStackEntry xmlTextWriterNsStackEntry;
77struct _xmlTextWriterNsStackEntry {
78 xmlChar *prefix;
79 xmlChar *uri;
80 xmlLinkPtr elem;
81};
82
83struct _xmlTextWriter {
Daniel Veillardab69f362004-02-17 11:40:32 +000084 xmlOutputBufferPtr out; /* output buffer */
85 xmlListPtr nodes; /* element name stack */
86 xmlListPtr nsstack; /* name spaces stack */
Daniel Veillard1d211e22003-10-20 22:32:39 +000087 int level;
Daniel Veillardab69f362004-02-17 11:40:32 +000088 int indent; /* enable indent */
89 int doindent; /* internal indent flag */
90 xmlChar *ichar; /* indent character */
91 char qchar; /* character used for quoting attribute values */
Daniel Veillard20c5e782004-01-21 09:57:31 +000092 xmlParserCtxtPtr ctxt;
Daniel Veillarda521d282004-11-09 14:59:59 +000093 int no_doc_free;
Daniel Veillard1d211e22003-10-20 22:32:39 +000094};
95
96static void xmlFreeTextWriterStackEntry(xmlLinkPtr lk);
97static int xmlCmpTextWriterStackEntry(const void *data0,
98 const void *data1);
99static void xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk);
100static int xmlCmpTextWriterNsStackEntry(const void *data0,
101 const void *data1);
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000102static int xmlTextWriterWriteDocCallback(void *context,
103 const xmlChar * str, int len);
104static int xmlTextWriterCloseDocCallback(void *context);
105
Daniel Veillard1d211e22003-10-20 22:32:39 +0000106static xmlChar *xmlTextWriterVSprintf(const char *format, va_list argptr);
107static int xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len,
108 const unsigned char *data);
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000109static void xmlTextWriterStartDocumentCallback(void *ctx);
Daniel Veillardab69f362004-02-17 11:40:32 +0000110static int xmlTextWriterWriteIndent(xmlTextWriterPtr writer);
Daniel Veillard500a1de2004-03-22 15:22:58 +0000111static int
112 xmlTextWriterHandleStateDependencies(xmlTextWriterPtr writer,
113 xmlTextWriterStackEntry * p);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000114
115/**
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000116 * xmlWriterErrMsg:
117 * @ctxt: a writer context
118 * @error: the error number
119 * @msg: the error message
120 *
121 * Handle a writer error
122 */
123static void
124xmlWriterErrMsg(xmlTextWriterPtr ctxt, xmlParserErrors error,
125 const char *msg)
126{
127 if (ctxt != NULL) {
128 __xmlRaiseError(NULL, NULL, NULL, ctxt->ctxt,
129 NULL, XML_FROM_WRITER, error, XML_ERR_FATAL,
130 NULL, 0, NULL, NULL, NULL, 0, 0, msg);
131 } else {
132 __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_WRITER, error,
133 XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, 0, 0, msg);
134 }
135}
136
137/**
138 * xmlWriterErrMsgInt:
139 * @ctxt: a writer context
140 * @error: the error number
141 * @msg: the error message
142 * @val: an int
143 *
144 * Handle a writer error
145 */
146static void
147xmlWriterErrMsgInt(xmlTextWriterPtr ctxt, xmlParserErrors error,
148 const char *msg, int val)
149{
150 if (ctxt != NULL) {
151 __xmlRaiseError(NULL, NULL, NULL, ctxt->ctxt,
152 NULL, XML_FROM_WRITER, error, XML_ERR_FATAL,
153 NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
154 } else {
155 __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_WRITER, error,
156 XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
157 }
158}
159
160/**
Daniel Veillard1d211e22003-10-20 22:32:39 +0000161 * xmlNewTextWriter:
162 * @out: an xmlOutputBufferPtr
163 *
164 * Create a new xmlNewTextWriter structure using an xmlOutputBufferPtr
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000165 * NOTE: the @out parameter will be deallocated when the writer is closed
166 * (if the call succeed.)
Daniel Veillard1d211e22003-10-20 22:32:39 +0000167 *
168 * Returns the new xmlTextWriterPtr or NULL in case of error
169 */
170xmlTextWriterPtr
171xmlNewTextWriter(xmlOutputBufferPtr out)
172{
173 xmlTextWriterPtr ret;
174
175 ret = (xmlTextWriterPtr) xmlMalloc(sizeof(xmlTextWriter));
176 if (ret == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000177 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000178 "xmlNewTextWriter : out of memory!\n");
179 return NULL;
180 }
181 memset(ret, 0, (size_t) sizeof(xmlTextWriter));
182
183 ret->nodes = xmlListCreate((xmlListDeallocator)
184 xmlFreeTextWriterStackEntry,
185 (xmlListDataCompare)
186 xmlCmpTextWriterStackEntry);
187 if (ret->nodes == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000188 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000189 "xmlNewTextWriter : out of memory!\n");
190 xmlFree(ret);
191 return NULL;
192 }
193
194 ret->nsstack = xmlListCreate((xmlListDeallocator)
195 xmlFreeTextWriterNsStackEntry,
196 (xmlListDataCompare)
197 xmlCmpTextWriterNsStackEntry);
198 if (ret->nsstack == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000199 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000200 "xmlNewTextWriter : out of memory!\n");
Daniel Veillard500a1de2004-03-22 15:22:58 +0000201 xmlListDelete(ret->nodes);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000202 xmlFree(ret);
203 return NULL;
204 }
205
206 ret->out = out;
Daniel Veillardab69f362004-02-17 11:40:32 +0000207 ret->ichar = xmlStrdup(BAD_CAST " ");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000208 ret->qchar = '"';
209
Daniel Veillard500a1de2004-03-22 15:22:58 +0000210 if (!ret->ichar) {
211 xmlListDelete(ret->nodes);
212 xmlListDelete(ret->nsstack);
213 xmlFree(ret);
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000214 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000215 "xmlNewTextWriter : out of memory!\n");
Daniel Veillardab69f362004-02-17 11:40:32 +0000216 return NULL;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000217 }
Daniel Veillarda521d282004-11-09 14:59:59 +0000218 ret->no_doc_free = 0;
Daniel Veillardab69f362004-02-17 11:40:32 +0000219
Daniel Veillard1d211e22003-10-20 22:32:39 +0000220 return ret;
221}
222
223/**
224 * xmlNewTextWriterFilename:
225 * @uri: the URI of the resource for the output
226 * @compression: compress the output?
227 *
228 * Create a new xmlNewTextWriter structure with @uri as output
229 *
230 * Returns the new xmlTextWriterPtr or NULL in case of error
231 */
232xmlTextWriterPtr
233xmlNewTextWriterFilename(const char *uri, int compression)
234{
235 xmlTextWriterPtr ret;
236 xmlOutputBufferPtr out;
237
238 out = xmlOutputBufferCreateFilename(uri, NULL, compression);
239 if (out == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000240 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000241 "xmlNewTextWriterFilename : out of memory!\n");
242 return NULL;
243 }
244
245 ret = xmlNewTextWriter(out);
246 if (ret == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000247 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000248 "xmlNewTextWriterFilename : out of memory!\n");
249 xmlOutputBufferClose(out);
250 return NULL;
251 }
252
Daniel Veillard2cca4462004-01-02 20:04:23 +0000253 ret->indent = 0;
254 ret->doindent = 0;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000255 return ret;
256}
257
258/**
259 * xmlNewTextWriterMemory:
260 * @buf: xmlBufferPtr
261 * @compression: compress the output?
262 *
263 * Create a new xmlNewTextWriter structure with @buf as output
264 * TODO: handle compression
265 *
266 * Returns the new xmlTextWriterPtr or NULL in case of error
267 */
268xmlTextWriterPtr
269xmlNewTextWriterMemory(xmlBufferPtr buf, int compression ATTRIBUTE_UNUSED)
270{
271 xmlTextWriterPtr ret;
272 xmlOutputBufferPtr out;
273
274/*::todo handle compression */
Rob Richardsa44f2342005-11-09 18:03:45 +0000275 out = xmlOutputBufferCreateBuffer(buf, NULL);
276
Daniel Veillard1d211e22003-10-20 22:32:39 +0000277 if (out == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000278 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000279 "xmlNewTextWriterMemory : out of memory!\n");
280 return NULL;
281 }
282
283 ret = xmlNewTextWriter(out);
284 if (ret == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000285 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000286 "xmlNewTextWriterMemory : out of memory!\n");
287 xmlOutputBufferClose(out);
288 return NULL;
289 }
290
291 return ret;
292}
293
294/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000295 * xmlNewTextWriterPushParser:
296 * @ctxt: xmlParserCtxtPtr to hold the new XML document tree
297 * @compression: compress the output?
298 *
299 * Create a new xmlNewTextWriter structure with @ctxt as output
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000300 * NOTE: the @ctxt context will be freed with the resulting writer
301 * (if the call succeeds).
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000302 * TODO: handle compression
303 *
304 * Returns the new xmlTextWriterPtr or NULL in case of error
305 */
306xmlTextWriterPtr
Daniel Veillard1d913862003-11-21 00:28:39 +0000307xmlNewTextWriterPushParser(xmlParserCtxtPtr ctxt,
308 int compression ATTRIBUTE_UNUSED)
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000309{
310 xmlTextWriterPtr ret;
311 xmlOutputBufferPtr out;
312
Daniel Veillard500a1de2004-03-22 15:22:58 +0000313 if (ctxt == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000314 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000315 "xmlNewTextWriterPushParser : invalid context!\n");
316 return NULL;
317 }
318
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000319 out = xmlOutputBufferCreateIO((xmlOutputWriteCallback)
320 xmlTextWriterWriteDocCallback,
321 (xmlOutputCloseCallback)
322 xmlTextWriterCloseDocCallback,
323 (void *) ctxt, NULL);
324 if (out == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000325 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000326 "xmlNewTextWriterPushParser : error at xmlOutputBufferCreateIO!\n");
327 return NULL;
328 }
329
330 ret = xmlNewTextWriter(out);
331 if (ret == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000332 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000333 "xmlNewTextWriterPushParser : error at xmlNewTextWriter!\n");
334 xmlOutputBufferClose(out);
335 return NULL;
336 }
337
Daniel Veillard20c5e782004-01-21 09:57:31 +0000338 ret->ctxt = ctxt;
339
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000340 return ret;
341}
342
343/**
344 * xmlNewTextWriterDoc:
345 * @doc: address of a xmlDocPtr to hold the new XML document tree
346 * @compression: compress the output?
347 *
348 * Create a new xmlNewTextWriter structure with @*doc as output
349 *
350 * Returns the new xmlTextWriterPtr or NULL in case of error
351 */
352xmlTextWriterPtr
353xmlNewTextWriterDoc(xmlDocPtr * doc, int compression)
354{
355 xmlTextWriterPtr ret;
356 xmlSAXHandler saxHandler;
357 xmlParserCtxtPtr ctxt;
358
359 memset(&saxHandler, '\0', sizeof(saxHandler));
360 xmlSAX2InitDefaultSAXHandler(&saxHandler, 1);
361 saxHandler.startDocument = xmlTextWriterStartDocumentCallback;
362 saxHandler.startElement = xmlSAX2StartElement;
363 saxHandler.endElement = xmlSAX2EndElement;
364
365 ctxt = xmlCreatePushParserCtxt(&saxHandler, NULL, NULL, 0, NULL);
366 if (ctxt == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000367 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000368 "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\n");
369 return NULL;
370 }
Daniel Veillard03a53c32004-10-26 16:06:51 +0000371 /*
372 * For some reason this seems to completely break if node names
373 * are interned.
374 */
375 ctxt->dictNames = 0;
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000376
Daniel Veillard1d913862003-11-21 00:28:39 +0000377 ctxt->myDoc = xmlNewDoc(BAD_CAST XML_DEFAULT_VERSION);
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000378 if (ctxt->myDoc == NULL) {
379 xmlFreeParserCtxt(ctxt);
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000380 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000381 "xmlNewTextWriterDoc : error at xmlNewDoc!\n");
382 return NULL;
383 }
384
385 ret = xmlNewTextWriterPushParser(ctxt, compression);
386 if (ret == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000387 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000388 "xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n");
389 return NULL;
390 }
391
Daniel Veillard500a1de2004-03-22 15:22:58 +0000392 xmlSetDocCompressMode(ctxt->myDoc, compression);
393
Daniel Veillarda521d282004-11-09 14:59:59 +0000394 if (doc != NULL) {
Daniel Veillard500a1de2004-03-22 15:22:58 +0000395 *doc = ctxt->myDoc;
Daniel Veillarda521d282004-11-09 14:59:59 +0000396 ret->no_doc_free = 1;
397 }
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000398
399 return ret;
400}
401
402/**
403 * xmlNewTextWriterTree:
404 * @doc: xmlDocPtr
405 * @node: xmlNodePtr or NULL for doc->children
406 * @compression: compress the output?
407 *
408 * Create a new xmlNewTextWriter structure with @doc as output
409 * starting at @node
410 *
411 * Returns the new xmlTextWriterPtr or NULL in case of error
412 */
413xmlTextWriterPtr
414xmlNewTextWriterTree(xmlDocPtr doc, xmlNodePtr node, int compression)
415{
416 xmlTextWriterPtr ret;
417 xmlSAXHandler saxHandler;
418 xmlParserCtxtPtr ctxt;
419
420 if (doc == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000421 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000422 "xmlNewTextWriterTree : invalid document tree!\n");
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000423 return NULL;
424 }
425
426 memset(&saxHandler, '\0', sizeof(saxHandler));
427 xmlSAX2InitDefaultSAXHandler(&saxHandler, 1);
428 saxHandler.startDocument = xmlTextWriterStartDocumentCallback;
429 saxHandler.startElement = xmlSAX2StartElement;
430 saxHandler.endElement = xmlSAX2EndElement;
431
432 ctxt = xmlCreatePushParserCtxt(&saxHandler, NULL, NULL, 0, NULL);
433 if (ctxt == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000434 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000435 "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\n");
436 return NULL;
437 }
Daniel Veillard03a53c32004-10-26 16:06:51 +0000438 /*
439 * For some reason this seems to completely break if node names
440 * are interned.
441 */
442 ctxt->dictNames = 0;
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000443
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000444 ret = xmlNewTextWriterPushParser(ctxt, compression);
445 if (ret == NULL) {
Daniel Veillard500a1de2004-03-22 15:22:58 +0000446 xmlFreeParserCtxt(ctxt);
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000447 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000448 "xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n");
449 return NULL;
450 }
451
Daniel Veillard500a1de2004-03-22 15:22:58 +0000452 ctxt->myDoc = doc;
453 ctxt->node = node;
Daniel Veillarda521d282004-11-09 14:59:59 +0000454 ret->no_doc_free = 1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000455
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000456 xmlSetDocCompressMode(doc, compression);
457
458 return ret;
459}
460
461/**
Daniel Veillard1d211e22003-10-20 22:32:39 +0000462 * xmlFreeTextWriter:
463 * @writer: the xmlTextWriterPtr
464 *
465 * Deallocate all the resources associated to the writer
466 */
467void
468xmlFreeTextWriter(xmlTextWriterPtr writer)
469{
470 if (writer == NULL)
471 return;
472
473 if (writer->out != NULL)
474 xmlOutputBufferClose(writer->out);
475
476 if (writer->nodes != NULL)
477 xmlListDelete(writer->nodes);
478
479 if (writer->nsstack != NULL)
480 xmlListDelete(writer->nsstack);
481
Daniel Veillarda521d282004-11-09 14:59:59 +0000482 if (writer->ctxt != NULL) {
483 if ((writer->ctxt->myDoc != NULL) && (writer->no_doc_free == 0)) {
484 xmlFreeDoc(writer->ctxt->myDoc);
485 writer->ctxt->myDoc = NULL;
486 }
Daniel Veillard20c5e782004-01-21 09:57:31 +0000487 xmlFreeParserCtxt(writer->ctxt);
Daniel Veillarda521d282004-11-09 14:59:59 +0000488 }
Daniel Veillard20c5e782004-01-21 09:57:31 +0000489
Daniel Veillard4773df22004-01-23 13:15:13 +0000490 if (writer->ichar != NULL)
491 xmlFree(writer->ichar);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000492 xmlFree(writer);
493}
494
495/**
496 * xmlTextWriterStartDocument:
497 * @writer: the xmlTextWriterPtr
498 * @version: the xml version ("1.0") or NULL for default ("1.0")
499 * @encoding: the encoding or NULL for default
500 * @standalone: "yes" or "no" or NULL for default
501 *
502 * Start a new xml document
503 *
504 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
505 */
506int
507xmlTextWriterStartDocument(xmlTextWriterPtr writer, const char *version,
508 const char *encoding, const char *standalone)
509{
510 int count;
511 int sum;
512 xmlLinkPtr lk;
513 xmlCharEncodingHandlerPtr encoder;
514
Daniel Veillard500a1de2004-03-22 15:22:58 +0000515 if ((writer == NULL) || (writer->out == NULL)) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000516 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000517 "xmlTextWriterStartDocument : invalid writer!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000518 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000519 }
Daniel Veillard1d211e22003-10-20 22:32:39 +0000520
521 lk = xmlListFront(writer->nodes);
522 if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000523 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000524 "xmlTextWriterStartDocument : not allowed in this context!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000525 return -1;
526 }
527
528 encoder = NULL;
529 if (encoding != NULL) {
530 encoder = xmlFindCharEncodingHandler(encoding);
531 if (encoder == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000532 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000533 "xmlTextWriterStartDocument : out of memory!\n");
534 return -1;
535 }
536 }
537
538 writer->out->encoder = encoder;
539 if (encoder != NULL) {
540 writer->out->conv = xmlBufferCreateSize(4000);
541 xmlCharEncOutFunc(encoder, writer->out->conv, NULL);
542 } else
543 writer->out->conv = NULL;
544
545 sum = 0;
546 count = xmlOutputBufferWriteString(writer->out, "<?xml version=");
547 if (count < 0)
548 return -1;
549 sum += count;
550 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
551 if (count < 0)
552 return -1;
553 sum += count;
554 if (version != 0)
555 count = xmlOutputBufferWriteString(writer->out, version);
556 else
557 count = xmlOutputBufferWriteString(writer->out, "1.0");
558 if (count < 0)
559 return -1;
560 sum += count;
561 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
562 if (count < 0)
563 return -1;
564 sum += count;
565 if (writer->out->encoder != 0) {
566 count = xmlOutputBufferWriteString(writer->out, " encoding=");
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 count =
575 xmlOutputBufferWriteString(writer->out,
576 writer->out->encoder->name);
577 if (count < 0)
578 return -1;
579 sum += count;
580 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
581 if (count < 0)
582 return -1;
583 sum += count;
584 }
585
586 if (standalone != 0) {
587 count = xmlOutputBufferWriteString(writer->out, " standalone=");
588 if (count < 0)
589 return -1;
590 sum += count;
591 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
592 if (count < 0)
593 return -1;
594 sum += count;
595 count = xmlOutputBufferWriteString(writer->out, standalone);
596 if (count < 0)
597 return -1;
598 sum += count;
599 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
600 if (count < 0)
601 return -1;
602 sum += count;
603 }
604
605 count = xmlOutputBufferWriteString(writer->out, "?>\n");
606 if (count < 0)
607 return -1;
608 sum += count;
609
610 return sum;
611}
612
613/**
614 * xmlTextWriterEndDocument:
615 * @writer: the xmlTextWriterPtr
616 *
617 * End an xml document. All open elements are closed
618 *
619 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
620 */
621int
622xmlTextWriterEndDocument(xmlTextWriterPtr writer)
623{
624 int count;
625 int sum;
626 xmlLinkPtr lk;
627 xmlTextWriterStackEntry *p;
628
Daniel Veillard500a1de2004-03-22 15:22:58 +0000629 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000630 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000631 "xmlTextWriterEndDocument : invalid writer!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000632 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000633 }
Daniel Veillard1d211e22003-10-20 22:32:39 +0000634
635 sum = 0;
636 while ((lk = xmlListFront(writer->nodes)) != NULL) {
637 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
638 if (p == 0)
639 break;
640 switch (p->state) {
641 case XML_TEXTWRITER_NAME:
642 case XML_TEXTWRITER_ATTRIBUTE:
643 case XML_TEXTWRITER_TEXT:
644 count = xmlTextWriterEndElement(writer);
645 if (count < 0)
646 return -1;
647 sum += count;
648 break;
649 case XML_TEXTWRITER_PI:
650 case XML_TEXTWRITER_PI_TEXT:
651 count = xmlTextWriterEndPI(writer);
652 if (count < 0)
653 return -1;
654 sum += count;
655 break;
656 case XML_TEXTWRITER_CDATA:
657 count = xmlTextWriterEndCDATA(writer);
658 if (count < 0)
659 return -1;
660 sum += count;
661 break;
662 case XML_TEXTWRITER_DTD:
Daniel Veillard500a1de2004-03-22 15:22:58 +0000663 case XML_TEXTWRITER_DTD_TEXT:
664 case XML_TEXTWRITER_DTD_ELEM:
665 case XML_TEXTWRITER_DTD_ELEM_TEXT:
666 case XML_TEXTWRITER_DTD_ATTL:
667 case XML_TEXTWRITER_DTD_ATTL_TEXT:
668 case XML_TEXTWRITER_DTD_ENTY:
669 case XML_TEXTWRITER_DTD_ENTY_TEXT:
670 case XML_TEXTWRITER_DTD_PENT:
Daniel Veillard1d211e22003-10-20 22:32:39 +0000671 count = xmlTextWriterEndDTD(writer);
672 if (count < 0)
673 return -1;
674 sum += count;
675 break;
Daniel Veillardab69f362004-02-17 11:40:32 +0000676 case XML_TEXTWRITER_COMMENT:
677 count = xmlTextWriterEndComment(writer);
678 if (count < 0)
679 return -1;
680 sum += count;
681 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000682 default:
Daniel Veillardab69f362004-02-17 11:40:32 +0000683 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000684 }
685 }
686
Daniel Veillard2cca4462004-01-02 20:04:23 +0000687 if (!writer->indent) {
Daniel Veillardab69f362004-02-17 11:40:32 +0000688 count = xmlOutputBufferWriteString(writer->out, "\n");
689 if (count < 0)
690 return -1;
691 sum += count;
692 }
693 return sum;
694}
695
Daniel Veillardab69f362004-02-17 11:40:32 +0000696/**
697 * xmlTextWriterStartComment:
698 * @writer: the xmlTextWriterPtr
699 *
700 * Start an xml comment.
701 *
702 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
703 */
704int
705xmlTextWriterStartComment(xmlTextWriterPtr writer)
706{
707 int count;
708 int sum;
709 xmlLinkPtr lk;
710 xmlTextWriterStackEntry *p;
711
Daniel Veillard500a1de2004-03-22 15:22:58 +0000712 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000713 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000714 "xmlTextWriterStartComment : invalid writer!\n");
Daniel Veillardab69f362004-02-17 11:40:32 +0000715 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000716 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000717
718 sum = 0;
719 lk = xmlListFront(writer->nodes);
720 if (lk != 0) {
721 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
722 if (p != 0) {
723 switch (p->state) {
724 case XML_TEXTWRITER_TEXT:
725 case XML_TEXTWRITER_NONE:
726 break;
727 case XML_TEXTWRITER_NAME:
728 count = xmlOutputBufferWriteString(writer->out, ">");
729 if (count < 0)
730 return -1;
731 sum += count;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000732 if (writer->indent) {
733 count =
734 xmlOutputBufferWriteString(writer->out, "\n");
735 if (count < 0)
736 return -1;
737 sum += count;
738 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000739 p->state = XML_TEXTWRITER_TEXT;
740 break;
741 default:
742 return -1;
743 }
744 }
745 }
746
747 p = (xmlTextWriterStackEntry *)
748 xmlMalloc(sizeof(xmlTextWriterStackEntry));
749 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000750 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillardab69f362004-02-17 11:40:32 +0000751 "xmlTextWriterStartElement : out of memory!\n");
752 return -1;
753 }
754
Daniel Veillard75e389d2005-07-29 22:02:24 +0000755 p->name = NULL;
Daniel Veillardab69f362004-02-17 11:40:32 +0000756 p->state = XML_TEXTWRITER_COMMENT;
757
758 xmlListPushFront(writer->nodes, p);
759
760 if (writer->indent) {
Daniel Veillardab69f362004-02-17 11:40:32 +0000761 count = xmlTextWriterWriteIndent(writer);
762 if (count < 0)
763 return -1;
764 sum += count;
765 }
766
767 count = xmlOutputBufferWriteString(writer->out, "<!--");
768 if (count < 0)
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000769 return -1;
770 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +0000771
772 return sum;
773}
774
775/**
776 * xmlTextWriterEndComment:
777 * @writer: the xmlTextWriterPtr
778 *
779 * End the current xml coment.
780 *
781 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
782 */
783int
784xmlTextWriterEndComment(xmlTextWriterPtr writer)
785{
786 int count;
787 int sum;
788 xmlLinkPtr lk;
789 xmlTextWriterStackEntry *p;
790
Daniel Veillard500a1de2004-03-22 15:22:58 +0000791 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000792 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000793 "xmlTextWriterEndComment : invalid writer!\n");
Daniel Veillardab69f362004-02-17 11:40:32 +0000794 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000795 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000796
797 lk = xmlListFront(writer->nodes);
Daniel Veillard500a1de2004-03-22 15:22:58 +0000798 if (lk == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000799 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000800 "xmlTextWriterEndComment : not allowed in this context!\n");
Daniel Veillardab69f362004-02-17 11:40:32 +0000801 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000802 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000803
804 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
805 if (p == 0)
806 return -1;
807
808 sum = 0;
809 switch (p->state) {
810 case XML_TEXTWRITER_COMMENT:
811 count = xmlOutputBufferWriteString(writer->out, "-->");
812 if (count < 0)
813 return -1;
814 sum += count;
815 break;
816 default:
817 return -1;
Daniel Veillard2cca4462004-01-02 20:04:23 +0000818 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000819
820 if (writer->indent) {
821 count = xmlOutputBufferWriteString(writer->out, "\n");
822 if (count < 0)
823 return -1;
824 sum += count;
825 }
826
827 xmlListPopFront(writer->nodes);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000828 return sum;
829}
830
831/**
832 * xmlTextWriterWriteFormatComment:
833 * @writer: the xmlTextWriterPtr
834 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +0000835 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +0000836 *
837 * Write an xml comment.
838 *
839 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
840 */
Daniel Veillardffa3c742005-07-21 13:24:09 +0000841int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +0000842xmlTextWriterWriteFormatComment(xmlTextWriterPtr writer,
843 const char *format, ...)
844{
845 int rc;
846 va_list ap;
847
848 va_start(ap, format);
849
850 rc = xmlTextWriterWriteVFormatComment(writer, format, ap);
851
852 va_end(ap);
853 return rc;
854}
855
856/**
857 * xmlTextWriterWriteVFormatComment:
858 * @writer: the xmlTextWriterPtr
859 * @format: format string (see printf)
860 * @argptr: pointer to the first member of the variable argument list.
861 *
862 * Write an xml comment.
863 *
864 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
865 */
866int
867xmlTextWriterWriteVFormatComment(xmlTextWriterPtr writer,
868 const char *format, va_list argptr)
869{
870 int rc;
871 xmlChar *buf;
872
Daniel Veillard500a1de2004-03-22 15:22:58 +0000873 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000874 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000875 "xmlTextWriterWriteVFormatComment : invalid writer!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000876 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000877 }
Daniel Veillard1d211e22003-10-20 22:32:39 +0000878
879 buf = xmlTextWriterVSprintf(format, argptr);
880 if (buf == 0)
881 return 0;
882
883 rc = xmlTextWriterWriteComment(writer, buf);
884
885 xmlFree(buf);
886 return rc;
887}
888
889/**
890 * xmlTextWriterWriteComment:
891 * @writer: the xmlTextWriterPtr
892 * @content: comment string
893 *
894 * Write an xml comment.
895 *
896 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
897 */
898int
899xmlTextWriterWriteComment(xmlTextWriterPtr writer, const xmlChar * content)
900{
901 int count;
902 int sum;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000903
904 sum = 0;
Daniel Veillardab69f362004-02-17 11:40:32 +0000905 count = xmlTextWriterStartComment(writer);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000906 if (count < 0)
907 return -1;
908 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +0000909 count = xmlTextWriterWriteString(writer, content);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000910 if (count < 0)
911 return -1;
912 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +0000913 count = xmlTextWriterEndComment(writer);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000914 if (count < 0)
915 return -1;
916 sum += count;
917
918 return sum;
919}
920
921/**
922 * xmlTextWriterStartElement:
923 * @writer: the xmlTextWriterPtr
924 * @name: element name
925 *
926 * Start an xml element.
927 *
928 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
929 */
930int
931xmlTextWriterStartElement(xmlTextWriterPtr writer, const xmlChar * name)
932{
933 int count;
934 int sum;
935 xmlLinkPtr lk;
936 xmlTextWriterStackEntry *p;
937
938 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
939 return -1;
940
941 sum = 0;
942 lk = xmlListFront(writer->nodes);
943 if (lk != 0) {
944 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
945 if (p != 0) {
946 switch (p->state) {
947 case XML_TEXTWRITER_PI:
948 case XML_TEXTWRITER_PI_TEXT:
949 return -1;
950 case XML_TEXTWRITER_NONE:
951 break;
Daniel Veillard614fdc12005-02-23 14:05:37 +0000952 case XML_TEXTWRITER_ATTRIBUTE:
953 count = xmlTextWriterEndAttribute(writer);
954 if (count < 0)
955 return -1;
956 sum += count;
957 /* fallthrough */
Daniel Veillard1d211e22003-10-20 22:32:39 +0000958 case XML_TEXTWRITER_NAME:
959 count = xmlOutputBufferWriteString(writer->out, ">");
960 if (count < 0)
961 return -1;
962 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +0000963 if (writer->indent)
964 count =
965 xmlOutputBufferWriteString(writer->out, "\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000966 p->state = XML_TEXTWRITER_TEXT;
967 break;
Daniel Veillardab69f362004-02-17 11:40:32 +0000968 default:
969 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000970 }
971 }
972 }
973
974 p = (xmlTextWriterStackEntry *)
975 xmlMalloc(sizeof(xmlTextWriterStackEntry));
976 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000977 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000978 "xmlTextWriterStartElement : out of memory!\n");
979 return -1;
980 }
981
982 p->name = xmlStrdup(name);
983 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000984 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000985 "xmlTextWriterStartElement : out of memory!\n");
986 xmlFree(p);
987 return -1;
988 }
989 p->state = XML_TEXTWRITER_NAME;
990
991 xmlListPushFront(writer->nodes, p);
992
Daniel Veillardab69f362004-02-17 11:40:32 +0000993 if (writer->indent) {
994 count = xmlTextWriterWriteIndent(writer);
995 sum += count;
Daniel Veillard2cca4462004-01-02 20:04:23 +0000996 }
997
Daniel Veillard1d211e22003-10-20 22:32:39 +0000998 count = xmlOutputBufferWriteString(writer->out, "<");
999 if (count < 0)
1000 return -1;
1001 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00001002 count =
1003 xmlOutputBufferWriteString(writer->out, (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001004 if (count < 0)
1005 return -1;
1006 sum += count;
1007
1008 return sum;
1009}
1010
1011/**
1012 * xmlTextWriterStartElementNS:
1013 * @writer: the xmlTextWriterPtr
1014 * @prefix: namespace prefix or NULL
1015 * @name: element local name
1016 * @namespaceURI: namespace URI or NULL
1017 *
1018 * Start an xml element with namespace support.
1019 *
1020 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1021 */
1022int
1023xmlTextWriterStartElementNS(xmlTextWriterPtr writer,
1024 const xmlChar * prefix, const xmlChar * name,
1025 const xmlChar * namespaceURI)
1026{
1027 int count;
1028 int sum;
1029 xmlChar *buf;
1030
1031 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1032 return -1;
1033
Daniel Veillard75e389d2005-07-29 22:02:24 +00001034 buf = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001035 if (prefix != 0) {
1036 buf = xmlStrdup(prefix);
1037 buf = xmlStrcat(buf, BAD_CAST ":");
1038 }
1039 buf = xmlStrcat(buf, name);
1040
1041 sum = 0;
1042 count = xmlTextWriterStartElement(writer, buf);
1043 xmlFree(buf);
1044 if (count < 0)
1045 return -1;
1046 sum += count;
1047
1048 if (namespaceURI != 0) {
1049 buf = xmlStrdup(BAD_CAST "xmlns");
1050 if (prefix != 0) {
1051 buf = xmlStrcat(buf, BAD_CAST ":");
1052 buf = xmlStrcat(buf, prefix);
1053 }
1054
1055 count = xmlTextWriterWriteAttribute(writer, buf, namespaceURI);
1056 xmlFree(buf);
1057 if (count < 0)
1058 return -1;
1059 sum += count;
1060 }
1061
1062 return sum;
1063}
1064
1065/**
1066 * xmlTextWriterEndElement:
1067 * @writer: the xmlTextWriterPtr
1068 *
1069 * End the current xml element.
1070 *
1071 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1072 */
1073int
1074xmlTextWriterEndElement(xmlTextWriterPtr writer)
1075{
1076 int count;
1077 int sum;
1078 xmlLinkPtr lk;
1079 xmlTextWriterStackEntry *p;
1080
1081 if (writer == NULL)
1082 return -1;
1083
1084 lk = xmlListFront(writer->nodes);
1085 if (lk == 0)
1086 return -1;
1087
1088 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1089 if (p == 0)
1090 return -1;
1091
1092 sum = 0;
1093 switch (p->state) {
1094 case XML_TEXTWRITER_ATTRIBUTE:
1095 count = xmlTextWriterEndAttribute(writer);
1096 if (count < 0)
1097 return -1;
1098 sum += count;
1099 /* fallthrough */
1100 case XML_TEXTWRITER_NAME:
Daniel Veillardab69f362004-02-17 11:40:32 +00001101 if (writer->indent) /* next element needs indent */
1102 writer->doindent = 1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001103 count = xmlOutputBufferWriteString(writer->out, "/>");
1104 if (count < 0)
1105 return -1;
1106 sum += count;
1107 break;
1108 case XML_TEXTWRITER_TEXT:
Daniel Veillardab69f362004-02-17 11:40:32 +00001109 if ((writer->indent) && (writer->doindent)) {
1110 count = xmlTextWriterWriteIndent(writer);
1111 sum += count;
1112 writer->doindent = 1;
1113 } else
1114 writer->doindent = 1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001115 count = xmlOutputBufferWriteString(writer->out, "</");
1116 if (count < 0)
1117 return -1;
1118 sum += count;
1119 count = xmlOutputBufferWriteString(writer->out,
Daniel Veillardab69f362004-02-17 11:40:32 +00001120 (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001121 if (count < 0)
1122 return -1;
1123 sum += count;
1124 count = xmlOutputBufferWriteString(writer->out, ">");
1125 if (count < 0)
1126 return -1;
1127 sum += count;
1128 break;
1129 default:
1130 return -1;
1131 }
1132
Daniel Veillard2cca4462004-01-02 20:04:23 +00001133 if (writer->indent) {
Daniel Veillardab69f362004-02-17 11:40:32 +00001134 count = xmlOutputBufferWriteString(writer->out, "\n");
1135 sum += count;
Daniel Veillard2cca4462004-01-02 20:04:23 +00001136 }
1137
Daniel Veillard1d211e22003-10-20 22:32:39 +00001138 xmlListPopFront(writer->nodes);
1139 return sum;
1140}
1141
1142/**
1143 * xmlTextWriterFullEndElement:
1144 * @writer: the xmlTextWriterPtr
1145 *
1146 * End the current xml element. Writes an end tag even if the element is empty
1147 *
1148 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1149 */
1150int
1151xmlTextWriterFullEndElement(xmlTextWriterPtr writer)
1152{
1153 int count;
1154 int sum;
1155 xmlLinkPtr lk;
1156 xmlTextWriterStackEntry *p;
1157
1158 if (writer == NULL)
1159 return -1;
1160
1161 lk = xmlListFront(writer->nodes);
1162 if (lk == 0)
1163 return -1;
1164
1165 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1166 if (p == 0)
1167 return -1;
1168
1169 sum = 0;
1170 switch (p->state) {
1171 case XML_TEXTWRITER_ATTRIBUTE:
1172 count = xmlTextWriterEndAttribute(writer);
1173 if (count < 0)
1174 return -1;
1175 sum += count;
1176 /* fallthrough */
1177 case XML_TEXTWRITER_NAME:
1178 count = xmlOutputBufferWriteString(writer->out, ">");
1179 if (count < 0)
1180 return -1;
1181 sum += count;
1182 /* fallthrough */
1183 case XML_TEXTWRITER_TEXT:
1184 count = xmlOutputBufferWriteString(writer->out, "</");
1185 if (count < 0)
1186 return -1;
1187 sum += count;
1188 count = xmlOutputBufferWriteString(writer->out,
Daniel Veillardab69f362004-02-17 11:40:32 +00001189 (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001190 if (count < 0)
1191 return -1;
1192 sum += count;
1193 count = xmlOutputBufferWriteString(writer->out, ">");
1194 if (count < 0)
1195 return -1;
1196 sum += count;
1197 break;
1198 default:
1199 return -1;
1200 }
1201
1202 xmlListPopFront(writer->nodes);
1203 return sum;
1204}
1205
1206/**
1207 * xmlTextWriterWriteFormatRaw:
1208 * @writer: the xmlTextWriterPtr
1209 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001210 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001211 *
1212 * Write a formatted raw xml text.
1213 *
1214 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1215 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00001216int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00001217xmlTextWriterWriteFormatRaw(xmlTextWriterPtr writer, const char *format,
1218 ...)
1219{
1220 int rc;
1221 va_list ap;
1222
1223 va_start(ap, format);
1224
1225 rc = xmlTextWriterWriteVFormatRaw(writer, format, ap);
1226
1227 va_end(ap);
1228 return rc;
1229}
1230
1231/**
1232 * xmlTextWriterWriteVFormatRaw:
1233 * @writer: the xmlTextWriterPtr
1234 * @format: format string (see printf)
1235 * @argptr: pointer to the first member of the variable argument list.
1236 *
1237 * Write a formatted raw xml text.
1238 *
1239 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1240 */
1241int
1242xmlTextWriterWriteVFormatRaw(xmlTextWriterPtr writer, const char *format,
1243 va_list argptr)
1244{
1245 int rc;
1246 xmlChar *buf;
1247
1248 if (writer == NULL)
1249 return -1;
1250
1251 buf = xmlTextWriterVSprintf(format, argptr);
1252 if (buf == 0)
1253 return 0;
1254
1255 rc = xmlTextWriterWriteRaw(writer, buf);
1256
1257 xmlFree(buf);
1258 return rc;
1259}
1260
1261/**
Daniel Veillard1e906612003-12-05 14:57:46 +00001262 * xmlTextWriterWriteRawLen:
Daniel Veillard1d211e22003-10-20 22:32:39 +00001263 * @writer: the xmlTextWriterPtr
1264 * @content: text string
1265 * @len: length of the text string
1266 *
1267 * Write an xml text.
1268 * TODO: what about entities and special chars??
1269 *
1270 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1271 */
1272int
1273xmlTextWriterWriteRawLen(xmlTextWriterPtr writer, const xmlChar * content,
1274 int len)
1275{
1276 int count;
1277 int sum;
1278 xmlLinkPtr lk;
1279 xmlTextWriterStackEntry *p;
1280
Daniel Veillard500a1de2004-03-22 15:22:58 +00001281 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00001282 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00001283 "xmlTextWriterWriteRawLen : invalid writer!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +00001284 return -1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001285 }
1286
Daniel Veillarde43cc572004-11-03 11:50:29 +00001287 if ((content == NULL) || (len < 0)) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00001288 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00001289 "xmlTextWriterWriteRawLen : invalid content!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +00001290 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001291 }
1292
1293 sum = 0;
1294 lk = xmlListFront(writer->nodes);
1295 if (lk != 0) {
1296 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1297 count = xmlTextWriterHandleStateDependencies(writer, p);
1298 if (count < 0)
1299 return -1;
1300 sum += count;
1301 }
1302
1303 if (writer->indent)
1304 writer->doindent = 0;
1305
1306 if (content != NULL) {
1307 count =
1308 xmlOutputBufferWrite(writer->out, len, (const char *) content);
1309 if (count < 0)
1310 return -1;
1311 sum += count;
1312 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001313
1314 return sum;
1315}
1316
1317/**
1318 * xmlTextWriterWriteRaw:
1319 * @writer: the xmlTextWriterPtr
1320 * @content: text string
1321 *
1322 * Write a raw xml text.
1323 *
1324 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1325 */
1326int
1327xmlTextWriterWriteRaw(xmlTextWriterPtr writer, const xmlChar * content)
1328{
1329 return xmlTextWriterWriteRawLen(writer, content, xmlStrlen(content));
1330}
1331
1332/**
1333 * xmlTextWriterWriteFormatString:
1334 * @writer: the xmlTextWriterPtr
1335 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001336 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001337 *
1338 * Write a formatted xml text.
1339 *
1340 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1341 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00001342int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00001343xmlTextWriterWriteFormatString(xmlTextWriterPtr writer, const char *format,
1344 ...)
1345{
1346 int rc;
1347 va_list ap;
1348
Daniel Veillarde43cc572004-11-03 11:50:29 +00001349 if ((writer == NULL) || (format == NULL))
1350 return -1;
1351
Daniel Veillard1d211e22003-10-20 22:32:39 +00001352 va_start(ap, format);
1353
1354 rc = xmlTextWriterWriteVFormatString(writer, format, ap);
1355
1356 va_end(ap);
1357 return rc;
1358}
1359
1360/**
1361 * xmlTextWriterWriteVFormatString:
1362 * @writer: the xmlTextWriterPtr
1363 * @format: format string (see printf)
1364 * @argptr: pointer to the first member of the variable argument list.
1365 *
1366 * Write a formatted xml text.
1367 *
1368 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1369 */
1370int
1371xmlTextWriterWriteVFormatString(xmlTextWriterPtr writer,
1372 const char *format, va_list argptr)
1373{
1374 int rc;
1375 xmlChar *buf;
1376
Daniel Veillarde43cc572004-11-03 11:50:29 +00001377 if ((writer == NULL) || (format == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00001378 return -1;
1379
1380 buf = xmlTextWriterVSprintf(format, argptr);
1381 if (buf == 0)
1382 return 0;
1383
1384 rc = xmlTextWriterWriteString(writer, buf);
1385
1386 xmlFree(buf);
1387 return rc;
1388}
1389
1390/**
1391 * xmlTextWriterWriteString:
1392 * @writer: the xmlTextWriterPtr
1393 * @content: text string
1394 *
1395 * Write an xml text.
1396 *
1397 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1398 */
1399int
1400xmlTextWriterWriteString(xmlTextWriterPtr writer, const xmlChar * content)
1401{
Daniel Veillard500a1de2004-03-22 15:22:58 +00001402 int count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001403 int sum;
1404 xmlLinkPtr lk;
1405 xmlTextWriterStackEntry *p;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001406 xmlChar *buf;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001407
Daniel Veillarde43cc572004-11-03 11:50:29 +00001408 if ((writer == NULL) || (content == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00001409 return -1;
1410
Daniel Veillard1d211e22003-10-20 22:32:39 +00001411 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001412 buf = (xmlChar *) content;
1413 lk = xmlListFront(writer->nodes);
1414 if (lk != 0) {
1415 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1416 if (p != 0) {
1417 switch (p->state) {
1418 case XML_TEXTWRITER_NAME:
1419 case XML_TEXTWRITER_TEXT:
Daniel Veillard62040be2004-05-17 03:17:26 +00001420#if 0
1421 buf = NULL;
1422 xmlOutputBufferWriteEscape(writer->out, content, NULL);
1423#endif
Daniel Veillard500a1de2004-03-22 15:22:58 +00001424 buf = xmlEncodeSpecialChars(NULL, content);
1425 break;
1426 case XML_TEXTWRITER_ATTRIBUTE:
1427 buf = NULL;
1428 xmlAttrSerializeTxtContent(writer->out->buffer, NULL,
1429 NULL, content);
1430 break;
William M. Brack87640d52004-04-17 14:58:15 +00001431 default:
1432 break;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001433 }
1434 }
1435 }
1436
1437 if (buf != NULL) {
1438 count = xmlTextWriterWriteRaw(writer, buf);
1439 if (count < 0)
Daniel Veillard1d211e22003-10-20 22:32:39 +00001440 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001441 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001442
Daniel Veillard500a1de2004-03-22 15:22:58 +00001443 if (buf != content) /* buf was allocated by us, so free it */
1444 xmlFree(buf);
William M. Bracka9c612c2004-02-01 10:04:05 +00001445 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001446
1447 return sum;
1448}
1449
1450/**
1451 * xmlOutputBufferWriteBase64:
1452 * @out: the xmlOutputBufferPtr
1453 * @data: binary data
1454 * @len: the number of bytes to encode
1455 *
1456 * Write base64 encoded data to an xmlOutputBuffer.
1457 * Adapted from John Walker's base64.c (http://www.fourmilab.ch/).
1458 *
1459 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1460 */
1461static int
1462xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len,
1463 const unsigned char *data)
1464{
1465 static unsigned char dtable[64] =
William M. Brack47a31882004-09-11 16:09:09 +00001466 {'A','B','C','D','E','F','G','H','I','J','K','L','M',
1467 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
1468 'a','b','c','d','e','f','g','h','i','j','k','l','m',
1469 'n','o','p','q','r','s','t','u','v','w','x','y','z',
1470 '0','1','2','3','4','5','6','7','8','9','+','/'};
1471
Daniel Veillard1d211e22003-10-20 22:32:39 +00001472 int i;
1473 int linelen;
1474 int count;
1475 int sum;
1476
Daniel Veillarde43cc572004-11-03 11:50:29 +00001477 if ((out == NULL) || (len < 0) || (data == NULL))
1478 return(-1);
1479
Daniel Veillard1d211e22003-10-20 22:32:39 +00001480 linelen = 0;
1481 sum = 0;
1482
1483 i = 0;
1484 while (1) {
1485 unsigned char igroup[3];
1486 unsigned char ogroup[4];
1487 int c;
1488 int n;
1489
1490 igroup[0] = igroup[1] = igroup[2] = 0;
1491 for (n = 0; n < 3 && i < len; n++, i++) {
1492 c = data[i];
1493 igroup[n] = (unsigned char) c;
1494 }
1495
1496 if (n > 0) {
1497 ogroup[0] = dtable[igroup[0] >> 2];
1498 ogroup[1] = dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)];
1499 ogroup[2] =
1500 dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)];
1501 ogroup[3] = dtable[igroup[2] & 0x3F];
1502
1503 if (n < 3) {
1504 ogroup[3] = '=';
1505 if (n < 2) {
1506 ogroup[2] = '=';
1507 }
1508 }
1509
1510 if (linelen >= B64LINELEN) {
1511 count = xmlOutputBufferWrite(out, 2, B64CRLF);
1512 if (count == -1)
1513 return -1;
1514 sum += count;
1515 linelen = 0;
1516 }
1517 count = xmlOutputBufferWrite(out, 4, (const char *) ogroup);
1518 if (count == -1)
1519 return -1;
1520 sum += count;
1521
1522 linelen += 4;
1523 }
Daniel Veillard929714b2003-10-22 12:34:36 +00001524
1525 if (i >= len)
1526 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001527 }
1528
Daniel Veillard1d211e22003-10-20 22:32:39 +00001529 return sum;
1530}
1531
1532/**
1533 * xmlTextWriterWriteBase64:
1534 * @writer: the xmlTextWriterPtr
1535 * @data: binary data
1536 * @start: the position within the data of the first byte to encode
1537 * @len: the number of bytes to encode
1538 *
1539 * Write an base64 encoded xml text.
1540 *
1541 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1542 */
1543int
Daniel Veillardab69f362004-02-17 11:40:32 +00001544xmlTextWriterWriteBase64(xmlTextWriterPtr writer, const char *data,
Daniel Veillard1d211e22003-10-20 22:32:39 +00001545 int start, int len)
1546{
1547 int count;
1548 int sum;
1549 xmlLinkPtr lk;
1550 xmlTextWriterStackEntry *p;
1551
Daniel Veillarde43cc572004-11-03 11:50:29 +00001552 if ((writer == NULL) || (data == NULL) || (start < 0) || (len < 0))
Daniel Veillard1d211e22003-10-20 22:32:39 +00001553 return -1;
1554
Daniel Veillard1d211e22003-10-20 22:32:39 +00001555 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001556 lk = xmlListFront(writer->nodes);
1557 if (lk != 0) {
1558 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1559 if (p != 0) {
1560 count = xmlTextWriterHandleStateDependencies(writer, p);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001561 if (count < 0)
1562 return -1;
1563 sum += count;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001564 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001565 }
1566
Daniel Veillardab69f362004-02-17 11:40:32 +00001567 if (writer->indent)
1568 writer->doindent = 0;
1569
Daniel Veillard1d211e22003-10-20 22:32:39 +00001570 count =
1571 xmlOutputBufferWriteBase64(writer->out, len,
1572 (unsigned char *) data + start);
1573 if (count < 0)
1574 return -1;
1575 sum += count;
1576
1577 return sum;
1578}
1579
1580/**
1581 * xmlOutputBufferWriteBinHex:
1582 * @out: the xmlOutputBufferPtr
1583 * @data: binary data
1584 * @len: the number of bytes to encode
1585 *
1586 * Write hqx encoded data to an xmlOutputBuffer.
1587 * ::todo
1588 *
William M. Brack47a31882004-09-11 16:09:09 +00001589 * Returns the bytes written (may be 0 because of buffering)
1590 * or -1 in case of error
Daniel Veillard1d211e22003-10-20 22:32:39 +00001591 */
1592static int
Daniel Veillardab69f362004-02-17 11:40:32 +00001593xmlOutputBufferWriteBinHex(xmlOutputBufferPtr out,
1594 int len, const unsigned char *data)
Daniel Veillard1d211e22003-10-20 22:32:39 +00001595{
Daniel Veillardab69f362004-02-17 11:40:32 +00001596 int count;
1597 int sum;
William M. Brack47a31882004-09-11 16:09:09 +00001598 static char hex[16] =
1599 {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
Daniel Veillardab69f362004-02-17 11:40:32 +00001600 int i;
1601
Daniel Veillarde43cc572004-11-03 11:50:29 +00001602 if ((out == NULL) || (data == NULL) || (len < 0)) {
Daniel Veillardab69f362004-02-17 11:40:32 +00001603 return -1;
1604 }
1605
1606 sum = 0;
1607 for (i = 0; i < len; i++) {
1608 count =
1609 xmlOutputBufferWrite(out, 1,
1610 (const char *) &hex[data[i] >> 4]);
1611 if (count == -1)
1612 return -1;
1613 sum += count;
1614 count =
1615 xmlOutputBufferWrite(out, 1,
1616 (const char *) &hex[data[i] & 0xF]);
1617 if (count == -1)
1618 return -1;
1619 sum += count;
1620 }
1621
1622 return sum;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001623}
1624
1625/**
1626 * xmlTextWriterWriteBinHex:
1627 * @writer: the xmlTextWriterPtr
1628 * @data: binary data
1629 * @start: the position within the data of the first byte to encode
1630 * @len: the number of bytes to encode
1631 *
1632 * Write a BinHex encoded xml text.
1633 *
1634 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1635 */
1636int
Daniel Veillardab69f362004-02-17 11:40:32 +00001637xmlTextWriterWriteBinHex(xmlTextWriterPtr writer, const char *data,
Daniel Veillard1d211e22003-10-20 22:32:39 +00001638 int start, int len)
1639{
1640 int count;
1641 int sum;
1642 xmlLinkPtr lk;
1643 xmlTextWriterStackEntry *p;
1644
Daniel Veillarde43cc572004-11-03 11:50:29 +00001645 if ((writer == NULL) || (data == NULL) || (start < 0) || (len < 0))
Daniel Veillard1d211e22003-10-20 22:32:39 +00001646 return -1;
1647
Daniel Veillard1d211e22003-10-20 22:32:39 +00001648 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001649 lk = xmlListFront(writer->nodes);
1650 if (lk != 0) {
1651 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1652 if (p != 0) {
1653 count = xmlTextWriterHandleStateDependencies(writer, p);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001654 if (count < 0)
1655 return -1;
1656 sum += count;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001657 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001658 }
1659
Daniel Veillardab69f362004-02-17 11:40:32 +00001660 if (writer->indent)
1661 writer->doindent = 0;
1662
Daniel Veillard1d211e22003-10-20 22:32:39 +00001663 count =
1664 xmlOutputBufferWriteBinHex(writer->out, len,
1665 (unsigned char *) data + start);
1666 if (count < 0)
1667 return -1;
1668 sum += count;
1669
1670 return sum;
1671}
1672
1673/**
1674 * xmlTextWriterStartAttribute:
1675 * @writer: the xmlTextWriterPtr
1676 * @name: element name
1677 *
1678 * Start an xml attribute.
1679 *
1680 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1681 */
1682int
1683xmlTextWriterStartAttribute(xmlTextWriterPtr writer, const xmlChar * name)
1684{
1685 int count;
1686 int sum;
1687 xmlLinkPtr lk;
1688 xmlTextWriterStackEntry *p;
1689
1690 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1691 return -1;
1692
1693 sum = 0;
1694 lk = xmlListFront(writer->nodes);
1695 if (lk == 0)
1696 return -1;
1697
1698 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1699 if (p == 0)
1700 return -1;
1701
1702 switch (p->state) {
1703 case XML_TEXTWRITER_ATTRIBUTE:
1704 count = xmlTextWriterEndAttribute(writer);
1705 if (count < 0)
1706 return -1;
1707 sum += count;
1708 /* fallthrough */
1709 case XML_TEXTWRITER_NAME:
1710 count = xmlOutputBufferWriteString(writer->out, " ");
1711 if (count < 0)
1712 return -1;
1713 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00001714 count =
1715 xmlOutputBufferWriteString(writer->out,
1716 (const char *) name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001717 if (count < 0)
1718 return -1;
1719 sum += count;
1720 count = xmlOutputBufferWriteString(writer->out, "=");
1721 if (count < 0)
1722 return -1;
1723 sum += count;
1724 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
1725 if (count < 0)
1726 return -1;
1727 sum += count;
1728 p->state = XML_TEXTWRITER_ATTRIBUTE;
1729 break;
1730 default:
1731 return -1;
1732 }
1733
1734 return sum;
1735}
1736
1737/**
1738 * xmlTextWriterStartAttributeNS:
1739 * @writer: the xmlTextWriterPtr
1740 * @prefix: namespace prefix or NULL
1741 * @name: element local name
1742 * @namespaceURI: namespace URI or NULL
1743 *
1744 * Start an xml attribute with namespace support.
1745 *
1746 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1747 */
1748int
1749xmlTextWriterStartAttributeNS(xmlTextWriterPtr writer,
1750 const xmlChar * prefix, const xmlChar * name,
1751 const xmlChar * namespaceURI)
1752{
1753 int count;
1754 int sum;
1755 xmlChar *buf;
1756 xmlTextWriterNsStackEntry *p;
1757
1758 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1759 return -1;
1760
Daniel Veillard75e389d2005-07-29 22:02:24 +00001761 buf = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001762 if (prefix != 0) {
1763 buf = xmlStrdup(prefix);
1764 buf = xmlStrcat(buf, BAD_CAST ":");
1765 }
1766 buf = xmlStrcat(buf, name);
1767
1768 sum = 0;
1769 count = xmlTextWriterStartAttribute(writer, buf);
1770 xmlFree(buf);
1771 if (count < 0)
1772 return -1;
1773 sum += count;
1774
1775 if (namespaceURI != 0) {
1776 buf = xmlStrdup(BAD_CAST "xmlns");
1777 if (prefix != 0) {
1778 buf = xmlStrcat(buf, BAD_CAST ":");
1779 buf = xmlStrcat(buf, prefix);
1780 }
1781
1782 p = (xmlTextWriterNsStackEntry *)
1783 xmlMalloc(sizeof(xmlTextWriterNsStackEntry));
1784 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00001785 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00001786 "xmlTextWriterStartAttributeNS : out of memory!\n");
1787 return -1;
1788 }
1789
1790 p->prefix = buf;
1791 p->uri = xmlStrdup(namespaceURI);
1792 if (p->uri == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00001793 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00001794 "xmlTextWriterStartAttributeNS : out of memory!\n");
1795 xmlFree(p);
1796 return -1;
1797 }
1798 p->elem = xmlListFront(writer->nodes);
1799
1800 xmlListPushFront(writer->nsstack, p);
1801 }
1802
1803 return sum;
1804}
1805
1806/**
1807 * xmlTextWriterEndAttribute:
1808 * @writer: the xmlTextWriterPtr
1809 *
1810 * End the current xml element.
1811 *
1812 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1813 */
1814int
1815xmlTextWriterEndAttribute(xmlTextWriterPtr writer)
1816{
1817 int count;
1818 int sum;
1819 xmlLinkPtr lk;
1820 xmlTextWriterStackEntry *p;
1821 xmlTextWriterNsStackEntry *np;
1822
1823 if (writer == NULL)
1824 return -1;
1825
1826 lk = xmlListFront(writer->nodes);
1827 if (lk == 0) {
1828 xmlListDelete(writer->nsstack);
Daniel Veillarde43cc572004-11-03 11:50:29 +00001829 writer->nsstack = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001830 return -1;
1831 }
1832
1833 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1834 if (p == 0) {
1835 xmlListDelete(writer->nsstack);
Daniel Veillarde43cc572004-11-03 11:50:29 +00001836 writer->nsstack = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001837 return -1;
1838 }
1839
1840 sum = 0;
1841 switch (p->state) {
1842 case XML_TEXTWRITER_ATTRIBUTE:
1843 p->state = XML_TEXTWRITER_NAME;
1844
1845 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
1846 if (count < 0) {
1847 xmlListDelete(writer->nsstack);
Daniel Veillarde43cc572004-11-03 11:50:29 +00001848 writer->nsstack = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001849 return -1;
1850 }
1851 sum += count;
1852
1853 while (!xmlListEmpty(writer->nsstack)) {
Daniel Veillardbd8fb0a2005-02-21 13:49:46 +00001854 xmlChar *namespaceURI = NULL;
1855 xmlChar *prefix = NULL;
1856
Daniel Veillard1d211e22003-10-20 22:32:39 +00001857 lk = xmlListFront(writer->nsstack);
1858 np = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
Daniel Veillardbd8fb0a2005-02-21 13:49:46 +00001859
1860 if (np != 0) {
Daniel Veillard614fdc12005-02-23 14:05:37 +00001861 namespaceURI = xmlStrdup(np->uri);
1862 prefix = xmlStrdup(np->prefix);
Daniel Veillardbd8fb0a2005-02-21 13:49:46 +00001863 }
1864
1865 xmlListPopFront(writer->nsstack);
1866
Daniel Veillard1d211e22003-10-20 22:32:39 +00001867 if (np != 0) {
1868 count =
Daniel Veillardbd8fb0a2005-02-21 13:49:46 +00001869 xmlTextWriterWriteAttribute(writer, prefix,
1870 namespaceURI);
1871 xmlFree(namespaceURI);
1872 xmlFree(prefix);
1873
Daniel Veillard1d211e22003-10-20 22:32:39 +00001874 if (count < 0) {
1875 xmlListDelete(writer->nsstack);
Daniel Veillarde43cc572004-11-03 11:50:29 +00001876 writer->nsstack = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001877 return -1;
1878 }
1879 sum += count;
1880 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001881 }
1882 break;
1883
1884 default:
1885 xmlListClear(writer->nsstack);
1886 return -1;
1887 }
1888
1889 return sum;
1890}
1891
1892/**
1893 * xmlTextWriterWriteFormatAttribute:
1894 * @writer: the xmlTextWriterPtr
1895 * @name: attribute name
1896 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001897 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001898 *
1899 * Write a formatted xml attribute.
1900 *
1901 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1902 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00001903int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00001904xmlTextWriterWriteFormatAttribute(xmlTextWriterPtr writer,
1905 const xmlChar * name, const char *format,
1906 ...)
1907{
1908 int rc;
1909 va_list ap;
1910
1911 va_start(ap, format);
1912
1913 rc = xmlTextWriterWriteVFormatAttribute(writer, name, format, ap);
1914
1915 va_end(ap);
1916 return rc;
1917}
1918
1919/**
1920 * xmlTextWriterWriteVFormatAttribute:
1921 * @writer: the xmlTextWriterPtr
1922 * @name: attribute name
1923 * @format: format string (see printf)
1924 * @argptr: pointer to the first member of the variable argument list.
1925 *
1926 * Write a formatted xml attribute.
1927 *
1928 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1929 */
1930int
1931xmlTextWriterWriteVFormatAttribute(xmlTextWriterPtr writer,
1932 const xmlChar * name,
1933 const char *format, va_list argptr)
1934{
1935 int rc;
1936 xmlChar *buf;
1937
1938 if (writer == NULL)
1939 return -1;
1940
1941 buf = xmlTextWriterVSprintf(format, argptr);
1942 if (buf == 0)
1943 return 0;
1944
1945 rc = xmlTextWriterWriteAttribute(writer, name, buf);
1946
1947 xmlFree(buf);
1948 return rc;
1949}
1950
1951/**
1952 * xmlTextWriterWriteAttribute:
1953 * @writer: the xmlTextWriterPtr
1954 * @name: attribute name
1955 * @content: attribute content
1956 *
1957 * Write an xml attribute.
1958 *
1959 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1960 */
1961int
1962xmlTextWriterWriteAttribute(xmlTextWriterPtr writer, const xmlChar * name,
1963 const xmlChar * content)
1964{
1965 int count;
1966 int sum;
1967
1968 sum = 0;
1969 count = xmlTextWriterStartAttribute(writer, name);
1970 if (count < 0)
1971 return -1;
1972 sum += count;
1973 count = xmlTextWriterWriteString(writer, content);
1974 if (count < 0)
1975 return -1;
1976 sum += count;
1977 count = xmlTextWriterEndAttribute(writer);
1978 if (count < 0)
1979 return -1;
1980 sum += count;
1981
1982 return sum;
1983}
1984
1985/**
1986 * xmlTextWriterWriteFormatAttributeNS:
1987 * @writer: the xmlTextWriterPtr
1988 * @prefix: namespace prefix
1989 * @name: attribute local name
1990 * @namespaceURI: namespace URI
1991 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001992 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001993 *
1994 * Write a formatted xml attribute.with namespace support
1995 *
1996 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1997 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00001998int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00001999xmlTextWriterWriteFormatAttributeNS(xmlTextWriterPtr writer,
2000 const xmlChar * prefix,
2001 const xmlChar * name,
2002 const xmlChar * namespaceURI,
2003 const char *format, ...)
2004{
2005 int rc;
2006 va_list ap;
2007
2008 va_start(ap, format);
2009
2010 rc = xmlTextWriterWriteVFormatAttributeNS(writer, prefix, name,
2011 namespaceURI, format, ap);
2012
2013 va_end(ap);
2014 return rc;
2015}
2016
2017/**
2018 * xmlTextWriterWriteVFormatAttributeNS:
2019 * @writer: the xmlTextWriterPtr
2020 * @prefix: namespace prefix
2021 * @name: attribute local name
2022 * @namespaceURI: namespace URI
2023 * @format: format string (see printf)
2024 * @argptr: pointer to the first member of the variable argument list.
2025 *
2026 * Write a formatted xml attribute.with namespace support
2027 *
2028 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2029 */
2030int
2031xmlTextWriterWriteVFormatAttributeNS(xmlTextWriterPtr writer,
2032 const xmlChar * prefix,
2033 const xmlChar * name,
2034 const xmlChar * namespaceURI,
2035 const char *format, va_list argptr)
2036{
2037 int rc;
2038 xmlChar *buf;
2039
2040 if (writer == NULL)
2041 return -1;
2042
2043 buf = xmlTextWriterVSprintf(format, argptr);
2044 if (buf == 0)
2045 return 0;
2046
2047 rc = xmlTextWriterWriteAttributeNS(writer, prefix, name, namespaceURI,
2048 buf);
2049
2050 xmlFree(buf);
2051 return rc;
2052}
2053
2054/**
2055 * xmlTextWriterWriteAttributeNS:
2056 * @writer: the xmlTextWriterPtr
2057 * @prefix: namespace prefix
2058 * @name: attribute local name
2059 * @namespaceURI: namespace URI
2060 * @content: attribute content
2061 *
2062 * Write an xml attribute.
2063 *
2064 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2065 */
2066int
2067xmlTextWriterWriteAttributeNS(xmlTextWriterPtr writer,
2068 const xmlChar * prefix, const xmlChar * name,
2069 const xmlChar * namespaceURI,
2070 const xmlChar * content)
2071{
2072 int count;
2073 int sum;
2074 xmlChar *buf;
2075
2076 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
2077 return -1;
2078
Daniel Veillard75e389d2005-07-29 22:02:24 +00002079 buf = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002080 if (prefix != NULL) {
2081 buf = xmlStrdup(prefix);
2082 buf = xmlStrcat(buf, BAD_CAST ":");
2083 }
2084 buf = xmlStrcat(buf, name);
2085
2086 sum = 0;
2087 count = xmlTextWriterWriteAttribute(writer, buf, content);
2088 xmlFree(buf);
2089 if (count < 0)
2090 return -1;
2091 sum += count;
2092
2093 if (namespaceURI != NULL) {
Daniel Veillard75e389d2005-07-29 22:02:24 +00002094 buf = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002095 buf = xmlStrdup(BAD_CAST "xmlns");
2096 if (prefix != NULL) {
2097 buf = xmlStrcat(buf, BAD_CAST ":");
2098 buf = xmlStrcat(buf, prefix);
2099 }
2100 count = xmlTextWriterWriteAttribute(writer, buf, namespaceURI);
2101 xmlFree(buf);
2102 if (count < 0)
2103 return -1;
2104 sum += count;
2105 }
2106 return sum;
2107}
2108
2109/**
2110 * xmlTextWriterWriteFormatElement:
2111 * @writer: the xmlTextWriterPtr
2112 * @name: element name
2113 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002114 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002115 *
2116 * Write a formatted xml element.
2117 *
2118 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2119 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00002120int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00002121xmlTextWriterWriteFormatElement(xmlTextWriterPtr writer,
2122 const xmlChar * name, const char *format,
2123 ...)
2124{
2125 int rc;
2126 va_list ap;
2127
2128 va_start(ap, format);
2129
2130 rc = xmlTextWriterWriteVFormatElement(writer, name, format, ap);
2131
2132 va_end(ap);
2133 return rc;
2134}
2135
2136/**
2137 * xmlTextWriterWriteVFormatElement:
2138 * @writer: the xmlTextWriterPtr
2139 * @name: element name
2140 * @format: format string (see printf)
2141 * @argptr: pointer to the first member of the variable argument list.
2142 *
2143 * Write a formatted xml element.
2144 *
2145 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2146 */
2147int
2148xmlTextWriterWriteVFormatElement(xmlTextWriterPtr writer,
2149 const xmlChar * name, const char *format,
2150 va_list argptr)
2151{
2152 int rc;
2153 xmlChar *buf;
2154
2155 if (writer == NULL)
2156 return -1;
2157
2158 buf = xmlTextWriterVSprintf(format, argptr);
2159 if (buf == 0)
2160 return 0;
2161
2162 rc = xmlTextWriterWriteElement(writer, name, buf);
2163
2164 xmlFree(buf);
2165 return rc;
2166}
2167
2168/**
2169 * xmlTextWriterWriteElement:
2170 * @writer: the xmlTextWriterPtr
2171 * @name: element name
2172 * @content: element content
2173 *
2174 * Write an xml element.
2175 *
2176 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2177 */
2178int
2179xmlTextWriterWriteElement(xmlTextWriterPtr writer, const xmlChar * name,
2180 const xmlChar * content)
2181{
2182 int count;
2183 int sum;
2184
2185 sum = 0;
2186 count = xmlTextWriterStartElement(writer, name);
2187 if (count == -1)
2188 return -1;
2189 sum += count;
2190 count = xmlTextWriterWriteString(writer, content);
2191 if (count == -1)
2192 return -1;
2193 sum += count;
2194 count = xmlTextWriterEndElement(writer);
2195 if (count == -1)
2196 return -1;
2197 sum += count;
2198
2199 return sum;
2200}
2201
2202/**
2203 * xmlTextWriterWriteFormatElementNS:
2204 * @writer: the xmlTextWriterPtr
2205 * @prefix: namespace prefix
2206 * @name: element local name
2207 * @namespaceURI: namespace URI
2208 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002209 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002210 *
2211 * Write a formatted xml element with namespace support.
2212 *
2213 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2214 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00002215int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00002216xmlTextWriterWriteFormatElementNS(xmlTextWriterPtr writer,
2217 const xmlChar * prefix,
2218 const xmlChar * name,
2219 const xmlChar * namespaceURI,
2220 const char *format, ...)
2221{
2222 int rc;
2223 va_list ap;
2224
2225 va_start(ap, format);
2226
2227 rc = xmlTextWriterWriteVFormatElementNS(writer, prefix, name,
2228 namespaceURI, format, ap);
2229
2230 va_end(ap);
2231 return rc;
2232}
2233
2234/**
2235 * xmlTextWriterWriteVFormatElementNS:
2236 * @writer: the xmlTextWriterPtr
2237 * @prefix: namespace prefix
2238 * @name: element local name
2239 * @namespaceURI: namespace URI
2240 * @format: format string (see printf)
2241 * @argptr: pointer to the first member of the variable argument list.
2242 *
2243 * Write a formatted xml element with namespace support.
2244 *
2245 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2246 */
2247int
2248xmlTextWriterWriteVFormatElementNS(xmlTextWriterPtr writer,
2249 const xmlChar * prefix,
2250 const xmlChar * name,
2251 const xmlChar * namespaceURI,
2252 const char *format, va_list argptr)
2253{
2254 int rc;
2255 xmlChar *buf;
2256
2257 if (writer == NULL)
2258 return -1;
2259
2260 buf = xmlTextWriterVSprintf(format, argptr);
2261 if (buf == 0)
2262 return 0;
2263
2264 rc = xmlTextWriterWriteElementNS(writer, prefix, name, namespaceURI,
2265 buf);
2266
2267 xmlFree(buf);
2268 return rc;
2269}
2270
2271/**
2272 * xmlTextWriterWriteElementNS:
2273 * @writer: the xmlTextWriterPtr
2274 * @prefix: namespace prefix
2275 * @name: element local name
2276 * @namespaceURI: namespace URI
2277 * @content: element content
2278 *
2279 * Write an xml element with namespace support.
2280 *
2281 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2282 */
2283int
2284xmlTextWriterWriteElementNS(xmlTextWriterPtr writer,
2285 const xmlChar * prefix, const xmlChar * name,
2286 const xmlChar * namespaceURI,
2287 const xmlChar * content)
2288{
2289 int count;
2290 int sum;
2291
2292 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
2293 return -1;
2294
2295 sum = 0;
2296 count =
2297 xmlTextWriterStartElementNS(writer, prefix, name, namespaceURI);
2298 if (count < 0)
2299 return -1;
2300 sum += count;
2301 count = xmlTextWriterWriteString(writer, content);
2302 if (count == -1)
2303 return -1;
2304 sum += count;
2305 count = xmlTextWriterEndElement(writer);
2306 if (count == -1)
2307 return -1;
2308 sum += count;
2309
2310 return sum;
2311}
2312
2313/**
2314 * xmlTextWriterStartPI:
2315 * @writer: the xmlTextWriterPtr
2316 * @target: PI target
2317 *
2318 * Start an xml PI.
2319 *
2320 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2321 */
2322int
2323xmlTextWriterStartPI(xmlTextWriterPtr writer, const xmlChar * target)
2324{
2325 int count;
2326 int sum;
2327 xmlLinkPtr lk;
2328 xmlTextWriterStackEntry *p;
2329
2330 if ((writer == NULL) || (target == NULL) || (*target == '\0'))
2331 return -1;
2332
2333 if (xmlStrcasecmp(target, (const xmlChar *) "xml") == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002334 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002335 "xmlTextWriterStartPI : target name [Xx][Mm][Ll] is reserved for xml standardization!\n");
2336 return -1;
2337 }
2338
2339 sum = 0;
2340 lk = xmlListFront(writer->nodes);
2341 if (lk != 0) {
2342 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2343 if (p != 0) {
2344 switch (p->state) {
2345 case XML_TEXTWRITER_ATTRIBUTE:
2346 count = xmlTextWriterEndAttribute(writer);
2347 if (count < 0)
2348 return -1;
2349 sum += count;
2350 /* fallthrough */
2351 case XML_TEXTWRITER_NAME:
2352 count = xmlOutputBufferWriteString(writer->out, ">");
2353 if (count < 0)
2354 return -1;
2355 sum += count;
2356 p->state = XML_TEXTWRITER_TEXT;
2357 break;
Daniel Veillardab69f362004-02-17 11:40:32 +00002358 case XML_TEXTWRITER_NONE:
2359 case XML_TEXTWRITER_TEXT:
2360 case XML_TEXTWRITER_DTD:
2361 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002362 case XML_TEXTWRITER_PI:
2363 case XML_TEXTWRITER_PI_TEXT:
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002364 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002365 "xmlTextWriterStartPI : nested PI!\n");
2366 return -1;
2367 default:
2368 return -1;
2369 }
2370 }
2371 }
2372
2373 p = (xmlTextWriterStackEntry *)
2374 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2375 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002376 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002377 "xmlTextWriterStartPI : out of memory!\n");
2378 return -1;
2379 }
2380
2381 p->name = xmlStrdup(target);
2382 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002383 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002384 "xmlTextWriterStartPI : out of memory!\n");
2385 xmlFree(p);
2386 return -1;
2387 }
2388 p->state = XML_TEXTWRITER_PI;
2389
2390 xmlListPushFront(writer->nodes, p);
2391
2392 count = xmlOutputBufferWriteString(writer->out, "<?");
2393 if (count < 0)
2394 return -1;
2395 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002396 count =
2397 xmlOutputBufferWriteString(writer->out, (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002398 if (count < 0)
2399 return -1;
2400 sum += count;
2401
2402 return sum;
2403}
2404
2405/**
2406 * xmlTextWriterEndPI:
2407 * @writer: the xmlTextWriterPtr
2408 *
2409 * End the current xml PI.
2410 *
2411 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2412 */
2413int
2414xmlTextWriterEndPI(xmlTextWriterPtr writer)
2415{
2416 int count;
2417 int sum;
2418 xmlLinkPtr lk;
2419 xmlTextWriterStackEntry *p;
2420
2421 if (writer == NULL)
2422 return -1;
2423
2424 lk = xmlListFront(writer->nodes);
2425 if (lk == 0)
2426 return 0;
2427
2428 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2429 if (p == 0)
2430 return 0;
2431
2432 sum = 0;
2433 switch (p->state) {
2434 case XML_TEXTWRITER_PI:
2435 case XML_TEXTWRITER_PI_TEXT:
2436 count = xmlOutputBufferWriteString(writer->out, "?>");
2437 if (count < 0)
2438 return -1;
2439 sum += count;
2440 break;
2441 default:
2442 return -1;
2443 }
2444
Daniel Veillard02c1f232006-04-27 08:10:25 +00002445 if (writer->indent) {
2446 count = xmlOutputBufferWriteString(writer->out, "\n");
2447 if (count < 0)
2448 return -1;
2449 sum += count;
2450 }
2451
Daniel Veillard1d211e22003-10-20 22:32:39 +00002452 xmlListPopFront(writer->nodes);
2453 return sum;
2454}
2455
2456/**
2457 * xmlTextWriterWriteFormatPI:
2458 * @writer: the xmlTextWriterPtr
2459 * @target: PI target
2460 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002461 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002462 *
2463 * Write a formatted PI.
2464 *
2465 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2466 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00002467int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00002468xmlTextWriterWriteFormatPI(xmlTextWriterPtr writer, const xmlChar * target,
2469 const char *format, ...)
2470{
2471 int rc;
2472 va_list ap;
2473
2474 va_start(ap, format);
2475
2476 rc = xmlTextWriterWriteVFormatPI(writer, target, format, ap);
2477
2478 va_end(ap);
2479 return rc;
2480}
2481
2482/**
2483 * xmlTextWriterWriteVFormatPI:
2484 * @writer: the xmlTextWriterPtr
2485 * @target: PI target
2486 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002487 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00002488 *
2489 * Write a formatted xml PI.
2490 *
2491 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2492 */
2493int
2494xmlTextWriterWriteVFormatPI(xmlTextWriterPtr writer,
2495 const xmlChar * target, const char *format,
2496 va_list argptr)
2497{
2498 int rc;
2499 xmlChar *buf;
2500
2501 if (writer == NULL)
2502 return -1;
2503
2504 buf = xmlTextWriterVSprintf(format, argptr);
2505 if (buf == 0)
2506 return 0;
2507
2508 rc = xmlTextWriterWritePI(writer, target, buf);
2509
2510 xmlFree(buf);
2511 return rc;
2512}
2513
2514/**
2515 * xmlTextWriterWritePI:
2516 * @writer: the xmlTextWriterPtr
2517 * @target: PI target
2518 * @content: PI content
2519 *
2520 * Write an xml PI.
2521 *
2522 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2523 */
2524int
2525xmlTextWriterWritePI(xmlTextWriterPtr writer, const xmlChar * target,
2526 const xmlChar * content)
2527{
2528 int count;
2529 int sum;
2530
2531 sum = 0;
2532 count = xmlTextWriterStartPI(writer, target);
2533 if (count == -1)
2534 return -1;
2535 sum += count;
2536 if (content != 0) {
2537 count = xmlTextWriterWriteString(writer, content);
2538 if (count == -1)
2539 return -1;
2540 sum += count;
2541 }
2542 count = xmlTextWriterEndPI(writer);
2543 if (count == -1)
2544 return -1;
2545 sum += count;
2546
2547 return sum;
2548}
2549
2550/**
2551 * xmlTextWriterStartCDATA:
2552 * @writer: the xmlTextWriterPtr
2553 *
2554 * Start an xml CDATA section.
2555 *
2556 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2557 */
2558int
2559xmlTextWriterStartCDATA(xmlTextWriterPtr writer)
2560{
2561 int count;
2562 int sum;
2563 xmlLinkPtr lk;
2564 xmlTextWriterStackEntry *p;
2565
2566 if (writer == NULL)
2567 return -1;
2568
2569 sum = 0;
2570 lk = xmlListFront(writer->nodes);
2571 if (lk != 0) {
2572 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2573 if (p != 0) {
2574 switch (p->state) {
2575 case XML_TEXTWRITER_NONE:
2576 case XML_TEXTWRITER_PI:
2577 case XML_TEXTWRITER_PI_TEXT:
2578 break;
2579 case XML_TEXTWRITER_ATTRIBUTE:
2580 count = xmlTextWriterEndAttribute(writer);
2581 if (count < 0)
2582 return -1;
2583 sum += count;
2584 /* fallthrough */
2585 case XML_TEXTWRITER_NAME:
2586 count = xmlOutputBufferWriteString(writer->out, ">");
2587 if (count < 0)
2588 return -1;
2589 sum += count;
2590 p->state = XML_TEXTWRITER_TEXT;
2591 break;
2592 case XML_TEXTWRITER_CDATA:
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002593 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002594 "xmlTextWriterStartCDATA : CDATA not allowed in this context!\n");
2595 return -1;
2596 default:
2597 return -1;
2598 }
2599 }
2600 }
2601
2602 p = (xmlTextWriterStackEntry *)
2603 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2604 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002605 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002606 "xmlTextWriterStartCDATA : out of memory!\n");
2607 return -1;
2608 }
2609
Daniel Veillard75e389d2005-07-29 22:02:24 +00002610 p->name = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002611 p->state = XML_TEXTWRITER_CDATA;
2612
2613 xmlListPushFront(writer->nodes, p);
2614
2615 count = xmlOutputBufferWriteString(writer->out, "<![CDATA[");
2616 if (count < 0)
2617 return -1;
2618 sum += count;
2619
2620 return sum;
2621}
2622
2623/**
2624 * xmlTextWriterEndCDATA:
2625 * @writer: the xmlTextWriterPtr
2626 *
2627 * End an xml CDATA section.
2628 *
2629 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2630 */
2631int
2632xmlTextWriterEndCDATA(xmlTextWriterPtr writer)
2633{
2634 int count;
2635 int sum;
2636 xmlLinkPtr lk;
2637 xmlTextWriterStackEntry *p;
2638
2639 if (writer == NULL)
2640 return -1;
2641
2642 lk = xmlListFront(writer->nodes);
2643 if (lk == 0)
2644 return -1;
2645
2646 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2647 if (p == 0)
2648 return -1;
2649
2650 sum = 0;
2651 switch (p->state) {
2652 case XML_TEXTWRITER_CDATA:
2653 count = xmlOutputBufferWriteString(writer->out, "]]>");
2654 if (count < 0)
2655 return -1;
2656 sum += count;
2657 break;
2658 default:
2659 return -1;
2660 }
2661
2662 xmlListPopFront(writer->nodes);
2663 return sum;
2664}
2665
2666/**
2667 * xmlTextWriterWriteFormatCDATA:
2668 * @writer: the xmlTextWriterPtr
2669 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002670 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002671 *
2672 * Write a formatted xml CDATA.
2673 *
2674 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2675 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00002676int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00002677xmlTextWriterWriteFormatCDATA(xmlTextWriterPtr writer, const char *format,
2678 ...)
2679{
2680 int rc;
2681 va_list ap;
2682
2683 va_start(ap, format);
2684
2685 rc = xmlTextWriterWriteVFormatCDATA(writer, format, ap);
2686
2687 va_end(ap);
2688 return rc;
2689}
2690
2691/**
2692 * xmlTextWriterWriteVFormatCDATA:
2693 * @writer: the xmlTextWriterPtr
2694 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002695 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00002696 *
2697 * Write a formatted xml CDATA.
2698 *
2699 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2700 */
2701int
2702xmlTextWriterWriteVFormatCDATA(xmlTextWriterPtr writer, const char *format,
2703 va_list argptr)
2704{
2705 int rc;
2706 xmlChar *buf;
2707
2708 if (writer == NULL)
2709 return -1;
2710
2711 buf = xmlTextWriterVSprintf(format, argptr);
2712 if (buf == 0)
2713 return 0;
2714
2715 rc = xmlTextWriterWriteCDATA(writer, buf);
2716
2717 xmlFree(buf);
2718 return rc;
2719}
2720
2721/**
2722 * xmlTextWriterWriteCDATA:
2723 * @writer: the xmlTextWriterPtr
2724 * @content: CDATA content
2725 *
2726 * Write an xml CDATA.
2727 *
2728 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2729 */
2730int
2731xmlTextWriterWriteCDATA(xmlTextWriterPtr writer, const xmlChar * content)
2732{
2733 int count;
2734 int sum;
2735
2736 sum = 0;
2737 count = xmlTextWriterStartCDATA(writer);
2738 if (count == -1)
2739 return -1;
2740 sum += count;
2741 if (content != 0) {
2742 count = xmlTextWriterWriteString(writer, content);
2743 if (count == -1)
2744 return -1;
2745 sum += count;
2746 }
2747 count = xmlTextWriterEndCDATA(writer);
2748 if (count == -1)
2749 return -1;
2750 sum += count;
2751
2752 return sum;
2753}
2754
2755/**
2756 * xmlTextWriterStartDTD:
2757 * @writer: the xmlTextWriterPtr
2758 * @name: the name of the DTD
2759 * @pubid: the public identifier, which is an alternative to the system identifier
2760 * @sysid: the system identifier, which is the URI of the DTD
2761 *
2762 * Start an xml DTD.
2763 *
2764 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2765 */
2766int
2767xmlTextWriterStartDTD(xmlTextWriterPtr writer,
2768 const xmlChar * name,
2769 const xmlChar * pubid, const xmlChar * sysid)
2770{
2771 int count;
2772 int sum;
2773 xmlLinkPtr lk;
2774 xmlTextWriterStackEntry *p;
2775
2776 if (writer == NULL || name == NULL || *name == '\0')
2777 return -1;
2778
2779 sum = 0;
2780 lk = xmlListFront(writer->nodes);
Daniel Veillardab69f362004-02-17 11:40:32 +00002781 if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002782 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002783 "xmlTextWriterStartDTD : DTD allowed only in prolog!\n");
2784 return -1;
2785 }
2786
2787 p = (xmlTextWriterStackEntry *)
2788 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2789 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002790 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002791 "xmlTextWriterStartDTD : out of memory!\n");
2792 return -1;
2793 }
2794
2795 p->name = xmlStrdup(name);
2796 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002797 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002798 "xmlTextWriterStartDTD : out of memory!\n");
2799 xmlFree(p);
2800 return -1;
2801 }
2802 p->state = XML_TEXTWRITER_DTD;
2803
2804 xmlListPushFront(writer->nodes, p);
2805
2806 count = xmlOutputBufferWriteString(writer->out, "<!DOCTYPE ");
2807 if (count < 0)
2808 return -1;
2809 sum += count;
2810 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
2811 if (count < 0)
2812 return -1;
2813 sum += count;
2814
2815 if (pubid != 0) {
2816 if (sysid == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002817 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002818 "xmlTextWriterStartDTD : system identifier needed!\n");
2819 return -1;
2820 }
2821
Daniel Veillard500a1de2004-03-22 15:22:58 +00002822 if (writer->indent)
2823 count = xmlOutputBufferWrite(writer->out, 1, "\n");
2824 else
2825 count = xmlOutputBufferWrite(writer->out, 1, " ");
2826 if (count < 0)
2827 return -1;
2828 sum += count;
2829
2830 count = xmlOutputBufferWriteString(writer->out, "PUBLIC ");
2831 if (count < 0)
2832 return -1;
2833 sum += count;
2834
2835 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002836 if (count < 0)
2837 return -1;
2838 sum += count;
2839
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002840 count =
2841 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002842 if (count < 0)
2843 return -1;
2844 sum += count;
2845
Daniel Veillard500a1de2004-03-22 15:22:58 +00002846 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002847 if (count < 0)
2848 return -1;
2849 sum += count;
2850 }
2851
2852 if (sysid != 0) {
2853 if (pubid == 0) {
Daniel Veillard500a1de2004-03-22 15:22:58 +00002854 if (writer->indent)
2855 count = xmlOutputBufferWrite(writer->out, 1, "\n");
2856 else
2857 count = xmlOutputBufferWrite(writer->out, 1, " ");
2858 if (count < 0)
2859 return -1;
2860 sum += count;
2861 count = xmlOutputBufferWriteString(writer->out, "SYSTEM ");
2862 if (count < 0)
2863 return -1;
2864 sum += count;
Rob Richardsffe47fe2005-12-09 17:52:21 +00002865 } else {
2866 if (writer->indent)
Daniel Veillard500a1de2004-03-22 15:22:58 +00002867 count = xmlOutputBufferWriteString(writer->out, "\n ");
Rob Richardsffe47fe2005-12-09 17:52:21 +00002868 else
2869 count = xmlOutputBufferWrite(writer->out, 1, " ");
Daniel Veillard1d211e22003-10-20 22:32:39 +00002870 if (count < 0)
2871 return -1;
2872 sum += count;
2873 }
2874
Daniel Veillard500a1de2004-03-22 15:22:58 +00002875 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002876 if (count < 0)
2877 return -1;
2878 sum += count;
2879
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002880 count =
2881 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002882 if (count < 0)
2883 return -1;
2884 sum += count;
2885
Daniel Veillard500a1de2004-03-22 15:22:58 +00002886 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002887 if (count < 0)
2888 return -1;
2889 sum += count;
2890 }
2891
2892 return sum;
2893}
2894
2895/**
2896 * xmlTextWriterEndDTD:
2897 * @writer: the xmlTextWriterPtr
2898 *
2899 * End an xml DTD.
2900 *
2901 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2902 */
2903int
2904xmlTextWriterEndDTD(xmlTextWriterPtr writer)
2905{
Daniel Veillard500a1de2004-03-22 15:22:58 +00002906 int loop;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002907 int count;
2908 int sum;
2909 xmlLinkPtr lk;
2910 xmlTextWriterStackEntry *p;
2911
2912 if (writer == NULL)
2913 return -1;
2914
2915 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00002916 loop = 1;
2917 while (loop) {
2918 lk = xmlListFront(writer->nodes);
2919 if (lk == NULL)
Daniel Veillard1d211e22003-10-20 22:32:39 +00002920 break;
Daniel Veillard500a1de2004-03-22 15:22:58 +00002921 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2922 if (p == 0)
2923 break;
2924 switch (p->state) {
2925 case XML_TEXTWRITER_DTD_TEXT:
2926 count = xmlOutputBufferWriteString(writer->out, "]");
2927 if (count < 0)
2928 return -1;
2929 sum += count;
2930 /* fallthrough */
2931 case XML_TEXTWRITER_DTD:
2932 count = xmlOutputBufferWriteString(writer->out, ">");
2933
2934 if (writer->indent) {
2935 if (count < 0)
2936 return -1;
2937 sum += count;
2938 count = xmlOutputBufferWriteString(writer->out, "\n");
2939 }
2940
2941 xmlListPopFront(writer->nodes);
2942 break;
2943 case XML_TEXTWRITER_DTD_ELEM:
2944 case XML_TEXTWRITER_DTD_ELEM_TEXT:
2945 count = xmlTextWriterEndDTDElement(writer);
2946 break;
2947 case XML_TEXTWRITER_DTD_ATTL:
2948 case XML_TEXTWRITER_DTD_ATTL_TEXT:
2949 count = xmlTextWriterEndDTDAttlist(writer);
2950 break;
2951 case XML_TEXTWRITER_DTD_ENTY:
2952 case XML_TEXTWRITER_DTD_PENT:
2953 case XML_TEXTWRITER_DTD_ENTY_TEXT:
2954 count = xmlTextWriterEndDTDEntity(writer);
2955 break;
2956 case XML_TEXTWRITER_COMMENT:
2957 count = xmlTextWriterEndComment(writer);
2958 break;
2959 default:
2960 loop = 0;
2961 continue;
2962 }
2963
2964 if (count < 0)
Daniel Veillard1d211e22003-10-20 22:32:39 +00002965 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00002966 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002967 }
2968
Daniel Veillard1d211e22003-10-20 22:32:39 +00002969 return sum;
2970}
2971
2972/**
2973 * xmlTextWriterWriteFormatDTD:
2974 * @writer: the xmlTextWriterPtr
2975 * @name: the name of the DTD
2976 * @pubid: the public identifier, which is an alternative to the system identifier
2977 * @sysid: the system identifier, which is the URI of the DTD
2978 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002979 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002980 *
2981 * Write a DTD with a formatted markup declarations part.
2982 *
2983 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2984 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00002985int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00002986xmlTextWriterWriteFormatDTD(xmlTextWriterPtr writer,
2987 const xmlChar * name,
2988 const xmlChar * pubid,
2989 const xmlChar * sysid, const char *format, ...)
2990{
2991 int rc;
2992 va_list ap;
2993
2994 va_start(ap, format);
2995
2996 rc = xmlTextWriterWriteVFormatDTD(writer, name, pubid, sysid, format,
2997 ap);
2998
2999 va_end(ap);
3000 return rc;
3001}
3002
3003/**
3004 * xmlTextWriterWriteVFormatDTD:
3005 * @writer: the xmlTextWriterPtr
3006 * @name: the name of the DTD
3007 * @pubid: the public identifier, which is an alternative to the system identifier
3008 * @sysid: the system identifier, which is the URI of the DTD
3009 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003010 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00003011 *
3012 * Write a DTD with a formatted markup declarations part.
3013 *
3014 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3015 */
3016int
3017xmlTextWriterWriteVFormatDTD(xmlTextWriterPtr writer,
3018 const xmlChar * name,
3019 const xmlChar * pubid,
3020 const xmlChar * sysid,
3021 const char *format, va_list argptr)
3022{
3023 int rc;
3024 xmlChar *buf;
3025
3026 if (writer == NULL)
3027 return -1;
3028
3029 buf = xmlTextWriterVSprintf(format, argptr);
3030 if (buf == 0)
3031 return 0;
3032
3033 rc = xmlTextWriterWriteDTD(writer, name, pubid, sysid, buf);
3034
3035 xmlFree(buf);
3036 return rc;
3037}
3038
3039/**
3040 * xmlTextWriterWriteDTD:
3041 * @writer: the xmlTextWriterPtr
3042 * @name: the name of the DTD
3043 * @pubid: the public identifier, which is an alternative to the system identifier
3044 * @sysid: the system identifier, which is the URI of the DTD
William M. Brackb1d53162003-11-18 06:54:40 +00003045 * @subset: string content of the DTD
Daniel Veillard1d211e22003-10-20 22:32:39 +00003046 *
3047 * Write a DTD.
3048 *
3049 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3050 */
3051int
3052xmlTextWriterWriteDTD(xmlTextWriterPtr writer,
3053 const xmlChar * name,
3054 const xmlChar * pubid,
3055 const xmlChar * sysid, const xmlChar * subset)
3056{
3057 int count;
3058 int sum;
3059
3060 sum = 0;
3061 count = xmlTextWriterStartDTD(writer, name, pubid, sysid);
3062 if (count == -1)
3063 return -1;
3064 sum += count;
3065 if (subset != 0) {
3066 count = xmlTextWriterWriteString(writer, subset);
3067 if (count == -1)
3068 return -1;
3069 sum += count;
3070 }
3071 count = xmlTextWriterEndDTD(writer);
3072 if (count == -1)
3073 return -1;
3074 sum += count;
3075
3076 return sum;
3077}
3078
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003079/**
3080 * xmlTextWriterStartDTDElement:
3081 * @writer: the xmlTextWriterPtr
3082 * @name: the name of the DTD element
3083 *
3084 * Start an xml DTD element.
3085 *
3086 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3087 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003088int
3089xmlTextWriterStartDTDElement(xmlTextWriterPtr writer, const xmlChar * name)
3090{
3091 int count;
3092 int sum;
3093 xmlLinkPtr lk;
3094 xmlTextWriterStackEntry *p;
3095
3096 if (writer == NULL || name == NULL || *name == '\0')
3097 return -1;
3098
3099 sum = 0;
3100 lk = xmlListFront(writer->nodes);
3101 if (lk == 0) {
3102 return -1;
3103 }
3104
3105 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
Daniel Veillard500a1de2004-03-22 15:22:58 +00003106 if (p != 0) {
3107 switch (p->state) {
3108 case XML_TEXTWRITER_DTD:
3109 count = xmlOutputBufferWriteString(writer->out, " [");
3110 if (count < 0)
3111 return -1;
3112 sum += count;
3113 if (writer->indent) {
3114 count = xmlOutputBufferWriteString(writer->out, "\n");
3115 if (count < 0)
3116 return -1;
3117 sum += count;
3118 }
3119 p->state = XML_TEXTWRITER_DTD_TEXT;
3120 /* fallthrough */
3121 case XML_TEXTWRITER_DTD_TEXT:
3122 case XML_TEXTWRITER_NONE:
3123 break;
3124 default:
Daniel Veillard1d211e22003-10-20 22:32:39 +00003125 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00003126 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00003127 }
3128
3129 p = (xmlTextWriterStackEntry *)
3130 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3131 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003132 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003133 "xmlTextWriterStartDTDElement : out of memory!\n");
3134 return -1;
3135 }
3136
3137 p->name = xmlStrdup(name);
3138 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003139 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003140 "xmlTextWriterStartDTDElement : out of memory!\n");
3141 xmlFree(p);
3142 return -1;
3143 }
3144 p->state = XML_TEXTWRITER_DTD_ELEM;
3145
3146 xmlListPushFront(writer->nodes, p);
3147
Daniel Veillard500a1de2004-03-22 15:22:58 +00003148 if (writer->indent) {
3149 count = xmlTextWriterWriteIndent(writer);
3150 if (count < 0)
3151 return -1;
3152 sum += count;
3153 }
3154
Daniel Veillard1d211e22003-10-20 22:32:39 +00003155 count = xmlOutputBufferWriteString(writer->out, "<!ELEMENT ");
3156 if (count < 0)
3157 return -1;
3158 sum += count;
3159 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
3160 if (count < 0)
3161 return -1;
3162 sum += count;
3163
3164 return sum;
3165}
3166
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003167/**
Daniel Veillard500a1de2004-03-22 15:22:58 +00003168 * xmlTextWriterEndDTDElement:
3169 * @writer: the xmlTextWriterPtr
3170 *
3171 * End an xml DTD element.
3172 *
3173 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3174 */
3175int
3176xmlTextWriterEndDTDElement(xmlTextWriterPtr writer)
3177{
3178 int count;
3179 int sum;
3180 xmlLinkPtr lk;
3181 xmlTextWriterStackEntry *p;
3182
3183 if (writer == NULL)
3184 return -1;
3185
3186 sum = 0;
3187 lk = xmlListFront(writer->nodes);
3188 if (lk == 0)
3189 return -1;
3190
3191 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3192 if (p == 0)
3193 return -1;
3194
3195 switch (p->state) {
3196 case XML_TEXTWRITER_DTD_ELEM:
3197 case XML_TEXTWRITER_DTD_ELEM_TEXT:
3198 count = xmlOutputBufferWriteString(writer->out, ">");
3199 if (count < 0)
3200 return -1;
3201 sum += count;
3202 break;
3203 default:
3204 return -1;
3205 }
3206
3207 if (writer->indent) {
3208 count = xmlOutputBufferWriteString(writer->out, "\n");
3209 if (count < 0)
3210 return -1;
3211 sum += count;
3212 }
3213
3214 xmlListPopFront(writer->nodes);
3215 return sum;
3216}
3217
3218/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003219 * xmlTextWriterWriteFormatDTDElement:
3220 * @writer: the xmlTextWriterPtr
3221 * @name: the name of the DTD element
3222 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003223 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003224 *
3225 * Write a formatted DTD element.
3226 *
3227 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3228 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00003229int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00003230xmlTextWriterWriteFormatDTDElement(xmlTextWriterPtr writer,
3231 const xmlChar * name,
3232 const char *format, ...)
3233{
3234 int rc;
3235 va_list ap;
3236
3237 va_start(ap, format);
3238
3239 rc = xmlTextWriterWriteVFormatDTDElement(writer, name, format, ap);
3240
3241 va_end(ap);
3242 return rc;
3243}
3244
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003245/**
3246 * xmlTextWriterWriteVFormatDTDElement:
3247 * @writer: the xmlTextWriterPtr
3248 * @name: the name of the DTD element
3249 * @format: format string (see printf)
3250 * @argptr: pointer to the first member of the variable argument list.
3251 *
3252 * Write a formatted DTD element.
3253 *
3254 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3255 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003256int
3257xmlTextWriterWriteVFormatDTDElement(xmlTextWriterPtr writer,
3258 const xmlChar * name,
3259 const char *format, va_list argptr)
3260{
3261 int rc;
3262 xmlChar *buf;
3263
3264 if (writer == NULL)
3265 return -1;
3266
3267 buf = xmlTextWriterVSprintf(format, argptr);
3268 if (buf == 0)
3269 return 0;
3270
3271 rc = xmlTextWriterWriteDTDElement(writer, name, buf);
3272
3273 xmlFree(buf);
3274 return rc;
3275}
3276
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003277/**
3278 * xmlTextWriterWriteDTDElement:
3279 * @writer: the xmlTextWriterPtr
3280 * @name: the name of the DTD element
3281 * @content: content of the element
3282 *
3283 * Write a DTD element.
3284 *
3285 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3286 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003287int
3288xmlTextWriterWriteDTDElement(xmlTextWriterPtr writer,
3289 const xmlChar * name, const xmlChar * content)
3290{
3291 int count;
3292 int sum;
3293
3294 if (content == NULL)
3295 return -1;
3296
3297 sum = 0;
3298 count = xmlTextWriterStartDTDElement(writer, name);
3299 if (count == -1)
3300 return -1;
3301 sum += count;
3302
Daniel Veillard1d211e22003-10-20 22:32:39 +00003303 count = xmlTextWriterWriteString(writer, content);
3304 if (count == -1)
3305 return -1;
3306 sum += count;
3307
3308 count = xmlTextWriterEndDTDElement(writer);
3309 if (count == -1)
3310 return -1;
3311 sum += count;
3312
3313 return sum;
3314}
3315
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003316/**
3317 * xmlTextWriterStartDTDAttlist:
3318 * @writer: the xmlTextWriterPtr
3319 * @name: the name of the DTD ATTLIST
3320 *
3321 * Start an xml DTD ATTLIST.
3322 *
3323 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3324 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003325int
3326xmlTextWriterStartDTDAttlist(xmlTextWriterPtr writer, const xmlChar * name)
3327{
3328 int count;
3329 int sum;
3330 xmlLinkPtr lk;
3331 xmlTextWriterStackEntry *p;
3332
3333 if (writer == NULL || name == NULL || *name == '\0')
3334 return -1;
3335
3336 sum = 0;
3337 lk = xmlListFront(writer->nodes);
3338 if (lk == 0) {
3339 return -1;
3340 }
3341
3342 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
Daniel Veillard500a1de2004-03-22 15:22:58 +00003343 if (p != 0) {
3344 switch (p->state) {
3345 case XML_TEXTWRITER_DTD:
3346 count = xmlOutputBufferWriteString(writer->out, " [");
3347 if (count < 0)
3348 return -1;
3349 sum += count;
3350 if (writer->indent) {
3351 count = xmlOutputBufferWriteString(writer->out, "\n");
3352 if (count < 0)
3353 return -1;
3354 sum += count;
3355 }
3356 p->state = XML_TEXTWRITER_DTD_TEXT;
3357 /* fallthrough */
3358 case XML_TEXTWRITER_DTD_TEXT:
3359 case XML_TEXTWRITER_NONE:
3360 break;
3361 default:
Daniel Veillard1d211e22003-10-20 22:32:39 +00003362 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00003363 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00003364 }
3365
3366 p = (xmlTextWriterStackEntry *)
3367 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3368 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003369 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003370 "xmlTextWriterStartDTDAttlist : out of memory!\n");
3371 return -1;
3372 }
3373
3374 p->name = xmlStrdup(name);
3375 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003376 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003377 "xmlTextWriterStartDTDAttlist : out of memory!\n");
3378 xmlFree(p);
3379 return -1;
3380 }
3381 p->state = XML_TEXTWRITER_DTD_ATTL;
3382
3383 xmlListPushFront(writer->nodes, p);
3384
Daniel Veillard500a1de2004-03-22 15:22:58 +00003385 if (writer->indent) {
3386 count = xmlTextWriterWriteIndent(writer);
3387 if (count < 0)
3388 return -1;
3389 sum += count;
3390 }
3391
Daniel Veillard1d211e22003-10-20 22:32:39 +00003392 count = xmlOutputBufferWriteString(writer->out, "<!ATTLIST ");
3393 if (count < 0)
3394 return -1;
3395 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +00003396 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003397 if (count < 0)
3398 return -1;
3399 sum += count;
3400
3401 return sum;
3402}
3403
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003404/**
Daniel Veillard500a1de2004-03-22 15:22:58 +00003405 * xmlTextWriterEndDTDAttlist:
3406 * @writer: the xmlTextWriterPtr
3407 *
3408 * End an xml DTD attribute list.
3409 *
3410 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3411 */
3412int
3413xmlTextWriterEndDTDAttlist(xmlTextWriterPtr writer)
3414{
3415 int count;
3416 int sum;
3417 xmlLinkPtr lk;
3418 xmlTextWriterStackEntry *p;
3419
3420 if (writer == NULL)
3421 return -1;
3422
3423 sum = 0;
3424 lk = xmlListFront(writer->nodes);
3425 if (lk == 0)
3426 return -1;
3427
3428 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3429 if (p == 0)
3430 return -1;
3431
3432 switch (p->state) {
3433 case XML_TEXTWRITER_DTD_ATTL:
3434 case XML_TEXTWRITER_DTD_ATTL_TEXT:
3435 count = xmlOutputBufferWriteString(writer->out, ">");
3436 if (count < 0)
3437 return -1;
3438 sum += count;
3439 break;
3440 default:
3441 return -1;
3442 }
3443
3444 if (writer->indent) {
3445 count = xmlOutputBufferWriteString(writer->out, "\n");
3446 if (count < 0)
3447 return -1;
3448 sum += count;
3449 }
3450
3451 xmlListPopFront(writer->nodes);
3452 return sum;
3453}
3454
3455/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003456 * xmlTextWriterWriteFormatDTDAttlist:
3457 * @writer: the xmlTextWriterPtr
3458 * @name: the name of the DTD ATTLIST
3459 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003460 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003461 *
3462 * Write a formatted DTD ATTLIST.
3463 *
3464 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3465 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00003466int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00003467xmlTextWriterWriteFormatDTDAttlist(xmlTextWriterPtr writer,
3468 const xmlChar * name,
3469 const char *format, ...)
3470{
3471 int rc;
3472 va_list ap;
3473
3474 va_start(ap, format);
3475
3476 rc = xmlTextWriterWriteVFormatDTDAttlist(writer, name, format, ap);
3477
3478 va_end(ap);
3479 return rc;
3480}
3481
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003482/**
3483 * xmlTextWriterWriteVFormatDTDAttlist:
3484 * @writer: the xmlTextWriterPtr
3485 * @name: the name of the DTD ATTLIST
3486 * @format: format string (see printf)
3487 * @argptr: pointer to the first member of the variable argument list.
3488 *
3489 * Write a formatted DTD ATTLIST.
3490 *
3491 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3492 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003493int
3494xmlTextWriterWriteVFormatDTDAttlist(xmlTextWriterPtr writer,
3495 const xmlChar * name,
3496 const char *format, va_list argptr)
3497{
3498 int rc;
3499 xmlChar *buf;
3500
3501 if (writer == NULL)
3502 return -1;
3503
3504 buf = xmlTextWriterVSprintf(format, argptr);
3505 if (buf == 0)
3506 return 0;
3507
3508 rc = xmlTextWriterWriteDTDAttlist(writer, name, buf);
3509
3510 xmlFree(buf);
3511 return rc;
3512}
3513
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003514/**
3515 * xmlTextWriterWriteDTDAttlist:
3516 * @writer: the xmlTextWriterPtr
3517 * @name: the name of the DTD ATTLIST
3518 * @content: content of the ATTLIST
3519 *
3520 * Write a DTD ATTLIST.
3521 *
3522 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3523 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003524int
3525xmlTextWriterWriteDTDAttlist(xmlTextWriterPtr writer,
3526 const xmlChar * name, const xmlChar * content)
3527{
3528 int count;
3529 int sum;
3530
3531 if (content == NULL)
3532 return -1;
3533
3534 sum = 0;
3535 count = xmlTextWriterStartDTDAttlist(writer, name);
3536 if (count == -1)
3537 return -1;
3538 sum += count;
3539
Daniel Veillard1d211e22003-10-20 22:32:39 +00003540 count = xmlTextWriterWriteString(writer, content);
3541 if (count == -1)
3542 return -1;
3543 sum += count;
3544
3545 count = xmlTextWriterEndDTDAttlist(writer);
3546 if (count == -1)
3547 return -1;
3548 sum += count;
3549
3550 return sum;
3551}
3552
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003553/**
3554 * xmlTextWriterStartDTDEntity:
3555 * @writer: the xmlTextWriterPtr
3556 * @pe: TRUE if this is a parameter entity, FALSE if not
3557 * @name: the name of the DTD ATTLIST
3558 *
3559 * Start an xml DTD ATTLIST.
3560 *
3561 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3562 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003563int
3564xmlTextWriterStartDTDEntity(xmlTextWriterPtr writer,
3565 int pe, const xmlChar * name)
3566{
3567 int count;
3568 int sum;
3569 xmlLinkPtr lk;
3570 xmlTextWriterStackEntry *p;
3571
3572 if (writer == NULL || name == NULL || *name == '\0')
3573 return -1;
3574
3575 sum = 0;
3576 lk = xmlListFront(writer->nodes);
Daniel Veillard500a1de2004-03-22 15:22:58 +00003577 if (lk != 0) {
Daniel Veillard1d211e22003-10-20 22:32:39 +00003578
Daniel Veillard500a1de2004-03-22 15:22:58 +00003579 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3580 if (p != 0) {
3581 switch (p->state) {
3582 case XML_TEXTWRITER_DTD:
3583 count = xmlOutputBufferWriteString(writer->out, " [");
3584 if (count < 0)
3585 return -1;
3586 sum += count;
3587 if (writer->indent) {
3588 count =
3589 xmlOutputBufferWriteString(writer->out, "\n");
3590 if (count < 0)
3591 return -1;
3592 sum += count;
3593 }
3594 p->state = XML_TEXTWRITER_DTD_TEXT;
3595 /* fallthrough */
3596 case XML_TEXTWRITER_DTD_TEXT:
3597 case XML_TEXTWRITER_NONE:
3598 break;
3599 default:
3600 return -1;
3601 }
3602 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00003603 }
3604
3605 p = (xmlTextWriterStackEntry *)
3606 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3607 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003608 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003609 "xmlTextWriterStartDTDElement : out of memory!\n");
3610 return -1;
3611 }
3612
3613 p->name = xmlStrdup(name);
3614 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003615 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003616 "xmlTextWriterStartDTDElement : out of memory!\n");
3617 xmlFree(p);
3618 return -1;
3619 }
Daniel Veillard500a1de2004-03-22 15:22:58 +00003620
3621 if (pe != 0)
3622 p->state = XML_TEXTWRITER_DTD_PENT;
3623 else
3624 p->state = XML_TEXTWRITER_DTD_ENTY;
Daniel Veillard1d211e22003-10-20 22:32:39 +00003625
3626 xmlListPushFront(writer->nodes, p);
3627
Daniel Veillard500a1de2004-03-22 15:22:58 +00003628 if (writer->indent) {
3629 count = xmlTextWriterWriteIndent(writer);
3630 if (count < 0)
3631 return -1;
3632 sum += count;
3633 }
3634
Daniel Veillard1d211e22003-10-20 22:32:39 +00003635 count = xmlOutputBufferWriteString(writer->out, "<!ENTITY ");
3636 if (count < 0)
3637 return -1;
3638 sum += count;
3639
3640 if (pe != 0) {
Daniel Veillard500a1de2004-03-22 15:22:58 +00003641 count = xmlOutputBufferWriteString(writer->out, "% ");
Daniel Veillard1d211e22003-10-20 22:32:39 +00003642 if (count < 0)
3643 return -1;
3644 sum += count;
3645 }
3646
Daniel Veillardab69f362004-02-17 11:40:32 +00003647 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003648 if (count < 0)
3649 return -1;
3650 sum += count;
3651
3652 return sum;
3653}
3654
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003655/**
Daniel Veillard500a1de2004-03-22 15:22:58 +00003656 * xmlTextWriterEndDTDEntity:
3657 * @writer: the xmlTextWriterPtr
3658 *
3659 * End an xml DTD entity.
3660 *
3661 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3662 */
3663int
3664xmlTextWriterEndDTDEntity(xmlTextWriterPtr writer)
3665{
3666 int count;
3667 int sum;
3668 xmlLinkPtr lk;
3669 xmlTextWriterStackEntry *p;
3670
3671 if (writer == NULL)
3672 return -1;
3673
3674 sum = 0;
3675 lk = xmlListFront(writer->nodes);
3676 if (lk == 0)
3677 return -1;
3678
3679 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3680 if (p == 0)
3681 return -1;
3682
3683 switch (p->state) {
3684 case XML_TEXTWRITER_DTD_ENTY_TEXT:
3685 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3686 if (count < 0)
3687 return -1;
3688 sum += count;
3689 case XML_TEXTWRITER_DTD_ENTY:
3690 case XML_TEXTWRITER_DTD_PENT:
Daniel Veillard500a1de2004-03-22 15:22:58 +00003691 count = xmlOutputBufferWriteString(writer->out, ">");
3692 if (count < 0)
3693 return -1;
3694 sum += count;
3695 break;
3696 default:
3697 return -1;
3698 }
3699
3700 if (writer->indent) {
3701 count = xmlOutputBufferWriteString(writer->out, "\n");
3702 if (count < 0)
3703 return -1;
3704 sum += count;
3705 }
3706
3707 xmlListPopFront(writer->nodes);
3708 return sum;
3709}
3710
3711/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003712 * xmlTextWriterWriteFormatDTDInternalEntity:
3713 * @writer: the xmlTextWriterPtr
3714 * @pe: TRUE if this is a parameter entity, FALSE if not
3715 * @name: the name of the DTD entity
3716 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003717 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003718 *
3719 * Write a formatted DTD internal entity.
3720 *
3721 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3722 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00003723int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00003724xmlTextWriterWriteFormatDTDInternalEntity(xmlTextWriterPtr writer,
3725 int pe,
3726 const xmlChar * name,
3727 const char *format, ...)
3728{
3729 int rc;
3730 va_list ap;
3731
3732 va_start(ap, format);
3733
3734 rc = xmlTextWriterWriteVFormatDTDInternalEntity(writer, pe, name,
3735 format, ap);
3736
3737 va_end(ap);
3738 return rc;
3739}
3740
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003741/**
3742 * xmlTextWriterWriteVFormatDTDInternalEntity:
3743 * @writer: the xmlTextWriterPtr
3744 * @pe: TRUE if this is a parameter entity, FALSE if not
3745 * @name: the name of the DTD entity
3746 * @format: format string (see printf)
3747 * @argptr: pointer to the first member of the variable argument list.
3748 *
3749 * Write a formatted DTD internal entity.
3750 *
3751 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3752 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003753int
3754xmlTextWriterWriteVFormatDTDInternalEntity(xmlTextWriterPtr writer,
3755 int pe,
3756 const xmlChar * name,
3757 const char *format,
3758 va_list argptr)
3759{
3760 int rc;
3761 xmlChar *buf;
3762
3763 if (writer == NULL)
3764 return -1;
3765
3766 buf = xmlTextWriterVSprintf(format, argptr);
3767 if (buf == 0)
3768 return 0;
3769
3770 rc = xmlTextWriterWriteDTDInternalEntity(writer, pe, name, buf);
3771
3772 xmlFree(buf);
3773 return rc;
3774}
3775
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003776/**
3777 * xmlTextWriterWriteDTDEntity:
3778 * @writer: the xmlTextWriterPtr
3779 * @pe: TRUE if this is a parameter entity, FALSE if not
3780 * @name: the name of the DTD entity
3781 * @pubid: the public identifier, which is an alternative to the system identifier
3782 * @sysid: the system identifier, which is the URI of the DTD
3783 * @ndataid: the xml notation name.
3784 * @content: content of the entity
3785 *
3786 * Write a DTD entity.
3787 *
3788 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3789 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003790int
3791xmlTextWriterWriteDTDEntity(xmlTextWriterPtr writer,
3792 int pe,
3793 const xmlChar * name,
3794 const xmlChar * pubid,
3795 const xmlChar * sysid,
3796 const xmlChar * ndataid,
3797 const xmlChar * content)
3798{
Daniel Veillard500a1de2004-03-22 15:22:58 +00003799 if ((content == NULL) && (pubid == NULL) && (sysid == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00003800 return -1;
3801 if ((pe != 0) && (ndataid != NULL))
3802 return -1;
3803
Daniel Veillard500a1de2004-03-22 15:22:58 +00003804 if ((pubid == NULL) && (sysid == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00003805 return xmlTextWriterWriteDTDInternalEntity(writer, pe, name,
3806 content);
3807
3808 return xmlTextWriterWriteDTDExternalEntity(writer, pe, name, pubid,
3809 sysid, ndataid);
3810}
3811
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003812/**
3813 * xmlTextWriterWriteDTDInternalEntity:
3814 * @writer: the xmlTextWriterPtr
3815 * @pe: TRUE if this is a parameter entity, FALSE if not
3816 * @name: the name of the DTD entity
3817 * @content: content of the entity
3818 *
3819 * Write a DTD internal entity.
3820 *
3821 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3822 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003823int
3824xmlTextWriterWriteDTDInternalEntity(xmlTextWriterPtr writer,
3825 int pe,
3826 const xmlChar * name,
3827 const xmlChar * content)
3828{
3829 int count;
3830 int sum;
3831
3832 if ((name == NULL) || (*name == '\0') || (content == NULL))
3833 return -1;
3834
3835 sum = 0;
3836 count = xmlTextWriterStartDTDEntity(writer, pe, name);
3837 if (count == -1)
3838 return -1;
3839 sum += count;
3840
Daniel Veillard1d211e22003-10-20 22:32:39 +00003841 count = xmlTextWriterWriteString(writer, content);
3842 if (count == -1)
3843 return -1;
3844 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00003845
3846 count = xmlTextWriterEndDTDEntity(writer);
3847 if (count == -1)
3848 return -1;
3849 sum += count;
3850
3851 return sum;
3852}
3853
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003854/**
3855 * xmlTextWriterWriteDTDExternalEntity:
3856 * @writer: the xmlTextWriterPtr
3857 * @pe: TRUE if this is a parameter entity, FALSE if not
3858 * @name: the name of the DTD entity
3859 * @pubid: the public identifier, which is an alternative to the system identifier
3860 * @sysid: the system identifier, which is the URI of the DTD
3861 * @ndataid: the xml notation name.
3862 *
Daniel Veillard500a1de2004-03-22 15:22:58 +00003863 * Write a DTD external entity. The entity must have been started with xmlTextWriterStartDTDEntity
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003864 *
3865 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3866 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003867int
3868xmlTextWriterWriteDTDExternalEntity(xmlTextWriterPtr writer,
3869 int pe,
3870 const xmlChar * name,
3871 const xmlChar * pubid,
3872 const xmlChar * sysid,
3873 const xmlChar * ndataid)
3874{
3875 int count;
3876 int sum;
3877
Daniel Veillard500a1de2004-03-22 15:22:58 +00003878 if (((pubid == NULL) && (sysid == NULL)))
Daniel Veillard1d211e22003-10-20 22:32:39 +00003879 return -1;
3880 if ((pe != 0) && (ndataid != NULL))
3881 return -1;
3882
3883 sum = 0;
3884 count = xmlTextWriterStartDTDEntity(writer, pe, name);
3885 if (count == -1)
3886 return -1;
3887 sum += count;
3888
Daniel Veillard500a1de2004-03-22 15:22:58 +00003889 count =
3890 xmlTextWriterWriteDTDExternalEntityContents(writer, pubid, sysid,
3891 ndataid);
3892 if (count < 0)
3893 return -1;
3894 sum += count;
3895
3896 count = xmlTextWriterEndDTDEntity(writer);
3897 if (count == -1)
3898 return -1;
3899 sum += count;
3900
3901 return sum;
3902}
3903
3904/**
3905 * xmlTextWriterWriteDTDExternalEntityContents:
3906 * @writer: the xmlTextWriterPtr
3907 * @pubid: the public identifier, which is an alternative to the system identifier
3908 * @sysid: the system identifier, which is the URI of the DTD
3909 * @ndataid: the xml notation name.
3910 *
3911 * Write the contents of a DTD external entity.
3912 *
3913 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3914 */
3915int
3916xmlTextWriterWriteDTDExternalEntityContents(xmlTextWriterPtr writer,
3917 const xmlChar * pubid,
3918 const xmlChar * sysid,
3919 const xmlChar * ndataid)
3920{
3921 int count;
3922 int sum;
3923 xmlLinkPtr lk;
3924 xmlTextWriterStackEntry *p;
3925
3926 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003927 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003928 "xmlTextWriterWriteDTDExternalEntityContents: xmlTextWriterPtr invalid!\n");
3929 return -1;
3930 }
3931
3932 sum = 0;
3933 lk = xmlListFront(writer->nodes);
3934 if (lk == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003935 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003936 "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n");
3937 return -1;
3938 }
3939
3940 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3941 if (p == 0)
3942 return -1;
3943
3944 switch (p->state) {
3945 case XML_TEXTWRITER_DTD_ENTY:
3946 break;
3947 case XML_TEXTWRITER_DTD_PENT:
3948 if (ndataid != NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003949 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003950 "xmlTextWriterWriteDTDExternalEntityContents: notation not allowed with parameter entities!\n");
3951 return -1;
3952 }
3953 break;
3954 default:
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003955 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003956 "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n");
3957 return -1;
3958 }
3959
Daniel Veillard1d211e22003-10-20 22:32:39 +00003960 if (pubid != 0) {
3961 if (sysid == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003962 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003963 "xmlTextWriterWriteDTDExternalEntityContents: system identifier needed!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +00003964 return -1;
3965 }
3966
3967 count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
3968 if (count < 0)
3969 return -1;
3970 sum += count;
3971
3972 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3973 if (count < 0)
3974 return -1;
3975 sum += count;
3976
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003977 count =
3978 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003979 if (count < 0)
3980 return -1;
3981 sum += count;
3982
3983 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3984 if (count < 0)
3985 return -1;
3986 sum += count;
3987 }
3988
3989 if (sysid != 0) {
3990 if (pubid == 0) {
3991 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
3992 if (count < 0)
3993 return -1;
3994 sum += count;
3995 }
3996
3997 count = xmlOutputBufferWriteString(writer->out, " ");
3998 if (count < 0)
3999 return -1;
4000 sum += count;
4001
4002 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4003 if (count < 0)
4004 return -1;
4005 sum += count;
4006
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004007 count =
4008 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004009 if (count < 0)
4010 return -1;
4011 sum += count;
4012
4013 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4014 if (count < 0)
4015 return -1;
4016 sum += count;
4017 }
4018
4019 if (ndataid != NULL) {
4020 count = xmlOutputBufferWriteString(writer->out, " NDATA ");
4021 if (count < 0)
4022 return -1;
4023 sum += count;
4024
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004025 count =
4026 xmlOutputBufferWriteString(writer->out,
4027 (const char *) ndataid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004028 if (count < 0)
4029 return -1;
4030 sum += count;
4031 }
4032
Daniel Veillard1d211e22003-10-20 22:32:39 +00004033 return sum;
4034}
4035
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004036/**
4037 * xmlTextWriterWriteDTDNotation:
4038 * @writer: the xmlTextWriterPtr
4039 * @name: the name of the xml notation
4040 * @pubid: the public identifier, which is an alternative to the system identifier
4041 * @sysid: the system identifier, which is the URI of the DTD
4042 *
4043 * Write a DTD entity.
4044 *
4045 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
4046 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00004047int
4048xmlTextWriterWriteDTDNotation(xmlTextWriterPtr writer,
4049 const xmlChar * name,
4050 const xmlChar * pubid, const xmlChar * sysid)
4051{
4052 int count;
4053 int sum;
4054 xmlLinkPtr lk;
4055 xmlTextWriterStackEntry *p;
4056
4057 if (writer == NULL || name == NULL || *name == '\0')
4058 return -1;
4059
4060 sum = 0;
4061 lk = xmlListFront(writer->nodes);
4062 if (lk == 0) {
4063 return -1;
4064 }
4065
4066 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
Daniel Veillard500a1de2004-03-22 15:22:58 +00004067 if (p != 0) {
4068 switch (p->state) {
4069 case XML_TEXTWRITER_DTD:
4070 count = xmlOutputBufferWriteString(writer->out, " [");
4071 if (count < 0)
4072 return -1;
4073 sum += count;
4074 if (writer->indent) {
4075 count = xmlOutputBufferWriteString(writer->out, "\n");
4076 if (count < 0)
4077 return -1;
4078 sum += count;
4079 }
4080 p->state = XML_TEXTWRITER_DTD_TEXT;
4081 /* fallthrough */
4082 case XML_TEXTWRITER_DTD_TEXT:
4083 break;
4084 default:
4085 return -1;
4086 }
4087 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00004088
Daniel Veillard500a1de2004-03-22 15:22:58 +00004089 if (writer->indent) {
4090 count = xmlTextWriterWriteIndent(writer);
4091 if (count < 0)
Daniel Veillard1d211e22003-10-20 22:32:39 +00004092 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00004093 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00004094 }
4095
4096 count = xmlOutputBufferWriteString(writer->out, "<!NOTATION ");
4097 if (count < 0)
4098 return -1;
4099 sum += count;
4100 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
4101 if (count < 0)
4102 return -1;
4103 sum += count;
4104
4105 if (pubid != 0) {
4106 count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
4107 if (count < 0)
4108 return -1;
4109 sum += count;
4110 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4111 if (count < 0)
4112 return -1;
4113 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004114 count =
4115 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004116 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;
4123 }
4124
4125 if (sysid != 0) {
4126 if (pubid == 0) {
4127 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
4128 if (count < 0)
4129 return -1;
4130 sum += count;
4131 }
4132 count = xmlOutputBufferWriteString(writer->out, " ");
4133 if (count < 0)
4134 return -1;
4135 sum += count;
4136 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4137 if (count < 0)
4138 return -1;
4139 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004140 count =
4141 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004142 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;
4149 }
4150
4151 count = xmlOutputBufferWriteString(writer->out, ">");
4152 if (count < 0)
4153 return -1;
4154 sum += count;
4155
4156 return sum;
4157}
4158
4159/**
4160 * xmlTextWriterFlush:
4161 * @writer: the xmlTextWriterPtr
4162 *
4163 * Flush the output buffer.
4164 *
4165 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
4166 */
4167int
4168xmlTextWriterFlush(xmlTextWriterPtr writer)
4169{
4170 int count;
4171
4172 if (writer == NULL)
4173 return -1;
4174
4175 if (writer->out == NULL)
4176 count = 0;
4177 else
4178 count = xmlOutputBufferFlush(writer->out);
4179
4180 return count;
4181}
4182
4183/**
4184 * misc
4185 */
4186
4187/**
4188 * xmlFreeTextWriterStackEntry:
4189 * @lk: the xmlLinkPtr
4190 *
4191 * Free callback for the xmlList.
4192 */
4193static void
4194xmlFreeTextWriterStackEntry(xmlLinkPtr lk)
4195{
4196 xmlTextWriterStackEntry *p;
4197
4198 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
4199 if (p == 0)
4200 return;
4201
4202 if (p->name != 0)
4203 xmlFree(p->name);
4204 xmlFree(p);
4205}
4206
4207/**
4208 * xmlCmpTextWriterStackEntry:
4209 * @data0: the first data
4210 * @data1: the second data
4211 *
4212 * Compare callback for the xmlList.
4213 *
4214 * Returns -1, 0, 1
4215 */
4216static int
4217xmlCmpTextWriterStackEntry(const void *data0, const void *data1)
4218{
4219 xmlTextWriterStackEntry *p0;
4220 xmlTextWriterStackEntry *p1;
4221
4222 if (data0 == data1)
4223 return 0;
4224
4225 if (data0 == 0)
4226 return -1;
4227
4228 if (data1 == 0)
4229 return 1;
4230
4231 p0 = (xmlTextWriterStackEntry *) data0;
4232 p1 = (xmlTextWriterStackEntry *) data1;
4233
4234 return xmlStrcmp(p0->name, p1->name);
4235}
4236
4237/**
4238 * misc
4239 */
4240
4241/**
4242 * xmlFreeTextWriterNsStackEntry:
4243 * @lk: the xmlLinkPtr
4244 *
4245 * Free callback for the xmlList.
4246 */
4247static void
4248xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk)
4249{
4250 xmlTextWriterNsStackEntry *p;
4251
4252 p = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
4253 if (p == 0)
4254 return;
4255
4256 if (p->prefix != 0)
4257 xmlFree(p->prefix);
4258 if (p->uri != 0)
4259 xmlFree(p->uri);
4260
4261 xmlFree(p);
4262}
4263
4264/**
4265 * xmlCmpTextWriterNsStackEntry:
4266 * @data0: the first data
4267 * @data1: the second data
4268 *
4269 * Compare callback for the xmlList.
4270 *
4271 * Returns -1, 0, 1
4272 */
4273static int
4274xmlCmpTextWriterNsStackEntry(const void *data0, const void *data1)
4275{
4276 xmlTextWriterNsStackEntry *p0;
4277 xmlTextWriterNsStackEntry *p1;
4278 int rc;
4279
4280 if (data0 == data1)
4281 return 0;
4282
4283 if (data0 == 0)
4284 return -1;
4285
4286 if (data1 == 0)
4287 return 1;
4288
4289 p0 = (xmlTextWriterNsStackEntry *) data0;
4290 p1 = (xmlTextWriterNsStackEntry *) data1;
4291
4292 rc = xmlStrcmp(p0->prefix, p1->prefix);
4293
4294 if (rc == 0)
4295 rc = p0->elem == p1->elem;
4296
4297 return rc;
4298}
4299
4300/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004301 * xmlTextWriterWriteDocCallback:
4302 * @context: the xmlBufferPtr
4303 * @str: the data to write
4304 * @len: the length of the data
4305 *
4306 * Write callback for the xmlOutputBuffer with target xmlBuffer
4307 *
4308 * Returns -1, 0, 1
4309 */
4310static int
4311xmlTextWriterWriteDocCallback(void *context, const xmlChar * str, int len)
4312{
4313 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context;
4314 int rc;
4315
Daniel Veillard1d913862003-11-21 00:28:39 +00004316 if ((rc = xmlParseChunk(ctxt, (const char *) str, len, 0)) != 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004317 xmlWriterErrMsgInt(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004318 "xmlTextWriterWriteDocCallback : XML error %d !\n",
4319 rc);
4320 return -1;
4321 }
4322
4323 return len;
4324}
4325
4326/**
4327 * xmlTextWriterCloseDocCallback:
4328 * @context: the xmlBufferPtr
4329 *
4330 * Close callback for the xmlOutputBuffer with target xmlBuffer
4331 *
4332 * Returns -1, 0, 1
4333 */
4334static int
4335xmlTextWriterCloseDocCallback(void *context)
4336{
4337 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context;
4338 int rc;
4339
4340 if ((rc = xmlParseChunk(ctxt, NULL, 0, 1)) != 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004341 xmlWriterErrMsgInt(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004342 "xmlTextWriterWriteDocCallback : XML error %d !\n",
4343 rc);
4344 return -1;
4345 }
4346
4347 return 0;
4348}
4349
4350/**
Daniel Veillard1d211e22003-10-20 22:32:39 +00004351 * xmlTextWriterVSprintf:
4352 * @format: see printf
4353 * @argptr: pointer to the first member of the variable argument list.
4354 *
4355 * Utility function for formatted output
4356 *
4357 * Returns a new xmlChar buffer with the data or NULL on error. This buffer must be freed.
4358 */
4359static xmlChar *
4360xmlTextWriterVSprintf(const char *format, va_list argptr)
4361{
4362 int size;
4363 int count;
4364 xmlChar *buf;
William M. Brackf4caa5e2005-10-20 09:04:05 +00004365 va_list locarg;
Daniel Veillard1d211e22003-10-20 22:32:39 +00004366
4367 size = BUFSIZ;
4368 buf = (xmlChar *) xmlMalloc(size);
4369 if (buf == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004370 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00004371 "xmlTextWriterVSprintf : out of memory!\n");
4372 return NULL;
4373 }
4374
William M. Brackf4caa5e2005-10-20 09:04:05 +00004375 VA_COPY(locarg, argptr);
4376 while (((count = vsnprintf((char *) buf, size, format, locarg)) < 0)
Daniel Veillard1d211e22003-10-20 22:32:39 +00004377 || (count == size - 1) || (count == size) || (count > size)) {
William M. Brackf4caa5e2005-10-20 09:04:05 +00004378 va_end(locarg);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004379 xmlFree(buf);
4380 size += BUFSIZ;
4381 buf = (xmlChar *) xmlMalloc(size);
4382 if (buf == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004383 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00004384 "xmlTextWriterVSprintf : out of memory!\n");
4385 return NULL;
4386 }
William M. Brackf4caa5e2005-10-20 09:04:05 +00004387 VA_COPY(locarg, argptr);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004388 }
William M. Brackf4caa5e2005-10-20 09:04:05 +00004389 va_end(locarg);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004390
4391 return buf;
4392}
4393
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004394/**
4395 * xmlTextWriterStartDocumentCallback:
4396 * @ctx: the user data (XML parser context)
4397 *
4398 * called at the start of document processing.
4399 */
4400static void
4401xmlTextWriterStartDocumentCallback(void *ctx)
4402{
4403 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
4404 xmlDocPtr doc;
4405
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004406 if (ctxt->html) {
4407#ifdef LIBXML_HTML_ENABLED
4408 if (ctxt->myDoc == NULL)
4409 ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
4410 if (ctxt->myDoc == NULL) {
4411 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
4412 ctxt->sax->error(ctxt->userData,
4413 "SAX.startDocument(): out of memory\n");
4414 ctxt->errNo = XML_ERR_NO_MEMORY;
4415 ctxt->instate = XML_PARSER_EOF;
4416 ctxt->disableSAX = 1;
4417 return;
4418 }
4419#else
Daniel Veillardd0cf7f62004-11-09 16:17:02 +00004420 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004421 "libxml2 built without HTML support\n");
4422 ctxt->errNo = XML_ERR_INTERNAL_ERROR;
4423 ctxt->instate = XML_PARSER_EOF;
4424 ctxt->disableSAX = 1;
4425 return;
4426#endif
4427 } else {
4428 doc = ctxt->myDoc;
4429 if (doc == NULL)
4430 doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
4431 if (doc != NULL) {
4432 if (doc->children == NULL) {
4433 if (ctxt->encoding != NULL)
4434 doc->encoding = xmlStrdup(ctxt->encoding);
4435 else
4436 doc->encoding = NULL;
4437 doc->standalone = ctxt->standalone;
4438 }
4439 } else {
4440 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
4441 ctxt->sax->error(ctxt->userData,
4442 "SAX.startDocument(): out of memory\n");
4443 ctxt->errNo = XML_ERR_NO_MEMORY;
4444 ctxt->instate = XML_PARSER_EOF;
4445 ctxt->disableSAX = 1;
4446 return;
4447 }
4448 }
4449 if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) &&
4450 (ctxt->input != NULL) && (ctxt->input->filename != NULL)) {
4451 ctxt->myDoc->URL =
4452 xmlCanonicPath((const xmlChar *) ctxt->input->filename);
4453 if (ctxt->myDoc->URL == NULL)
4454 ctxt->myDoc->URL =
4455 xmlStrdup((const xmlChar *) ctxt->input->filename);
4456 }
4457}
4458
Daniel Veillard2cca4462004-01-02 20:04:23 +00004459/**
4460 * xmlTextWriterSetIndent:
4461 * @writer: the xmlTextWriterPtr
4462 * @indent: do indentation?
4463 *
4464 * Set indentation output. indent = 0 do not indentation. indent > 0 do indentation.
4465 *
4466 * Returns -1 on error or 0 otherwise.
4467 */
4468int
Daniel Veillardab69f362004-02-17 11:40:32 +00004469xmlTextWriterSetIndent(xmlTextWriterPtr writer, int indent)
Daniel Veillard2cca4462004-01-02 20:04:23 +00004470{
Daniel Veillarde43cc572004-11-03 11:50:29 +00004471 if ((writer == NULL) || (indent < 0))
Daniel Veillardab69f362004-02-17 11:40:32 +00004472 return -1;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004473
Daniel Veillardab69f362004-02-17 11:40:32 +00004474 writer->indent = indent;
4475 writer->doindent = 1;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004476
Daniel Veillardab69f362004-02-17 11:40:32 +00004477 return 0;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004478}
4479
4480/**
4481 * xmlTextWriterSetIndentString:
4482 * @writer: the xmlTextWriterPtr
4483 * @str: the xmlChar string
4484 *
4485 * Set string indentation.
4486 *
4487 * Returns -1 on error or 0 otherwise.
4488 */
4489int
Daniel Veillardab69f362004-02-17 11:40:32 +00004490xmlTextWriterSetIndentString(xmlTextWriterPtr writer, const xmlChar * str)
Daniel Veillard2cca4462004-01-02 20:04:23 +00004491{
Daniel Veillarde43cc572004-11-03 11:50:29 +00004492 if ((writer == NULL) || (!str))
Daniel Veillardab69f362004-02-17 11:40:32 +00004493 return -1;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004494
Daniel Veillardab69f362004-02-17 11:40:32 +00004495 if (writer->ichar != NULL)
4496 xmlFree(writer->ichar);
4497 writer->ichar = xmlStrdup(str);
4498
4499 if (!writer->ichar)
4500 return -1;
4501 else
4502 return 0;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004503}
4504
4505/**
4506 * xmlTextWriterWriteIndent:
4507 * @writer: the xmlTextWriterPtr
4508 *
4509 * Write indent string.
4510 *
4511 * Returns -1 on error or the number of strings written.
Daniel Veillardab69f362004-02-17 11:40:32 +00004512 */
Daniel Veillard2cca4462004-01-02 20:04:23 +00004513static int
Daniel Veillardab69f362004-02-17 11:40:32 +00004514xmlTextWriterWriteIndent(xmlTextWriterPtr writer)
Daniel Veillard2cca4462004-01-02 20:04:23 +00004515{
Daniel Veillardab69f362004-02-17 11:40:32 +00004516 int lksize;
4517 int i;
4518 int ret;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004519
Daniel Veillardab69f362004-02-17 11:40:32 +00004520 lksize = xmlListSize(writer->nodes);
4521 if (lksize < 1)
4522 return (-1); /* list is empty */
4523 for (i = 0; i < (lksize - 1); i++) {
4524 ret = xmlOutputBufferWriteString(writer->out,
4525 (const char *) writer->ichar);
4526 if (ret == -1)
4527 return (-1);
4528 }
4529
4530 return (lksize - 1);
Daniel Veillard2cca4462004-01-02 20:04:23 +00004531}
4532
Daniel Veillard500a1de2004-03-22 15:22:58 +00004533/**
4534 * xmlTextWriterHandleStateDependencies:
4535 * @writer: the xmlTextWriterPtr
4536 * @p: the xmlTextWriterStackEntry
4537 *
4538 * Write state dependent strings.
4539 *
4540 * Returns -1 on error or the number of characters written.
4541 */
4542static int
4543xmlTextWriterHandleStateDependencies(xmlTextWriterPtr writer,
4544 xmlTextWriterStackEntry * p)
4545{
4546 int count;
4547 int sum;
4548 char extra[3];
4549
4550 if (writer == NULL)
4551 return -1;
4552
4553 if (p == NULL)
4554 return 0;
4555
4556 sum = 0;
4557 extra[0] = extra[1] = extra[2] = '\0';
4558 if (p != 0) {
4559 sum = 0;
4560 switch (p->state) {
4561 case XML_TEXTWRITER_NAME:
4562 extra[0] = '>';
4563 p->state = XML_TEXTWRITER_TEXT;
4564 break;
4565 case XML_TEXTWRITER_PI:
4566 extra[0] = ' ';
4567 p->state = XML_TEXTWRITER_PI_TEXT;
4568 break;
4569 case XML_TEXTWRITER_DTD:
4570 extra[0] = ' ';
4571 extra[1] = '[';
4572 p->state = XML_TEXTWRITER_DTD_TEXT;
4573 break;
4574 case XML_TEXTWRITER_DTD_ELEM:
4575 extra[0] = ' ';
4576 p->state = XML_TEXTWRITER_DTD_ELEM_TEXT;
4577 break;
4578 case XML_TEXTWRITER_DTD_ATTL:
4579 extra[0] = ' ';
4580 p->state = XML_TEXTWRITER_DTD_ATTL_TEXT;
4581 break;
4582 case XML_TEXTWRITER_DTD_ENTY:
4583 case XML_TEXTWRITER_DTD_PENT:
4584 extra[0] = ' ';
4585 extra[1] = writer->qchar;
4586 p->state = XML_TEXTWRITER_DTD_ENTY_TEXT;
4587 break;
4588 default:
4589 break;
4590 }
4591 }
4592
4593 if (*extra != '\0') {
4594 count = xmlOutputBufferWriteString(writer->out, extra);
4595 if (count < 0)
4596 return -1;
4597 sum += count;
4598 }
4599
4600 return sum;
4601}
4602
Daniel Veillard5d4644e2005-04-01 13:11:58 +00004603#define bottom_xmlwriter
4604#include "elfgcchack.h"
Daniel Veillard1d211e22003-10-20 22:32:39 +00004605#endif