blob: 37b794516af2d29b5ffe3b2d4a89a74a790e582c [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
2445 xmlListPopFront(writer->nodes);
2446 return sum;
2447}
2448
2449/**
2450 * xmlTextWriterWriteFormatPI:
2451 * @writer: the xmlTextWriterPtr
2452 * @target: PI target
2453 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002454 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002455 *
2456 * Write a formatted PI.
2457 *
2458 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2459 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00002460int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00002461xmlTextWriterWriteFormatPI(xmlTextWriterPtr writer, const xmlChar * target,
2462 const char *format, ...)
2463{
2464 int rc;
2465 va_list ap;
2466
2467 va_start(ap, format);
2468
2469 rc = xmlTextWriterWriteVFormatPI(writer, target, format, ap);
2470
2471 va_end(ap);
2472 return rc;
2473}
2474
2475/**
2476 * xmlTextWriterWriteVFormatPI:
2477 * @writer: the xmlTextWriterPtr
2478 * @target: PI target
2479 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002480 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00002481 *
2482 * Write a formatted xml PI.
2483 *
2484 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2485 */
2486int
2487xmlTextWriterWriteVFormatPI(xmlTextWriterPtr writer,
2488 const xmlChar * target, const char *format,
2489 va_list argptr)
2490{
2491 int rc;
2492 xmlChar *buf;
2493
2494 if (writer == NULL)
2495 return -1;
2496
2497 buf = xmlTextWriterVSprintf(format, argptr);
2498 if (buf == 0)
2499 return 0;
2500
2501 rc = xmlTextWriterWritePI(writer, target, buf);
2502
2503 xmlFree(buf);
2504 return rc;
2505}
2506
2507/**
2508 * xmlTextWriterWritePI:
2509 * @writer: the xmlTextWriterPtr
2510 * @target: PI target
2511 * @content: PI content
2512 *
2513 * Write an xml PI.
2514 *
2515 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2516 */
2517int
2518xmlTextWriterWritePI(xmlTextWriterPtr writer, const xmlChar * target,
2519 const xmlChar * content)
2520{
2521 int count;
2522 int sum;
2523
2524 sum = 0;
2525 count = xmlTextWriterStartPI(writer, target);
2526 if (count == -1)
2527 return -1;
2528 sum += count;
2529 if (content != 0) {
2530 count = xmlTextWriterWriteString(writer, content);
2531 if (count == -1)
2532 return -1;
2533 sum += count;
2534 }
2535 count = xmlTextWriterEndPI(writer);
2536 if (count == -1)
2537 return -1;
2538 sum += count;
2539
2540 return sum;
2541}
2542
2543/**
2544 * xmlTextWriterStartCDATA:
2545 * @writer: the xmlTextWriterPtr
2546 *
2547 * Start an xml CDATA section.
2548 *
2549 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2550 */
2551int
2552xmlTextWriterStartCDATA(xmlTextWriterPtr writer)
2553{
2554 int count;
2555 int sum;
2556 xmlLinkPtr lk;
2557 xmlTextWriterStackEntry *p;
2558
2559 if (writer == NULL)
2560 return -1;
2561
2562 sum = 0;
2563 lk = xmlListFront(writer->nodes);
2564 if (lk != 0) {
2565 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2566 if (p != 0) {
2567 switch (p->state) {
2568 case XML_TEXTWRITER_NONE:
2569 case XML_TEXTWRITER_PI:
2570 case XML_TEXTWRITER_PI_TEXT:
2571 break;
2572 case XML_TEXTWRITER_ATTRIBUTE:
2573 count = xmlTextWriterEndAttribute(writer);
2574 if (count < 0)
2575 return -1;
2576 sum += count;
2577 /* fallthrough */
2578 case XML_TEXTWRITER_NAME:
2579 count = xmlOutputBufferWriteString(writer->out, ">");
2580 if (count < 0)
2581 return -1;
2582 sum += count;
2583 p->state = XML_TEXTWRITER_TEXT;
2584 break;
2585 case XML_TEXTWRITER_CDATA:
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002586 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002587 "xmlTextWriterStartCDATA : CDATA not allowed in this context!\n");
2588 return -1;
2589 default:
2590 return -1;
2591 }
2592 }
2593 }
2594
2595 p = (xmlTextWriterStackEntry *)
2596 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2597 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002598 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002599 "xmlTextWriterStartCDATA : out of memory!\n");
2600 return -1;
2601 }
2602
Daniel Veillard75e389d2005-07-29 22:02:24 +00002603 p->name = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002604 p->state = XML_TEXTWRITER_CDATA;
2605
2606 xmlListPushFront(writer->nodes, p);
2607
2608 count = xmlOutputBufferWriteString(writer->out, "<![CDATA[");
2609 if (count < 0)
2610 return -1;
2611 sum += count;
2612
2613 return sum;
2614}
2615
2616/**
2617 * xmlTextWriterEndCDATA:
2618 * @writer: the xmlTextWriterPtr
2619 *
2620 * End an xml CDATA section.
2621 *
2622 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2623 */
2624int
2625xmlTextWriterEndCDATA(xmlTextWriterPtr writer)
2626{
2627 int count;
2628 int sum;
2629 xmlLinkPtr lk;
2630 xmlTextWriterStackEntry *p;
2631
2632 if (writer == NULL)
2633 return -1;
2634
2635 lk = xmlListFront(writer->nodes);
2636 if (lk == 0)
2637 return -1;
2638
2639 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2640 if (p == 0)
2641 return -1;
2642
2643 sum = 0;
2644 switch (p->state) {
2645 case XML_TEXTWRITER_CDATA:
2646 count = xmlOutputBufferWriteString(writer->out, "]]>");
2647 if (count < 0)
2648 return -1;
2649 sum += count;
2650 break;
2651 default:
2652 return -1;
2653 }
2654
2655 xmlListPopFront(writer->nodes);
2656 return sum;
2657}
2658
2659/**
2660 * xmlTextWriterWriteFormatCDATA:
2661 * @writer: the xmlTextWriterPtr
2662 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002663 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002664 *
2665 * Write a formatted xml CDATA.
2666 *
2667 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2668 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00002669int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00002670xmlTextWriterWriteFormatCDATA(xmlTextWriterPtr writer, const char *format,
2671 ...)
2672{
2673 int rc;
2674 va_list ap;
2675
2676 va_start(ap, format);
2677
2678 rc = xmlTextWriterWriteVFormatCDATA(writer, format, ap);
2679
2680 va_end(ap);
2681 return rc;
2682}
2683
2684/**
2685 * xmlTextWriterWriteVFormatCDATA:
2686 * @writer: the xmlTextWriterPtr
2687 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002688 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00002689 *
2690 * Write a formatted xml CDATA.
2691 *
2692 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2693 */
2694int
2695xmlTextWriterWriteVFormatCDATA(xmlTextWriterPtr writer, const char *format,
2696 va_list argptr)
2697{
2698 int rc;
2699 xmlChar *buf;
2700
2701 if (writer == NULL)
2702 return -1;
2703
2704 buf = xmlTextWriterVSprintf(format, argptr);
2705 if (buf == 0)
2706 return 0;
2707
2708 rc = xmlTextWriterWriteCDATA(writer, buf);
2709
2710 xmlFree(buf);
2711 return rc;
2712}
2713
2714/**
2715 * xmlTextWriterWriteCDATA:
2716 * @writer: the xmlTextWriterPtr
2717 * @content: CDATA content
2718 *
2719 * Write an xml CDATA.
2720 *
2721 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2722 */
2723int
2724xmlTextWriterWriteCDATA(xmlTextWriterPtr writer, const xmlChar * content)
2725{
2726 int count;
2727 int sum;
2728
2729 sum = 0;
2730 count = xmlTextWriterStartCDATA(writer);
2731 if (count == -1)
2732 return -1;
2733 sum += count;
2734 if (content != 0) {
2735 count = xmlTextWriterWriteString(writer, content);
2736 if (count == -1)
2737 return -1;
2738 sum += count;
2739 }
2740 count = xmlTextWriterEndCDATA(writer);
2741 if (count == -1)
2742 return -1;
2743 sum += count;
2744
2745 return sum;
2746}
2747
2748/**
2749 * xmlTextWriterStartDTD:
2750 * @writer: the xmlTextWriterPtr
2751 * @name: the name of the DTD
2752 * @pubid: the public identifier, which is an alternative to the system identifier
2753 * @sysid: the system identifier, which is the URI of the DTD
2754 *
2755 * Start an xml DTD.
2756 *
2757 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2758 */
2759int
2760xmlTextWriterStartDTD(xmlTextWriterPtr writer,
2761 const xmlChar * name,
2762 const xmlChar * pubid, const xmlChar * sysid)
2763{
2764 int count;
2765 int sum;
2766 xmlLinkPtr lk;
2767 xmlTextWriterStackEntry *p;
2768
2769 if (writer == NULL || name == NULL || *name == '\0')
2770 return -1;
2771
2772 sum = 0;
2773 lk = xmlListFront(writer->nodes);
Daniel Veillardab69f362004-02-17 11:40:32 +00002774 if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002775 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002776 "xmlTextWriterStartDTD : DTD allowed only in prolog!\n");
2777 return -1;
2778 }
2779
2780 p = (xmlTextWriterStackEntry *)
2781 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2782 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002783 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002784 "xmlTextWriterStartDTD : out of memory!\n");
2785 return -1;
2786 }
2787
2788 p->name = xmlStrdup(name);
2789 if (p->name == 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 xmlFree(p);
2793 return -1;
2794 }
2795 p->state = XML_TEXTWRITER_DTD;
2796
2797 xmlListPushFront(writer->nodes, p);
2798
2799 count = xmlOutputBufferWriteString(writer->out, "<!DOCTYPE ");
2800 if (count < 0)
2801 return -1;
2802 sum += count;
2803 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
2804 if (count < 0)
2805 return -1;
2806 sum += count;
2807
2808 if (pubid != 0) {
2809 if (sysid == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002810 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002811 "xmlTextWriterStartDTD : system identifier needed!\n");
2812 return -1;
2813 }
2814
Daniel Veillard500a1de2004-03-22 15:22:58 +00002815 if (writer->indent)
2816 count = xmlOutputBufferWrite(writer->out, 1, "\n");
2817 else
2818 count = xmlOutputBufferWrite(writer->out, 1, " ");
2819 if (count < 0)
2820 return -1;
2821 sum += count;
2822
2823 count = xmlOutputBufferWriteString(writer->out, "PUBLIC ");
2824 if (count < 0)
2825 return -1;
2826 sum += count;
2827
2828 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002829 if (count < 0)
2830 return -1;
2831 sum += count;
2832
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002833 count =
2834 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002835 if (count < 0)
2836 return -1;
2837 sum += count;
2838
Daniel Veillard500a1de2004-03-22 15:22:58 +00002839 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002840 if (count < 0)
2841 return -1;
2842 sum += count;
2843 }
2844
2845 if (sysid != 0) {
2846 if (pubid == 0) {
Daniel Veillard500a1de2004-03-22 15:22:58 +00002847 if (writer->indent)
2848 count = xmlOutputBufferWrite(writer->out, 1, "\n");
2849 else
2850 count = xmlOutputBufferWrite(writer->out, 1, " ");
2851 if (count < 0)
2852 return -1;
2853 sum += count;
2854 count = xmlOutputBufferWriteString(writer->out, "SYSTEM ");
2855 if (count < 0)
2856 return -1;
2857 sum += count;
Rob Richardsffe47fe2005-12-09 17:52:21 +00002858 } else {
2859 if (writer->indent)
Daniel Veillard500a1de2004-03-22 15:22:58 +00002860 count = xmlOutputBufferWriteString(writer->out, "\n ");
Rob Richardsffe47fe2005-12-09 17:52:21 +00002861 else
2862 count = xmlOutputBufferWrite(writer->out, 1, " ");
Daniel Veillard1d211e22003-10-20 22:32:39 +00002863 if (count < 0)
2864 return -1;
2865 sum += count;
2866 }
2867
Daniel Veillard500a1de2004-03-22 15:22:58 +00002868 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002869 if (count < 0)
2870 return -1;
2871 sum += count;
2872
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002873 count =
2874 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002875 if (count < 0)
2876 return -1;
2877 sum += count;
2878
Daniel Veillard500a1de2004-03-22 15:22:58 +00002879 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002880 if (count < 0)
2881 return -1;
2882 sum += count;
2883 }
2884
2885 return sum;
2886}
2887
2888/**
2889 * xmlTextWriterEndDTD:
2890 * @writer: the xmlTextWriterPtr
2891 *
2892 * End an xml DTD.
2893 *
2894 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2895 */
2896int
2897xmlTextWriterEndDTD(xmlTextWriterPtr writer)
2898{
Daniel Veillard500a1de2004-03-22 15:22:58 +00002899 int loop;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002900 int count;
2901 int sum;
2902 xmlLinkPtr lk;
2903 xmlTextWriterStackEntry *p;
2904
2905 if (writer == NULL)
2906 return -1;
2907
2908 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00002909 loop = 1;
2910 while (loop) {
2911 lk = xmlListFront(writer->nodes);
2912 if (lk == NULL)
Daniel Veillard1d211e22003-10-20 22:32:39 +00002913 break;
Daniel Veillard500a1de2004-03-22 15:22:58 +00002914 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2915 if (p == 0)
2916 break;
2917 switch (p->state) {
2918 case XML_TEXTWRITER_DTD_TEXT:
2919 count = xmlOutputBufferWriteString(writer->out, "]");
2920 if (count < 0)
2921 return -1;
2922 sum += count;
2923 /* fallthrough */
2924 case XML_TEXTWRITER_DTD:
2925 count = xmlOutputBufferWriteString(writer->out, ">");
2926
2927 if (writer->indent) {
2928 if (count < 0)
2929 return -1;
2930 sum += count;
2931 count = xmlOutputBufferWriteString(writer->out, "\n");
2932 }
2933
2934 xmlListPopFront(writer->nodes);
2935 break;
2936 case XML_TEXTWRITER_DTD_ELEM:
2937 case XML_TEXTWRITER_DTD_ELEM_TEXT:
2938 count = xmlTextWriterEndDTDElement(writer);
2939 break;
2940 case XML_TEXTWRITER_DTD_ATTL:
2941 case XML_TEXTWRITER_DTD_ATTL_TEXT:
2942 count = xmlTextWriterEndDTDAttlist(writer);
2943 break;
2944 case XML_TEXTWRITER_DTD_ENTY:
2945 case XML_TEXTWRITER_DTD_PENT:
2946 case XML_TEXTWRITER_DTD_ENTY_TEXT:
2947 count = xmlTextWriterEndDTDEntity(writer);
2948 break;
2949 case XML_TEXTWRITER_COMMENT:
2950 count = xmlTextWriterEndComment(writer);
2951 break;
2952 default:
2953 loop = 0;
2954 continue;
2955 }
2956
2957 if (count < 0)
Daniel Veillard1d211e22003-10-20 22:32:39 +00002958 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00002959 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002960 }
2961
Daniel Veillard1d211e22003-10-20 22:32:39 +00002962 return sum;
2963}
2964
2965/**
2966 * xmlTextWriterWriteFormatDTD:
2967 * @writer: the xmlTextWriterPtr
2968 * @name: the name of the DTD
2969 * @pubid: the public identifier, which is an alternative to the system identifier
2970 * @sysid: the system identifier, which is the URI of the DTD
2971 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002972 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002973 *
2974 * Write a DTD with a formatted markup declarations part.
2975 *
2976 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2977 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00002978int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00002979xmlTextWriterWriteFormatDTD(xmlTextWriterPtr writer,
2980 const xmlChar * name,
2981 const xmlChar * pubid,
2982 const xmlChar * sysid, const char *format, ...)
2983{
2984 int rc;
2985 va_list ap;
2986
2987 va_start(ap, format);
2988
2989 rc = xmlTextWriterWriteVFormatDTD(writer, name, pubid, sysid, format,
2990 ap);
2991
2992 va_end(ap);
2993 return rc;
2994}
2995
2996/**
2997 * xmlTextWriterWriteVFormatDTD:
2998 * @writer: the xmlTextWriterPtr
2999 * @name: the name of the DTD
3000 * @pubid: the public identifier, which is an alternative to the system identifier
3001 * @sysid: the system identifier, which is the URI of the DTD
3002 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003003 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00003004 *
3005 * Write a DTD with a formatted markup declarations part.
3006 *
3007 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3008 */
3009int
3010xmlTextWriterWriteVFormatDTD(xmlTextWriterPtr writer,
3011 const xmlChar * name,
3012 const xmlChar * pubid,
3013 const xmlChar * sysid,
3014 const char *format, va_list argptr)
3015{
3016 int rc;
3017 xmlChar *buf;
3018
3019 if (writer == NULL)
3020 return -1;
3021
3022 buf = xmlTextWriterVSprintf(format, argptr);
3023 if (buf == 0)
3024 return 0;
3025
3026 rc = xmlTextWriterWriteDTD(writer, name, pubid, sysid, buf);
3027
3028 xmlFree(buf);
3029 return rc;
3030}
3031
3032/**
3033 * xmlTextWriterWriteDTD:
3034 * @writer: the xmlTextWriterPtr
3035 * @name: the name of the DTD
3036 * @pubid: the public identifier, which is an alternative to the system identifier
3037 * @sysid: the system identifier, which is the URI of the DTD
William M. Brackb1d53162003-11-18 06:54:40 +00003038 * @subset: string content of the DTD
Daniel Veillard1d211e22003-10-20 22:32:39 +00003039 *
3040 * Write a DTD.
3041 *
3042 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3043 */
3044int
3045xmlTextWriterWriteDTD(xmlTextWriterPtr writer,
3046 const xmlChar * name,
3047 const xmlChar * pubid,
3048 const xmlChar * sysid, const xmlChar * subset)
3049{
3050 int count;
3051 int sum;
3052
3053 sum = 0;
3054 count = xmlTextWriterStartDTD(writer, name, pubid, sysid);
3055 if (count == -1)
3056 return -1;
3057 sum += count;
3058 if (subset != 0) {
3059 count = xmlTextWriterWriteString(writer, subset);
3060 if (count == -1)
3061 return -1;
3062 sum += count;
3063 }
3064 count = xmlTextWriterEndDTD(writer);
3065 if (count == -1)
3066 return -1;
3067 sum += count;
3068
3069 return sum;
3070}
3071
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003072/**
3073 * xmlTextWriterStartDTDElement:
3074 * @writer: the xmlTextWriterPtr
3075 * @name: the name of the DTD element
3076 *
3077 * Start an xml DTD element.
3078 *
3079 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3080 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003081int
3082xmlTextWriterStartDTDElement(xmlTextWriterPtr writer, const xmlChar * name)
3083{
3084 int count;
3085 int sum;
3086 xmlLinkPtr lk;
3087 xmlTextWriterStackEntry *p;
3088
3089 if (writer == NULL || name == NULL || *name == '\0')
3090 return -1;
3091
3092 sum = 0;
3093 lk = xmlListFront(writer->nodes);
3094 if (lk == 0) {
3095 return -1;
3096 }
3097
3098 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
Daniel Veillard500a1de2004-03-22 15:22:58 +00003099 if (p != 0) {
3100 switch (p->state) {
3101 case XML_TEXTWRITER_DTD:
3102 count = xmlOutputBufferWriteString(writer->out, " [");
3103 if (count < 0)
3104 return -1;
3105 sum += count;
3106 if (writer->indent) {
3107 count = xmlOutputBufferWriteString(writer->out, "\n");
3108 if (count < 0)
3109 return -1;
3110 sum += count;
3111 }
3112 p->state = XML_TEXTWRITER_DTD_TEXT;
3113 /* fallthrough */
3114 case XML_TEXTWRITER_DTD_TEXT:
3115 case XML_TEXTWRITER_NONE:
3116 break;
3117 default:
Daniel Veillard1d211e22003-10-20 22:32:39 +00003118 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00003119 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00003120 }
3121
3122 p = (xmlTextWriterStackEntry *)
3123 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3124 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003125 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003126 "xmlTextWriterStartDTDElement : out of memory!\n");
3127 return -1;
3128 }
3129
3130 p->name = xmlStrdup(name);
3131 if (p->name == 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 xmlFree(p);
3135 return -1;
3136 }
3137 p->state = XML_TEXTWRITER_DTD_ELEM;
3138
3139 xmlListPushFront(writer->nodes, p);
3140
Daniel Veillard500a1de2004-03-22 15:22:58 +00003141 if (writer->indent) {
3142 count = xmlTextWriterWriteIndent(writer);
3143 if (count < 0)
3144 return -1;
3145 sum += count;
3146 }
3147
Daniel Veillard1d211e22003-10-20 22:32:39 +00003148 count = xmlOutputBufferWriteString(writer->out, "<!ELEMENT ");
3149 if (count < 0)
3150 return -1;
3151 sum += count;
3152 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
3153 if (count < 0)
3154 return -1;
3155 sum += count;
3156
3157 return sum;
3158}
3159
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003160/**
Daniel Veillard500a1de2004-03-22 15:22:58 +00003161 * xmlTextWriterEndDTDElement:
3162 * @writer: the xmlTextWriterPtr
3163 *
3164 * End an xml DTD element.
3165 *
3166 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3167 */
3168int
3169xmlTextWriterEndDTDElement(xmlTextWriterPtr writer)
3170{
3171 int count;
3172 int sum;
3173 xmlLinkPtr lk;
3174 xmlTextWriterStackEntry *p;
3175
3176 if (writer == NULL)
3177 return -1;
3178
3179 sum = 0;
3180 lk = xmlListFront(writer->nodes);
3181 if (lk == 0)
3182 return -1;
3183
3184 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3185 if (p == 0)
3186 return -1;
3187
3188 switch (p->state) {
3189 case XML_TEXTWRITER_DTD_ELEM:
3190 case XML_TEXTWRITER_DTD_ELEM_TEXT:
3191 count = xmlOutputBufferWriteString(writer->out, ">");
3192 if (count < 0)
3193 return -1;
3194 sum += count;
3195 break;
3196 default:
3197 return -1;
3198 }
3199
3200 if (writer->indent) {
3201 count = xmlOutputBufferWriteString(writer->out, "\n");
3202 if (count < 0)
3203 return -1;
3204 sum += count;
3205 }
3206
3207 xmlListPopFront(writer->nodes);
3208 return sum;
3209}
3210
3211/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003212 * xmlTextWriterWriteFormatDTDElement:
3213 * @writer: the xmlTextWriterPtr
3214 * @name: the name of the DTD element
3215 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003216 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003217 *
3218 * Write a formatted DTD element.
3219 *
3220 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3221 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00003222int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00003223xmlTextWriterWriteFormatDTDElement(xmlTextWriterPtr writer,
3224 const xmlChar * name,
3225 const char *format, ...)
3226{
3227 int rc;
3228 va_list ap;
3229
3230 va_start(ap, format);
3231
3232 rc = xmlTextWriterWriteVFormatDTDElement(writer, name, format, ap);
3233
3234 va_end(ap);
3235 return rc;
3236}
3237
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003238/**
3239 * xmlTextWriterWriteVFormatDTDElement:
3240 * @writer: the xmlTextWriterPtr
3241 * @name: the name of the DTD element
3242 * @format: format string (see printf)
3243 * @argptr: pointer to the first member of the variable argument list.
3244 *
3245 * Write a formatted DTD element.
3246 *
3247 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3248 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003249int
3250xmlTextWriterWriteVFormatDTDElement(xmlTextWriterPtr writer,
3251 const xmlChar * name,
3252 const char *format, va_list argptr)
3253{
3254 int rc;
3255 xmlChar *buf;
3256
3257 if (writer == NULL)
3258 return -1;
3259
3260 buf = xmlTextWriterVSprintf(format, argptr);
3261 if (buf == 0)
3262 return 0;
3263
3264 rc = xmlTextWriterWriteDTDElement(writer, name, buf);
3265
3266 xmlFree(buf);
3267 return rc;
3268}
3269
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003270/**
3271 * xmlTextWriterWriteDTDElement:
3272 * @writer: the xmlTextWriterPtr
3273 * @name: the name of the DTD element
3274 * @content: content of the element
3275 *
3276 * Write a DTD element.
3277 *
3278 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3279 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003280int
3281xmlTextWriterWriteDTDElement(xmlTextWriterPtr writer,
3282 const xmlChar * name, const xmlChar * content)
3283{
3284 int count;
3285 int sum;
3286
3287 if (content == NULL)
3288 return -1;
3289
3290 sum = 0;
3291 count = xmlTextWriterStartDTDElement(writer, name);
3292 if (count == -1)
3293 return -1;
3294 sum += count;
3295
Daniel Veillard1d211e22003-10-20 22:32:39 +00003296 count = xmlTextWriterWriteString(writer, content);
3297 if (count == -1)
3298 return -1;
3299 sum += count;
3300
3301 count = xmlTextWriterEndDTDElement(writer);
3302 if (count == -1)
3303 return -1;
3304 sum += count;
3305
3306 return sum;
3307}
3308
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003309/**
3310 * xmlTextWriterStartDTDAttlist:
3311 * @writer: the xmlTextWriterPtr
3312 * @name: the name of the DTD ATTLIST
3313 *
3314 * Start an xml DTD ATTLIST.
3315 *
3316 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3317 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003318int
3319xmlTextWriterStartDTDAttlist(xmlTextWriterPtr writer, const xmlChar * name)
3320{
3321 int count;
3322 int sum;
3323 xmlLinkPtr lk;
3324 xmlTextWriterStackEntry *p;
3325
3326 if (writer == NULL || name == NULL || *name == '\0')
3327 return -1;
3328
3329 sum = 0;
3330 lk = xmlListFront(writer->nodes);
3331 if (lk == 0) {
3332 return -1;
3333 }
3334
3335 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
Daniel Veillard500a1de2004-03-22 15:22:58 +00003336 if (p != 0) {
3337 switch (p->state) {
3338 case XML_TEXTWRITER_DTD:
3339 count = xmlOutputBufferWriteString(writer->out, " [");
3340 if (count < 0)
3341 return -1;
3342 sum += count;
3343 if (writer->indent) {
3344 count = xmlOutputBufferWriteString(writer->out, "\n");
3345 if (count < 0)
3346 return -1;
3347 sum += count;
3348 }
3349 p->state = XML_TEXTWRITER_DTD_TEXT;
3350 /* fallthrough */
3351 case XML_TEXTWRITER_DTD_TEXT:
3352 case XML_TEXTWRITER_NONE:
3353 break;
3354 default:
Daniel Veillard1d211e22003-10-20 22:32:39 +00003355 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00003356 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00003357 }
3358
3359 p = (xmlTextWriterStackEntry *)
3360 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3361 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003362 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003363 "xmlTextWriterStartDTDAttlist : out of memory!\n");
3364 return -1;
3365 }
3366
3367 p->name = xmlStrdup(name);
3368 if (p->name == 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 xmlFree(p);
3372 return -1;
3373 }
3374 p->state = XML_TEXTWRITER_DTD_ATTL;
3375
3376 xmlListPushFront(writer->nodes, p);
3377
Daniel Veillard500a1de2004-03-22 15:22:58 +00003378 if (writer->indent) {
3379 count = xmlTextWriterWriteIndent(writer);
3380 if (count < 0)
3381 return -1;
3382 sum += count;
3383 }
3384
Daniel Veillard1d211e22003-10-20 22:32:39 +00003385 count = xmlOutputBufferWriteString(writer->out, "<!ATTLIST ");
3386 if (count < 0)
3387 return -1;
3388 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +00003389 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003390 if (count < 0)
3391 return -1;
3392 sum += count;
3393
3394 return sum;
3395}
3396
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003397/**
Daniel Veillard500a1de2004-03-22 15:22:58 +00003398 * xmlTextWriterEndDTDAttlist:
3399 * @writer: the xmlTextWriterPtr
3400 *
3401 * End an xml DTD attribute list.
3402 *
3403 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3404 */
3405int
3406xmlTextWriterEndDTDAttlist(xmlTextWriterPtr writer)
3407{
3408 int count;
3409 int sum;
3410 xmlLinkPtr lk;
3411 xmlTextWriterStackEntry *p;
3412
3413 if (writer == NULL)
3414 return -1;
3415
3416 sum = 0;
3417 lk = xmlListFront(writer->nodes);
3418 if (lk == 0)
3419 return -1;
3420
3421 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3422 if (p == 0)
3423 return -1;
3424
3425 switch (p->state) {
3426 case XML_TEXTWRITER_DTD_ATTL:
3427 case XML_TEXTWRITER_DTD_ATTL_TEXT:
3428 count = xmlOutputBufferWriteString(writer->out, ">");
3429 if (count < 0)
3430 return -1;
3431 sum += count;
3432 break;
3433 default:
3434 return -1;
3435 }
3436
3437 if (writer->indent) {
3438 count = xmlOutputBufferWriteString(writer->out, "\n");
3439 if (count < 0)
3440 return -1;
3441 sum += count;
3442 }
3443
3444 xmlListPopFront(writer->nodes);
3445 return sum;
3446}
3447
3448/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003449 * xmlTextWriterWriteFormatDTDAttlist:
3450 * @writer: the xmlTextWriterPtr
3451 * @name: the name of the DTD ATTLIST
3452 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003453 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003454 *
3455 * Write a formatted DTD ATTLIST.
3456 *
3457 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3458 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00003459int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00003460xmlTextWriterWriteFormatDTDAttlist(xmlTextWriterPtr writer,
3461 const xmlChar * name,
3462 const char *format, ...)
3463{
3464 int rc;
3465 va_list ap;
3466
3467 va_start(ap, format);
3468
3469 rc = xmlTextWriterWriteVFormatDTDAttlist(writer, name, format, ap);
3470
3471 va_end(ap);
3472 return rc;
3473}
3474
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003475/**
3476 * xmlTextWriterWriteVFormatDTDAttlist:
3477 * @writer: the xmlTextWriterPtr
3478 * @name: the name of the DTD ATTLIST
3479 * @format: format string (see printf)
3480 * @argptr: pointer to the first member of the variable argument list.
3481 *
3482 * Write a formatted DTD ATTLIST.
3483 *
3484 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3485 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003486int
3487xmlTextWriterWriteVFormatDTDAttlist(xmlTextWriterPtr writer,
3488 const xmlChar * name,
3489 const char *format, va_list argptr)
3490{
3491 int rc;
3492 xmlChar *buf;
3493
3494 if (writer == NULL)
3495 return -1;
3496
3497 buf = xmlTextWriterVSprintf(format, argptr);
3498 if (buf == 0)
3499 return 0;
3500
3501 rc = xmlTextWriterWriteDTDAttlist(writer, name, buf);
3502
3503 xmlFree(buf);
3504 return rc;
3505}
3506
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003507/**
3508 * xmlTextWriterWriteDTDAttlist:
3509 * @writer: the xmlTextWriterPtr
3510 * @name: the name of the DTD ATTLIST
3511 * @content: content of the ATTLIST
3512 *
3513 * Write a DTD ATTLIST.
3514 *
3515 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3516 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003517int
3518xmlTextWriterWriteDTDAttlist(xmlTextWriterPtr writer,
3519 const xmlChar * name, const xmlChar * content)
3520{
3521 int count;
3522 int sum;
3523
3524 if (content == NULL)
3525 return -1;
3526
3527 sum = 0;
3528 count = xmlTextWriterStartDTDAttlist(writer, name);
3529 if (count == -1)
3530 return -1;
3531 sum += count;
3532
Daniel Veillard1d211e22003-10-20 22:32:39 +00003533 count = xmlTextWriterWriteString(writer, content);
3534 if (count == -1)
3535 return -1;
3536 sum += count;
3537
3538 count = xmlTextWriterEndDTDAttlist(writer);
3539 if (count == -1)
3540 return -1;
3541 sum += count;
3542
3543 return sum;
3544}
3545
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003546/**
3547 * xmlTextWriterStartDTDEntity:
3548 * @writer: the xmlTextWriterPtr
3549 * @pe: TRUE if this is a parameter entity, FALSE if not
3550 * @name: the name of the DTD ATTLIST
3551 *
3552 * Start an xml DTD ATTLIST.
3553 *
3554 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3555 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003556int
3557xmlTextWriterStartDTDEntity(xmlTextWriterPtr writer,
3558 int pe, const xmlChar * name)
3559{
3560 int count;
3561 int sum;
3562 xmlLinkPtr lk;
3563 xmlTextWriterStackEntry *p;
3564
3565 if (writer == NULL || name == NULL || *name == '\0')
3566 return -1;
3567
3568 sum = 0;
3569 lk = xmlListFront(writer->nodes);
Daniel Veillard500a1de2004-03-22 15:22:58 +00003570 if (lk != 0) {
Daniel Veillard1d211e22003-10-20 22:32:39 +00003571
Daniel Veillard500a1de2004-03-22 15:22:58 +00003572 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3573 if (p != 0) {
3574 switch (p->state) {
3575 case XML_TEXTWRITER_DTD:
3576 count = xmlOutputBufferWriteString(writer->out, " [");
3577 if (count < 0)
3578 return -1;
3579 sum += count;
3580 if (writer->indent) {
3581 count =
3582 xmlOutputBufferWriteString(writer->out, "\n");
3583 if (count < 0)
3584 return -1;
3585 sum += count;
3586 }
3587 p->state = XML_TEXTWRITER_DTD_TEXT;
3588 /* fallthrough */
3589 case XML_TEXTWRITER_DTD_TEXT:
3590 case XML_TEXTWRITER_NONE:
3591 break;
3592 default:
3593 return -1;
3594 }
3595 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00003596 }
3597
3598 p = (xmlTextWriterStackEntry *)
3599 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3600 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003601 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003602 "xmlTextWriterStartDTDElement : out of memory!\n");
3603 return -1;
3604 }
3605
3606 p->name = xmlStrdup(name);
3607 if (p->name == 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 xmlFree(p);
3611 return -1;
3612 }
Daniel Veillard500a1de2004-03-22 15:22:58 +00003613
3614 if (pe != 0)
3615 p->state = XML_TEXTWRITER_DTD_PENT;
3616 else
3617 p->state = XML_TEXTWRITER_DTD_ENTY;
Daniel Veillard1d211e22003-10-20 22:32:39 +00003618
3619 xmlListPushFront(writer->nodes, p);
3620
Daniel Veillard500a1de2004-03-22 15:22:58 +00003621 if (writer->indent) {
3622 count = xmlTextWriterWriteIndent(writer);
3623 if (count < 0)
3624 return -1;
3625 sum += count;
3626 }
3627
Daniel Veillard1d211e22003-10-20 22:32:39 +00003628 count = xmlOutputBufferWriteString(writer->out, "<!ENTITY ");
3629 if (count < 0)
3630 return -1;
3631 sum += count;
3632
3633 if (pe != 0) {
Daniel Veillard500a1de2004-03-22 15:22:58 +00003634 count = xmlOutputBufferWriteString(writer->out, "% ");
Daniel Veillard1d211e22003-10-20 22:32:39 +00003635 if (count < 0)
3636 return -1;
3637 sum += count;
3638 }
3639
Daniel Veillardab69f362004-02-17 11:40:32 +00003640 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003641 if (count < 0)
3642 return -1;
3643 sum += count;
3644
3645 return sum;
3646}
3647
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003648/**
Daniel Veillard500a1de2004-03-22 15:22:58 +00003649 * xmlTextWriterEndDTDEntity:
3650 * @writer: the xmlTextWriterPtr
3651 *
3652 * End an xml DTD entity.
3653 *
3654 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3655 */
3656int
3657xmlTextWriterEndDTDEntity(xmlTextWriterPtr writer)
3658{
3659 int count;
3660 int sum;
3661 xmlLinkPtr lk;
3662 xmlTextWriterStackEntry *p;
3663
3664 if (writer == NULL)
3665 return -1;
3666
3667 sum = 0;
3668 lk = xmlListFront(writer->nodes);
3669 if (lk == 0)
3670 return -1;
3671
3672 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3673 if (p == 0)
3674 return -1;
3675
3676 switch (p->state) {
3677 case XML_TEXTWRITER_DTD_ENTY_TEXT:
3678 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3679 if (count < 0)
3680 return -1;
3681 sum += count;
3682 case XML_TEXTWRITER_DTD_ENTY:
3683 case XML_TEXTWRITER_DTD_PENT:
Daniel Veillard500a1de2004-03-22 15:22:58 +00003684 count = xmlOutputBufferWriteString(writer->out, ">");
3685 if (count < 0)
3686 return -1;
3687 sum += count;
3688 break;
3689 default:
3690 return -1;
3691 }
3692
3693 if (writer->indent) {
3694 count = xmlOutputBufferWriteString(writer->out, "\n");
3695 if (count < 0)
3696 return -1;
3697 sum += count;
3698 }
3699
3700 xmlListPopFront(writer->nodes);
3701 return sum;
3702}
3703
3704/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003705 * xmlTextWriterWriteFormatDTDInternalEntity:
3706 * @writer: the xmlTextWriterPtr
3707 * @pe: TRUE if this is a parameter entity, FALSE if not
3708 * @name: the name of the DTD entity
3709 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003710 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003711 *
3712 * Write a formatted DTD internal entity.
3713 *
3714 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3715 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00003716int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00003717xmlTextWriterWriteFormatDTDInternalEntity(xmlTextWriterPtr writer,
3718 int pe,
3719 const xmlChar * name,
3720 const char *format, ...)
3721{
3722 int rc;
3723 va_list ap;
3724
3725 va_start(ap, format);
3726
3727 rc = xmlTextWriterWriteVFormatDTDInternalEntity(writer, pe, name,
3728 format, ap);
3729
3730 va_end(ap);
3731 return rc;
3732}
3733
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003734/**
3735 * xmlTextWriterWriteVFormatDTDInternalEntity:
3736 * @writer: the xmlTextWriterPtr
3737 * @pe: TRUE if this is a parameter entity, FALSE if not
3738 * @name: the name of the DTD entity
3739 * @format: format string (see printf)
3740 * @argptr: pointer to the first member of the variable argument list.
3741 *
3742 * Write a formatted DTD internal entity.
3743 *
3744 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3745 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003746int
3747xmlTextWriterWriteVFormatDTDInternalEntity(xmlTextWriterPtr writer,
3748 int pe,
3749 const xmlChar * name,
3750 const char *format,
3751 va_list argptr)
3752{
3753 int rc;
3754 xmlChar *buf;
3755
3756 if (writer == NULL)
3757 return -1;
3758
3759 buf = xmlTextWriterVSprintf(format, argptr);
3760 if (buf == 0)
3761 return 0;
3762
3763 rc = xmlTextWriterWriteDTDInternalEntity(writer, pe, name, buf);
3764
3765 xmlFree(buf);
3766 return rc;
3767}
3768
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003769/**
3770 * xmlTextWriterWriteDTDEntity:
3771 * @writer: the xmlTextWriterPtr
3772 * @pe: TRUE if this is a parameter entity, FALSE if not
3773 * @name: the name of the DTD entity
3774 * @pubid: the public identifier, which is an alternative to the system identifier
3775 * @sysid: the system identifier, which is the URI of the DTD
3776 * @ndataid: the xml notation name.
3777 * @content: content of the entity
3778 *
3779 * Write a DTD entity.
3780 *
3781 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3782 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003783int
3784xmlTextWriterWriteDTDEntity(xmlTextWriterPtr writer,
3785 int pe,
3786 const xmlChar * name,
3787 const xmlChar * pubid,
3788 const xmlChar * sysid,
3789 const xmlChar * ndataid,
3790 const xmlChar * content)
3791{
Daniel Veillard500a1de2004-03-22 15:22:58 +00003792 if ((content == NULL) && (pubid == NULL) && (sysid == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00003793 return -1;
3794 if ((pe != 0) && (ndataid != NULL))
3795 return -1;
3796
Daniel Veillard500a1de2004-03-22 15:22:58 +00003797 if ((pubid == NULL) && (sysid == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00003798 return xmlTextWriterWriteDTDInternalEntity(writer, pe, name,
3799 content);
3800
3801 return xmlTextWriterWriteDTDExternalEntity(writer, pe, name, pubid,
3802 sysid, ndataid);
3803}
3804
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003805/**
3806 * xmlTextWriterWriteDTDInternalEntity:
3807 * @writer: the xmlTextWriterPtr
3808 * @pe: TRUE if this is a parameter entity, FALSE if not
3809 * @name: the name of the DTD entity
3810 * @content: content of the entity
3811 *
3812 * Write a DTD internal entity.
3813 *
3814 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3815 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003816int
3817xmlTextWriterWriteDTDInternalEntity(xmlTextWriterPtr writer,
3818 int pe,
3819 const xmlChar * name,
3820 const xmlChar * content)
3821{
3822 int count;
3823 int sum;
3824
3825 if ((name == NULL) || (*name == '\0') || (content == NULL))
3826 return -1;
3827
3828 sum = 0;
3829 count = xmlTextWriterStartDTDEntity(writer, pe, name);
3830 if (count == -1)
3831 return -1;
3832 sum += count;
3833
Daniel Veillard1d211e22003-10-20 22:32:39 +00003834 count = xmlTextWriterWriteString(writer, content);
3835 if (count == -1)
3836 return -1;
3837 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00003838
3839 count = xmlTextWriterEndDTDEntity(writer);
3840 if (count == -1)
3841 return -1;
3842 sum += count;
3843
3844 return sum;
3845}
3846
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003847/**
3848 * xmlTextWriterWriteDTDExternalEntity:
3849 * @writer: the xmlTextWriterPtr
3850 * @pe: TRUE if this is a parameter entity, FALSE if not
3851 * @name: the name of the DTD entity
3852 * @pubid: the public identifier, which is an alternative to the system identifier
3853 * @sysid: the system identifier, which is the URI of the DTD
3854 * @ndataid: the xml notation name.
3855 *
Daniel Veillard500a1de2004-03-22 15:22:58 +00003856 * Write a DTD external entity. The entity must have been started with xmlTextWriterStartDTDEntity
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003857 *
3858 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3859 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003860int
3861xmlTextWriterWriteDTDExternalEntity(xmlTextWriterPtr writer,
3862 int pe,
3863 const xmlChar * name,
3864 const xmlChar * pubid,
3865 const xmlChar * sysid,
3866 const xmlChar * ndataid)
3867{
3868 int count;
3869 int sum;
3870
Daniel Veillard500a1de2004-03-22 15:22:58 +00003871 if (((pubid == NULL) && (sysid == NULL)))
Daniel Veillard1d211e22003-10-20 22:32:39 +00003872 return -1;
3873 if ((pe != 0) && (ndataid != NULL))
3874 return -1;
3875
3876 sum = 0;
3877 count = xmlTextWriterStartDTDEntity(writer, pe, name);
3878 if (count == -1)
3879 return -1;
3880 sum += count;
3881
Daniel Veillard500a1de2004-03-22 15:22:58 +00003882 count =
3883 xmlTextWriterWriteDTDExternalEntityContents(writer, pubid, sysid,
3884 ndataid);
3885 if (count < 0)
3886 return -1;
3887 sum += count;
3888
3889 count = xmlTextWriterEndDTDEntity(writer);
3890 if (count == -1)
3891 return -1;
3892 sum += count;
3893
3894 return sum;
3895}
3896
3897/**
3898 * xmlTextWriterWriteDTDExternalEntityContents:
3899 * @writer: the xmlTextWriterPtr
3900 * @pubid: the public identifier, which is an alternative to the system identifier
3901 * @sysid: the system identifier, which is the URI of the DTD
3902 * @ndataid: the xml notation name.
3903 *
3904 * Write the contents of a DTD external entity.
3905 *
3906 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3907 */
3908int
3909xmlTextWriterWriteDTDExternalEntityContents(xmlTextWriterPtr writer,
3910 const xmlChar * pubid,
3911 const xmlChar * sysid,
3912 const xmlChar * ndataid)
3913{
3914 int count;
3915 int sum;
3916 xmlLinkPtr lk;
3917 xmlTextWriterStackEntry *p;
3918
3919 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003920 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003921 "xmlTextWriterWriteDTDExternalEntityContents: xmlTextWriterPtr invalid!\n");
3922 return -1;
3923 }
3924
3925 sum = 0;
3926 lk = xmlListFront(writer->nodes);
3927 if (lk == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003928 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003929 "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n");
3930 return -1;
3931 }
3932
3933 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3934 if (p == 0)
3935 return -1;
3936
3937 switch (p->state) {
3938 case XML_TEXTWRITER_DTD_ENTY:
3939 break;
3940 case XML_TEXTWRITER_DTD_PENT:
3941 if (ndataid != NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003942 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003943 "xmlTextWriterWriteDTDExternalEntityContents: notation not allowed with parameter entities!\n");
3944 return -1;
3945 }
3946 break;
3947 default:
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003948 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003949 "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n");
3950 return -1;
3951 }
3952
Daniel Veillard1d211e22003-10-20 22:32:39 +00003953 if (pubid != 0) {
3954 if (sysid == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003955 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003956 "xmlTextWriterWriteDTDExternalEntityContents: system identifier needed!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +00003957 return -1;
3958 }
3959
3960 count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
3961 if (count < 0)
3962 return -1;
3963 sum += count;
3964
3965 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3966 if (count < 0)
3967 return -1;
3968 sum += count;
3969
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003970 count =
3971 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003972 if (count < 0)
3973 return -1;
3974 sum += count;
3975
3976 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3977 if (count < 0)
3978 return -1;
3979 sum += count;
3980 }
3981
3982 if (sysid != 0) {
3983 if (pubid == 0) {
3984 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
3985 if (count < 0)
3986 return -1;
3987 sum += count;
3988 }
3989
3990 count = xmlOutputBufferWriteString(writer->out, " ");
3991 if (count < 0)
3992 return -1;
3993 sum += count;
3994
3995 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3996 if (count < 0)
3997 return -1;
3998 sum += count;
3999
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004000 count =
4001 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004002 if (count < 0)
4003 return -1;
4004 sum += count;
4005
4006 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4007 if (count < 0)
4008 return -1;
4009 sum += count;
4010 }
4011
4012 if (ndataid != NULL) {
4013 count = xmlOutputBufferWriteString(writer->out, " NDATA ");
4014 if (count < 0)
4015 return -1;
4016 sum += count;
4017
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004018 count =
4019 xmlOutputBufferWriteString(writer->out,
4020 (const char *) ndataid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004021 if (count < 0)
4022 return -1;
4023 sum += count;
4024 }
4025
Daniel Veillard1d211e22003-10-20 22:32:39 +00004026 return sum;
4027}
4028
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004029/**
4030 * xmlTextWriterWriteDTDNotation:
4031 * @writer: the xmlTextWriterPtr
4032 * @name: the name of the xml notation
4033 * @pubid: the public identifier, which is an alternative to the system identifier
4034 * @sysid: the system identifier, which is the URI of the DTD
4035 *
4036 * Write a DTD entity.
4037 *
4038 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
4039 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00004040int
4041xmlTextWriterWriteDTDNotation(xmlTextWriterPtr writer,
4042 const xmlChar * name,
4043 const xmlChar * pubid, const xmlChar * sysid)
4044{
4045 int count;
4046 int sum;
4047 xmlLinkPtr lk;
4048 xmlTextWriterStackEntry *p;
4049
4050 if (writer == NULL || name == NULL || *name == '\0')
4051 return -1;
4052
4053 sum = 0;
4054 lk = xmlListFront(writer->nodes);
4055 if (lk == 0) {
4056 return -1;
4057 }
4058
4059 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
Daniel Veillard500a1de2004-03-22 15:22:58 +00004060 if (p != 0) {
4061 switch (p->state) {
4062 case XML_TEXTWRITER_DTD:
4063 count = xmlOutputBufferWriteString(writer->out, " [");
4064 if (count < 0)
4065 return -1;
4066 sum += count;
4067 if (writer->indent) {
4068 count = xmlOutputBufferWriteString(writer->out, "\n");
4069 if (count < 0)
4070 return -1;
4071 sum += count;
4072 }
4073 p->state = XML_TEXTWRITER_DTD_TEXT;
4074 /* fallthrough */
4075 case XML_TEXTWRITER_DTD_TEXT:
4076 break;
4077 default:
4078 return -1;
4079 }
4080 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00004081
Daniel Veillard500a1de2004-03-22 15:22:58 +00004082 if (writer->indent) {
4083 count = xmlTextWriterWriteIndent(writer);
4084 if (count < 0)
Daniel Veillard1d211e22003-10-20 22:32:39 +00004085 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00004086 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00004087 }
4088
4089 count = xmlOutputBufferWriteString(writer->out, "<!NOTATION ");
4090 if (count < 0)
4091 return -1;
4092 sum += count;
4093 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
4094 if (count < 0)
4095 return -1;
4096 sum += count;
4097
4098 if (pubid != 0) {
4099 count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
4100 if (count < 0)
4101 return -1;
4102 sum += count;
4103 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4104 if (count < 0)
4105 return -1;
4106 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004107 count =
4108 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004109 if (count < 0)
4110 return -1;
4111 sum += count;
4112 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4113 if (count < 0)
4114 return -1;
4115 sum += count;
4116 }
4117
4118 if (sysid != 0) {
4119 if (pubid == 0) {
4120 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
4121 if (count < 0)
4122 return -1;
4123 sum += count;
4124 }
4125 count = xmlOutputBufferWriteString(writer->out, " ");
4126 if (count < 0)
4127 return -1;
4128 sum += count;
4129 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4130 if (count < 0)
4131 return -1;
4132 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004133 count =
4134 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004135 if (count < 0)
4136 return -1;
4137 sum += count;
4138 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4139 if (count < 0)
4140 return -1;
4141 sum += count;
4142 }
4143
4144 count = xmlOutputBufferWriteString(writer->out, ">");
4145 if (count < 0)
4146 return -1;
4147 sum += count;
4148
4149 return sum;
4150}
4151
4152/**
4153 * xmlTextWriterFlush:
4154 * @writer: the xmlTextWriterPtr
4155 *
4156 * Flush the output buffer.
4157 *
4158 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
4159 */
4160int
4161xmlTextWriterFlush(xmlTextWriterPtr writer)
4162{
4163 int count;
4164
4165 if (writer == NULL)
4166 return -1;
4167
4168 if (writer->out == NULL)
4169 count = 0;
4170 else
4171 count = xmlOutputBufferFlush(writer->out);
4172
4173 return count;
4174}
4175
4176/**
4177 * misc
4178 */
4179
4180/**
4181 * xmlFreeTextWriterStackEntry:
4182 * @lk: the xmlLinkPtr
4183 *
4184 * Free callback for the xmlList.
4185 */
4186static void
4187xmlFreeTextWriterStackEntry(xmlLinkPtr lk)
4188{
4189 xmlTextWriterStackEntry *p;
4190
4191 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
4192 if (p == 0)
4193 return;
4194
4195 if (p->name != 0)
4196 xmlFree(p->name);
4197 xmlFree(p);
4198}
4199
4200/**
4201 * xmlCmpTextWriterStackEntry:
4202 * @data0: the first data
4203 * @data1: the second data
4204 *
4205 * Compare callback for the xmlList.
4206 *
4207 * Returns -1, 0, 1
4208 */
4209static int
4210xmlCmpTextWriterStackEntry(const void *data0, const void *data1)
4211{
4212 xmlTextWriterStackEntry *p0;
4213 xmlTextWriterStackEntry *p1;
4214
4215 if (data0 == data1)
4216 return 0;
4217
4218 if (data0 == 0)
4219 return -1;
4220
4221 if (data1 == 0)
4222 return 1;
4223
4224 p0 = (xmlTextWriterStackEntry *) data0;
4225 p1 = (xmlTextWriterStackEntry *) data1;
4226
4227 return xmlStrcmp(p0->name, p1->name);
4228}
4229
4230/**
4231 * misc
4232 */
4233
4234/**
4235 * xmlFreeTextWriterNsStackEntry:
4236 * @lk: the xmlLinkPtr
4237 *
4238 * Free callback for the xmlList.
4239 */
4240static void
4241xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk)
4242{
4243 xmlTextWriterNsStackEntry *p;
4244
4245 p = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
4246 if (p == 0)
4247 return;
4248
4249 if (p->prefix != 0)
4250 xmlFree(p->prefix);
4251 if (p->uri != 0)
4252 xmlFree(p->uri);
4253
4254 xmlFree(p);
4255}
4256
4257/**
4258 * xmlCmpTextWriterNsStackEntry:
4259 * @data0: the first data
4260 * @data1: the second data
4261 *
4262 * Compare callback for the xmlList.
4263 *
4264 * Returns -1, 0, 1
4265 */
4266static int
4267xmlCmpTextWriterNsStackEntry(const void *data0, const void *data1)
4268{
4269 xmlTextWriterNsStackEntry *p0;
4270 xmlTextWriterNsStackEntry *p1;
4271 int rc;
4272
4273 if (data0 == data1)
4274 return 0;
4275
4276 if (data0 == 0)
4277 return -1;
4278
4279 if (data1 == 0)
4280 return 1;
4281
4282 p0 = (xmlTextWriterNsStackEntry *) data0;
4283 p1 = (xmlTextWriterNsStackEntry *) data1;
4284
4285 rc = xmlStrcmp(p0->prefix, p1->prefix);
4286
4287 if (rc == 0)
4288 rc = p0->elem == p1->elem;
4289
4290 return rc;
4291}
4292
4293/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004294 * xmlTextWriterWriteDocCallback:
4295 * @context: the xmlBufferPtr
4296 * @str: the data to write
4297 * @len: the length of the data
4298 *
4299 * Write callback for the xmlOutputBuffer with target xmlBuffer
4300 *
4301 * Returns -1, 0, 1
4302 */
4303static int
4304xmlTextWriterWriteDocCallback(void *context, const xmlChar * str, int len)
4305{
4306 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context;
4307 int rc;
4308
Daniel Veillard1d913862003-11-21 00:28:39 +00004309 if ((rc = xmlParseChunk(ctxt, (const char *) str, len, 0)) != 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004310 xmlWriterErrMsgInt(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004311 "xmlTextWriterWriteDocCallback : XML error %d !\n",
4312 rc);
4313 return -1;
4314 }
4315
4316 return len;
4317}
4318
4319/**
4320 * xmlTextWriterCloseDocCallback:
4321 * @context: the xmlBufferPtr
4322 *
4323 * Close callback for the xmlOutputBuffer with target xmlBuffer
4324 *
4325 * Returns -1, 0, 1
4326 */
4327static int
4328xmlTextWriterCloseDocCallback(void *context)
4329{
4330 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context;
4331 int rc;
4332
4333 if ((rc = xmlParseChunk(ctxt, NULL, 0, 1)) != 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004334 xmlWriterErrMsgInt(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004335 "xmlTextWriterWriteDocCallback : XML error %d !\n",
4336 rc);
4337 return -1;
4338 }
4339
4340 return 0;
4341}
4342
4343/**
Daniel Veillard1d211e22003-10-20 22:32:39 +00004344 * xmlTextWriterVSprintf:
4345 * @format: see printf
4346 * @argptr: pointer to the first member of the variable argument list.
4347 *
4348 * Utility function for formatted output
4349 *
4350 * Returns a new xmlChar buffer with the data or NULL on error. This buffer must be freed.
4351 */
4352static xmlChar *
4353xmlTextWriterVSprintf(const char *format, va_list argptr)
4354{
4355 int size;
4356 int count;
4357 xmlChar *buf;
William M. Brackf4caa5e2005-10-20 09:04:05 +00004358 va_list locarg;
Daniel Veillard1d211e22003-10-20 22:32:39 +00004359
4360 size = BUFSIZ;
4361 buf = (xmlChar *) xmlMalloc(size);
4362 if (buf == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004363 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00004364 "xmlTextWriterVSprintf : out of memory!\n");
4365 return NULL;
4366 }
4367
William M. Brackf4caa5e2005-10-20 09:04:05 +00004368 VA_COPY(locarg, argptr);
4369 while (((count = vsnprintf((char *) buf, size, format, locarg)) < 0)
Daniel Veillard1d211e22003-10-20 22:32:39 +00004370 || (count == size - 1) || (count == size) || (count > size)) {
William M. Brackf4caa5e2005-10-20 09:04:05 +00004371 va_end(locarg);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004372 xmlFree(buf);
4373 size += BUFSIZ;
4374 buf = (xmlChar *) xmlMalloc(size);
4375 if (buf == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004376 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00004377 "xmlTextWriterVSprintf : out of memory!\n");
4378 return NULL;
4379 }
William M. Brackf4caa5e2005-10-20 09:04:05 +00004380 VA_COPY(locarg, argptr);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004381 }
William M. Brackf4caa5e2005-10-20 09:04:05 +00004382 va_end(locarg);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004383
4384 return buf;
4385}
4386
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004387/**
4388 * xmlTextWriterStartDocumentCallback:
4389 * @ctx: the user data (XML parser context)
4390 *
4391 * called at the start of document processing.
4392 */
4393static void
4394xmlTextWriterStartDocumentCallback(void *ctx)
4395{
4396 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
4397 xmlDocPtr doc;
4398
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004399 if (ctxt->html) {
4400#ifdef LIBXML_HTML_ENABLED
4401 if (ctxt->myDoc == NULL)
4402 ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
4403 if (ctxt->myDoc == NULL) {
4404 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
4405 ctxt->sax->error(ctxt->userData,
4406 "SAX.startDocument(): out of memory\n");
4407 ctxt->errNo = XML_ERR_NO_MEMORY;
4408 ctxt->instate = XML_PARSER_EOF;
4409 ctxt->disableSAX = 1;
4410 return;
4411 }
4412#else
Daniel Veillardd0cf7f62004-11-09 16:17:02 +00004413 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004414 "libxml2 built without HTML support\n");
4415 ctxt->errNo = XML_ERR_INTERNAL_ERROR;
4416 ctxt->instate = XML_PARSER_EOF;
4417 ctxt->disableSAX = 1;
4418 return;
4419#endif
4420 } else {
4421 doc = ctxt->myDoc;
4422 if (doc == NULL)
4423 doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
4424 if (doc != NULL) {
4425 if (doc->children == NULL) {
4426 if (ctxt->encoding != NULL)
4427 doc->encoding = xmlStrdup(ctxt->encoding);
4428 else
4429 doc->encoding = NULL;
4430 doc->standalone = ctxt->standalone;
4431 }
4432 } else {
4433 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
4434 ctxt->sax->error(ctxt->userData,
4435 "SAX.startDocument(): out of memory\n");
4436 ctxt->errNo = XML_ERR_NO_MEMORY;
4437 ctxt->instate = XML_PARSER_EOF;
4438 ctxt->disableSAX = 1;
4439 return;
4440 }
4441 }
4442 if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) &&
4443 (ctxt->input != NULL) && (ctxt->input->filename != NULL)) {
4444 ctxt->myDoc->URL =
4445 xmlCanonicPath((const xmlChar *) ctxt->input->filename);
4446 if (ctxt->myDoc->URL == NULL)
4447 ctxt->myDoc->URL =
4448 xmlStrdup((const xmlChar *) ctxt->input->filename);
4449 }
4450}
4451
Daniel Veillard2cca4462004-01-02 20:04:23 +00004452/**
4453 * xmlTextWriterSetIndent:
4454 * @writer: the xmlTextWriterPtr
4455 * @indent: do indentation?
4456 *
4457 * Set indentation output. indent = 0 do not indentation. indent > 0 do indentation.
4458 *
4459 * Returns -1 on error or 0 otherwise.
4460 */
4461int
Daniel Veillardab69f362004-02-17 11:40:32 +00004462xmlTextWriterSetIndent(xmlTextWriterPtr writer, int indent)
Daniel Veillard2cca4462004-01-02 20:04:23 +00004463{
Daniel Veillarde43cc572004-11-03 11:50:29 +00004464 if ((writer == NULL) || (indent < 0))
Daniel Veillardab69f362004-02-17 11:40:32 +00004465 return -1;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004466
Daniel Veillardab69f362004-02-17 11:40:32 +00004467 writer->indent = indent;
4468 writer->doindent = 1;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004469
Daniel Veillardab69f362004-02-17 11:40:32 +00004470 return 0;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004471}
4472
4473/**
4474 * xmlTextWriterSetIndentString:
4475 * @writer: the xmlTextWriterPtr
4476 * @str: the xmlChar string
4477 *
4478 * Set string indentation.
4479 *
4480 * Returns -1 on error or 0 otherwise.
4481 */
4482int
Daniel Veillardab69f362004-02-17 11:40:32 +00004483xmlTextWriterSetIndentString(xmlTextWriterPtr writer, const xmlChar * str)
Daniel Veillard2cca4462004-01-02 20:04:23 +00004484{
Daniel Veillarde43cc572004-11-03 11:50:29 +00004485 if ((writer == NULL) || (!str))
Daniel Veillardab69f362004-02-17 11:40:32 +00004486 return -1;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004487
Daniel Veillardab69f362004-02-17 11:40:32 +00004488 if (writer->ichar != NULL)
4489 xmlFree(writer->ichar);
4490 writer->ichar = xmlStrdup(str);
4491
4492 if (!writer->ichar)
4493 return -1;
4494 else
4495 return 0;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004496}
4497
4498/**
4499 * xmlTextWriterWriteIndent:
4500 * @writer: the xmlTextWriterPtr
4501 *
4502 * Write indent string.
4503 *
4504 * Returns -1 on error or the number of strings written.
Daniel Veillardab69f362004-02-17 11:40:32 +00004505 */
Daniel Veillard2cca4462004-01-02 20:04:23 +00004506static int
Daniel Veillardab69f362004-02-17 11:40:32 +00004507xmlTextWriterWriteIndent(xmlTextWriterPtr writer)
Daniel Veillard2cca4462004-01-02 20:04:23 +00004508{
Daniel Veillardab69f362004-02-17 11:40:32 +00004509 int lksize;
4510 int i;
4511 int ret;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004512
Daniel Veillardab69f362004-02-17 11:40:32 +00004513 lksize = xmlListSize(writer->nodes);
4514 if (lksize < 1)
4515 return (-1); /* list is empty */
4516 for (i = 0; i < (lksize - 1); i++) {
4517 ret = xmlOutputBufferWriteString(writer->out,
4518 (const char *) writer->ichar);
4519 if (ret == -1)
4520 return (-1);
4521 }
4522
4523 return (lksize - 1);
Daniel Veillard2cca4462004-01-02 20:04:23 +00004524}
4525
Daniel Veillard500a1de2004-03-22 15:22:58 +00004526/**
4527 * xmlTextWriterHandleStateDependencies:
4528 * @writer: the xmlTextWriterPtr
4529 * @p: the xmlTextWriterStackEntry
4530 *
4531 * Write state dependent strings.
4532 *
4533 * Returns -1 on error or the number of characters written.
4534 */
4535static int
4536xmlTextWriterHandleStateDependencies(xmlTextWriterPtr writer,
4537 xmlTextWriterStackEntry * p)
4538{
4539 int count;
4540 int sum;
4541 char extra[3];
4542
4543 if (writer == NULL)
4544 return -1;
4545
4546 if (p == NULL)
4547 return 0;
4548
4549 sum = 0;
4550 extra[0] = extra[1] = extra[2] = '\0';
4551 if (p != 0) {
4552 sum = 0;
4553 switch (p->state) {
4554 case XML_TEXTWRITER_NAME:
4555 extra[0] = '>';
4556 p->state = XML_TEXTWRITER_TEXT;
4557 break;
4558 case XML_TEXTWRITER_PI:
4559 extra[0] = ' ';
4560 p->state = XML_TEXTWRITER_PI_TEXT;
4561 break;
4562 case XML_TEXTWRITER_DTD:
4563 extra[0] = ' ';
4564 extra[1] = '[';
4565 p->state = XML_TEXTWRITER_DTD_TEXT;
4566 break;
4567 case XML_TEXTWRITER_DTD_ELEM:
4568 extra[0] = ' ';
4569 p->state = XML_TEXTWRITER_DTD_ELEM_TEXT;
4570 break;
4571 case XML_TEXTWRITER_DTD_ATTL:
4572 extra[0] = ' ';
4573 p->state = XML_TEXTWRITER_DTD_ATTL_TEXT;
4574 break;
4575 case XML_TEXTWRITER_DTD_ENTY:
4576 case XML_TEXTWRITER_DTD_PENT:
4577 extra[0] = ' ';
4578 extra[1] = writer->qchar;
4579 p->state = XML_TEXTWRITER_DTD_ENTY_TEXT;
4580 break;
4581 default:
4582 break;
4583 }
4584 }
4585
4586 if (*extra != '\0') {
4587 count = xmlOutputBufferWriteString(writer->out, extra);
4588 if (count < 0)
4589 return -1;
4590 sum += count;
4591 }
4592
4593 return sum;
4594}
4595
Daniel Veillard5d4644e2005-04-01 13:11:58 +00004596#define bottom_xmlwriter
4597#include "elfgcchack.h"
Daniel Veillard1d211e22003-10-20 22:32:39 +00004598#endif