blob: 59113471f461f6d1d791d4afcfbc211181bdd8f9 [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;
2858 } else if (writer->indent) {
2859 count = xmlOutputBufferWriteString(writer->out, "\n ");
Daniel Veillard1d211e22003-10-20 22:32:39 +00002860 if (count < 0)
2861 return -1;
2862 sum += count;
2863 }
2864
Daniel Veillard500a1de2004-03-22 15:22:58 +00002865 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002866 if (count < 0)
2867 return -1;
2868 sum += count;
2869
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002870 count =
2871 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002872 if (count < 0)
2873 return -1;
2874 sum += count;
2875
Daniel Veillard500a1de2004-03-22 15:22:58 +00002876 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002877 if (count < 0)
2878 return -1;
2879 sum += count;
2880 }
2881
2882 return sum;
2883}
2884
2885/**
2886 * xmlTextWriterEndDTD:
2887 * @writer: the xmlTextWriterPtr
2888 *
2889 * End an xml DTD.
2890 *
2891 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2892 */
2893int
2894xmlTextWriterEndDTD(xmlTextWriterPtr writer)
2895{
Daniel Veillard500a1de2004-03-22 15:22:58 +00002896 int loop;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002897 int count;
2898 int sum;
2899 xmlLinkPtr lk;
2900 xmlTextWriterStackEntry *p;
2901
2902 if (writer == NULL)
2903 return -1;
2904
2905 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00002906 loop = 1;
2907 while (loop) {
2908 lk = xmlListFront(writer->nodes);
2909 if (lk == NULL)
Daniel Veillard1d211e22003-10-20 22:32:39 +00002910 break;
Daniel Veillard500a1de2004-03-22 15:22:58 +00002911 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2912 if (p == 0)
2913 break;
2914 switch (p->state) {
2915 case XML_TEXTWRITER_DTD_TEXT:
2916 count = xmlOutputBufferWriteString(writer->out, "]");
2917 if (count < 0)
2918 return -1;
2919 sum += count;
2920 /* fallthrough */
2921 case XML_TEXTWRITER_DTD:
2922 count = xmlOutputBufferWriteString(writer->out, ">");
2923
2924 if (writer->indent) {
2925 if (count < 0)
2926 return -1;
2927 sum += count;
2928 count = xmlOutputBufferWriteString(writer->out, "\n");
2929 }
2930
2931 xmlListPopFront(writer->nodes);
2932 break;
2933 case XML_TEXTWRITER_DTD_ELEM:
2934 case XML_TEXTWRITER_DTD_ELEM_TEXT:
2935 count = xmlTextWriterEndDTDElement(writer);
2936 break;
2937 case XML_TEXTWRITER_DTD_ATTL:
2938 case XML_TEXTWRITER_DTD_ATTL_TEXT:
2939 count = xmlTextWriterEndDTDAttlist(writer);
2940 break;
2941 case XML_TEXTWRITER_DTD_ENTY:
2942 case XML_TEXTWRITER_DTD_PENT:
2943 case XML_TEXTWRITER_DTD_ENTY_TEXT:
2944 count = xmlTextWriterEndDTDEntity(writer);
2945 break;
2946 case XML_TEXTWRITER_COMMENT:
2947 count = xmlTextWriterEndComment(writer);
2948 break;
2949 default:
2950 loop = 0;
2951 continue;
2952 }
2953
2954 if (count < 0)
Daniel Veillard1d211e22003-10-20 22:32:39 +00002955 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00002956 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002957 }
2958
Daniel Veillard1d211e22003-10-20 22:32:39 +00002959 return sum;
2960}
2961
2962/**
2963 * xmlTextWriterWriteFormatDTD:
2964 * @writer: the xmlTextWriterPtr
2965 * @name: the name of the DTD
2966 * @pubid: the public identifier, which is an alternative to the system identifier
2967 * @sysid: the system identifier, which is the URI of the DTD
2968 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002969 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002970 *
2971 * Write a DTD with a formatted markup declarations part.
2972 *
2973 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2974 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00002975int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00002976xmlTextWriterWriteFormatDTD(xmlTextWriterPtr writer,
2977 const xmlChar * name,
2978 const xmlChar * pubid,
2979 const xmlChar * sysid, const char *format, ...)
2980{
2981 int rc;
2982 va_list ap;
2983
2984 va_start(ap, format);
2985
2986 rc = xmlTextWriterWriteVFormatDTD(writer, name, pubid, sysid, format,
2987 ap);
2988
2989 va_end(ap);
2990 return rc;
2991}
2992
2993/**
2994 * xmlTextWriterWriteVFormatDTD:
2995 * @writer: the xmlTextWriterPtr
2996 * @name: the name of the DTD
2997 * @pubid: the public identifier, which is an alternative to the system identifier
2998 * @sysid: the system identifier, which is the URI of the DTD
2999 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003000 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00003001 *
3002 * Write a DTD with a formatted markup declarations part.
3003 *
3004 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3005 */
3006int
3007xmlTextWriterWriteVFormatDTD(xmlTextWriterPtr writer,
3008 const xmlChar * name,
3009 const xmlChar * pubid,
3010 const xmlChar * sysid,
3011 const char *format, va_list argptr)
3012{
3013 int rc;
3014 xmlChar *buf;
3015
3016 if (writer == NULL)
3017 return -1;
3018
3019 buf = xmlTextWriterVSprintf(format, argptr);
3020 if (buf == 0)
3021 return 0;
3022
3023 rc = xmlTextWriterWriteDTD(writer, name, pubid, sysid, buf);
3024
3025 xmlFree(buf);
3026 return rc;
3027}
3028
3029/**
3030 * xmlTextWriterWriteDTD:
3031 * @writer: the xmlTextWriterPtr
3032 * @name: the name of the DTD
3033 * @pubid: the public identifier, which is an alternative to the system identifier
3034 * @sysid: the system identifier, which is the URI of the DTD
William M. Brackb1d53162003-11-18 06:54:40 +00003035 * @subset: string content of the DTD
Daniel Veillard1d211e22003-10-20 22:32:39 +00003036 *
3037 * Write a DTD.
3038 *
3039 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3040 */
3041int
3042xmlTextWriterWriteDTD(xmlTextWriterPtr writer,
3043 const xmlChar * name,
3044 const xmlChar * pubid,
3045 const xmlChar * sysid, const xmlChar * subset)
3046{
3047 int count;
3048 int sum;
3049
3050 sum = 0;
3051 count = xmlTextWriterStartDTD(writer, name, pubid, sysid);
3052 if (count == -1)
3053 return -1;
3054 sum += count;
3055 if (subset != 0) {
3056 count = xmlTextWriterWriteString(writer, subset);
3057 if (count == -1)
3058 return -1;
3059 sum += count;
3060 }
3061 count = xmlTextWriterEndDTD(writer);
3062 if (count == -1)
3063 return -1;
3064 sum += count;
3065
3066 return sum;
3067}
3068
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003069/**
3070 * xmlTextWriterStartDTDElement:
3071 * @writer: the xmlTextWriterPtr
3072 * @name: the name of the DTD element
3073 *
3074 * Start an xml DTD element.
3075 *
3076 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3077 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003078int
3079xmlTextWriterStartDTDElement(xmlTextWriterPtr writer, const xmlChar * name)
3080{
3081 int count;
3082 int sum;
3083 xmlLinkPtr lk;
3084 xmlTextWriterStackEntry *p;
3085
3086 if (writer == NULL || name == NULL || *name == '\0')
3087 return -1;
3088
3089 sum = 0;
3090 lk = xmlListFront(writer->nodes);
3091 if (lk == 0) {
3092 return -1;
3093 }
3094
3095 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
Daniel Veillard500a1de2004-03-22 15:22:58 +00003096 if (p != 0) {
3097 switch (p->state) {
3098 case XML_TEXTWRITER_DTD:
3099 count = xmlOutputBufferWriteString(writer->out, " [");
3100 if (count < 0)
3101 return -1;
3102 sum += count;
3103 if (writer->indent) {
3104 count = xmlOutputBufferWriteString(writer->out, "\n");
3105 if (count < 0)
3106 return -1;
3107 sum += count;
3108 }
3109 p->state = XML_TEXTWRITER_DTD_TEXT;
3110 /* fallthrough */
3111 case XML_TEXTWRITER_DTD_TEXT:
3112 case XML_TEXTWRITER_NONE:
3113 break;
3114 default:
Daniel Veillard1d211e22003-10-20 22:32:39 +00003115 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00003116 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00003117 }
3118
3119 p = (xmlTextWriterStackEntry *)
3120 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3121 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003122 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003123 "xmlTextWriterStartDTDElement : out of memory!\n");
3124 return -1;
3125 }
3126
3127 p->name = xmlStrdup(name);
3128 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003129 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003130 "xmlTextWriterStartDTDElement : out of memory!\n");
3131 xmlFree(p);
3132 return -1;
3133 }
3134 p->state = XML_TEXTWRITER_DTD_ELEM;
3135
3136 xmlListPushFront(writer->nodes, p);
3137
Daniel Veillard500a1de2004-03-22 15:22:58 +00003138 if (writer->indent) {
3139 count = xmlTextWriterWriteIndent(writer);
3140 if (count < 0)
3141 return -1;
3142 sum += count;
3143 }
3144
Daniel Veillard1d211e22003-10-20 22:32:39 +00003145 count = xmlOutputBufferWriteString(writer->out, "<!ELEMENT ");
3146 if (count < 0)
3147 return -1;
3148 sum += count;
3149 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
3150 if (count < 0)
3151 return -1;
3152 sum += count;
3153
3154 return sum;
3155}
3156
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003157/**
Daniel Veillard500a1de2004-03-22 15:22:58 +00003158 * xmlTextWriterEndDTDElement:
3159 * @writer: the xmlTextWriterPtr
3160 *
3161 * End an xml DTD element.
3162 *
3163 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3164 */
3165int
3166xmlTextWriterEndDTDElement(xmlTextWriterPtr writer)
3167{
3168 int count;
3169 int sum;
3170 xmlLinkPtr lk;
3171 xmlTextWriterStackEntry *p;
3172
3173 if (writer == NULL)
3174 return -1;
3175
3176 sum = 0;
3177 lk = xmlListFront(writer->nodes);
3178 if (lk == 0)
3179 return -1;
3180
3181 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3182 if (p == 0)
3183 return -1;
3184
3185 switch (p->state) {
3186 case XML_TEXTWRITER_DTD_ELEM:
3187 case XML_TEXTWRITER_DTD_ELEM_TEXT:
3188 count = xmlOutputBufferWriteString(writer->out, ">");
3189 if (count < 0)
3190 return -1;
3191 sum += count;
3192 break;
3193 default:
3194 return -1;
3195 }
3196
3197 if (writer->indent) {
3198 count = xmlOutputBufferWriteString(writer->out, "\n");
3199 if (count < 0)
3200 return -1;
3201 sum += count;
3202 }
3203
3204 xmlListPopFront(writer->nodes);
3205 return sum;
3206}
3207
3208/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003209 * xmlTextWriterWriteFormatDTDElement:
3210 * @writer: the xmlTextWriterPtr
3211 * @name: the name of the DTD element
3212 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003213 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003214 *
3215 * Write a formatted DTD element.
3216 *
3217 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3218 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00003219int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00003220xmlTextWriterWriteFormatDTDElement(xmlTextWriterPtr writer,
3221 const xmlChar * name,
3222 const char *format, ...)
3223{
3224 int rc;
3225 va_list ap;
3226
3227 va_start(ap, format);
3228
3229 rc = xmlTextWriterWriteVFormatDTDElement(writer, name, format, ap);
3230
3231 va_end(ap);
3232 return rc;
3233}
3234
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003235/**
3236 * xmlTextWriterWriteVFormatDTDElement:
3237 * @writer: the xmlTextWriterPtr
3238 * @name: the name of the DTD element
3239 * @format: format string (see printf)
3240 * @argptr: pointer to the first member of the variable argument list.
3241 *
3242 * Write a formatted DTD element.
3243 *
3244 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3245 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003246int
3247xmlTextWriterWriteVFormatDTDElement(xmlTextWriterPtr writer,
3248 const xmlChar * name,
3249 const char *format, va_list argptr)
3250{
3251 int rc;
3252 xmlChar *buf;
3253
3254 if (writer == NULL)
3255 return -1;
3256
3257 buf = xmlTextWriterVSprintf(format, argptr);
3258 if (buf == 0)
3259 return 0;
3260
3261 rc = xmlTextWriterWriteDTDElement(writer, name, buf);
3262
3263 xmlFree(buf);
3264 return rc;
3265}
3266
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003267/**
3268 * xmlTextWriterWriteDTDElement:
3269 * @writer: the xmlTextWriterPtr
3270 * @name: the name of the DTD element
3271 * @content: content of the element
3272 *
3273 * Write a DTD element.
3274 *
3275 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3276 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003277int
3278xmlTextWriterWriteDTDElement(xmlTextWriterPtr writer,
3279 const xmlChar * name, const xmlChar * content)
3280{
3281 int count;
3282 int sum;
3283
3284 if (content == NULL)
3285 return -1;
3286
3287 sum = 0;
3288 count = xmlTextWriterStartDTDElement(writer, name);
3289 if (count == -1)
3290 return -1;
3291 sum += count;
3292
Daniel Veillard1d211e22003-10-20 22:32:39 +00003293 count = xmlTextWriterWriteString(writer, content);
3294 if (count == -1)
3295 return -1;
3296 sum += count;
3297
3298 count = xmlTextWriterEndDTDElement(writer);
3299 if (count == -1)
3300 return -1;
3301 sum += count;
3302
3303 return sum;
3304}
3305
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003306/**
3307 * xmlTextWriterStartDTDAttlist:
3308 * @writer: the xmlTextWriterPtr
3309 * @name: the name of the DTD ATTLIST
3310 *
3311 * Start an xml DTD ATTLIST.
3312 *
3313 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3314 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003315int
3316xmlTextWriterStartDTDAttlist(xmlTextWriterPtr writer, const xmlChar * name)
3317{
3318 int count;
3319 int sum;
3320 xmlLinkPtr lk;
3321 xmlTextWriterStackEntry *p;
3322
3323 if (writer == NULL || name == NULL || *name == '\0')
3324 return -1;
3325
3326 sum = 0;
3327 lk = xmlListFront(writer->nodes);
3328 if (lk == 0) {
3329 return -1;
3330 }
3331
3332 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
Daniel Veillard500a1de2004-03-22 15:22:58 +00003333 if (p != 0) {
3334 switch (p->state) {
3335 case XML_TEXTWRITER_DTD:
3336 count = xmlOutputBufferWriteString(writer->out, " [");
3337 if (count < 0)
3338 return -1;
3339 sum += count;
3340 if (writer->indent) {
3341 count = xmlOutputBufferWriteString(writer->out, "\n");
3342 if (count < 0)
3343 return -1;
3344 sum += count;
3345 }
3346 p->state = XML_TEXTWRITER_DTD_TEXT;
3347 /* fallthrough */
3348 case XML_TEXTWRITER_DTD_TEXT:
3349 case XML_TEXTWRITER_NONE:
3350 break;
3351 default:
Daniel Veillard1d211e22003-10-20 22:32:39 +00003352 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00003353 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00003354 }
3355
3356 p = (xmlTextWriterStackEntry *)
3357 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3358 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003359 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003360 "xmlTextWriterStartDTDAttlist : out of memory!\n");
3361 return -1;
3362 }
3363
3364 p->name = xmlStrdup(name);
3365 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003366 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003367 "xmlTextWriterStartDTDAttlist : out of memory!\n");
3368 xmlFree(p);
3369 return -1;
3370 }
3371 p->state = XML_TEXTWRITER_DTD_ATTL;
3372
3373 xmlListPushFront(writer->nodes, p);
3374
Daniel Veillard500a1de2004-03-22 15:22:58 +00003375 if (writer->indent) {
3376 count = xmlTextWriterWriteIndent(writer);
3377 if (count < 0)
3378 return -1;
3379 sum += count;
3380 }
3381
Daniel Veillard1d211e22003-10-20 22:32:39 +00003382 count = xmlOutputBufferWriteString(writer->out, "<!ATTLIST ");
3383 if (count < 0)
3384 return -1;
3385 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +00003386 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003387 if (count < 0)
3388 return -1;
3389 sum += count;
3390
3391 return sum;
3392}
3393
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003394/**
Daniel Veillard500a1de2004-03-22 15:22:58 +00003395 * xmlTextWriterEndDTDAttlist:
3396 * @writer: the xmlTextWriterPtr
3397 *
3398 * End an xml DTD attribute list.
3399 *
3400 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3401 */
3402int
3403xmlTextWriterEndDTDAttlist(xmlTextWriterPtr writer)
3404{
3405 int count;
3406 int sum;
3407 xmlLinkPtr lk;
3408 xmlTextWriterStackEntry *p;
3409
3410 if (writer == NULL)
3411 return -1;
3412
3413 sum = 0;
3414 lk = xmlListFront(writer->nodes);
3415 if (lk == 0)
3416 return -1;
3417
3418 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3419 if (p == 0)
3420 return -1;
3421
3422 switch (p->state) {
3423 case XML_TEXTWRITER_DTD_ATTL:
3424 case XML_TEXTWRITER_DTD_ATTL_TEXT:
3425 count = xmlOutputBufferWriteString(writer->out, ">");
3426 if (count < 0)
3427 return -1;
3428 sum += count;
3429 break;
3430 default:
3431 return -1;
3432 }
3433
3434 if (writer->indent) {
3435 count = xmlOutputBufferWriteString(writer->out, "\n");
3436 if (count < 0)
3437 return -1;
3438 sum += count;
3439 }
3440
3441 xmlListPopFront(writer->nodes);
3442 return sum;
3443}
3444
3445/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003446 * xmlTextWriterWriteFormatDTDAttlist:
3447 * @writer: the xmlTextWriterPtr
3448 * @name: the name of the DTD ATTLIST
3449 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003450 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003451 *
3452 * Write a formatted DTD ATTLIST.
3453 *
3454 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3455 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00003456int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00003457xmlTextWriterWriteFormatDTDAttlist(xmlTextWriterPtr writer,
3458 const xmlChar * name,
3459 const char *format, ...)
3460{
3461 int rc;
3462 va_list ap;
3463
3464 va_start(ap, format);
3465
3466 rc = xmlTextWriterWriteVFormatDTDAttlist(writer, name, format, ap);
3467
3468 va_end(ap);
3469 return rc;
3470}
3471
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003472/**
3473 * xmlTextWriterWriteVFormatDTDAttlist:
3474 * @writer: the xmlTextWriterPtr
3475 * @name: the name of the DTD ATTLIST
3476 * @format: format string (see printf)
3477 * @argptr: pointer to the first member of the variable argument list.
3478 *
3479 * Write a formatted DTD ATTLIST.
3480 *
3481 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3482 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003483int
3484xmlTextWriterWriteVFormatDTDAttlist(xmlTextWriterPtr writer,
3485 const xmlChar * name,
3486 const char *format, va_list argptr)
3487{
3488 int rc;
3489 xmlChar *buf;
3490
3491 if (writer == NULL)
3492 return -1;
3493
3494 buf = xmlTextWriterVSprintf(format, argptr);
3495 if (buf == 0)
3496 return 0;
3497
3498 rc = xmlTextWriterWriteDTDAttlist(writer, name, buf);
3499
3500 xmlFree(buf);
3501 return rc;
3502}
3503
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003504/**
3505 * xmlTextWriterWriteDTDAttlist:
3506 * @writer: the xmlTextWriterPtr
3507 * @name: the name of the DTD ATTLIST
3508 * @content: content of the ATTLIST
3509 *
3510 * Write a DTD ATTLIST.
3511 *
3512 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3513 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003514int
3515xmlTextWriterWriteDTDAttlist(xmlTextWriterPtr writer,
3516 const xmlChar * name, const xmlChar * content)
3517{
3518 int count;
3519 int sum;
3520
3521 if (content == NULL)
3522 return -1;
3523
3524 sum = 0;
3525 count = xmlTextWriterStartDTDAttlist(writer, name);
3526 if (count == -1)
3527 return -1;
3528 sum += count;
3529
Daniel Veillard1d211e22003-10-20 22:32:39 +00003530 count = xmlTextWriterWriteString(writer, content);
3531 if (count == -1)
3532 return -1;
3533 sum += count;
3534
3535 count = xmlTextWriterEndDTDAttlist(writer);
3536 if (count == -1)
3537 return -1;
3538 sum += count;
3539
3540 return sum;
3541}
3542
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003543/**
3544 * xmlTextWriterStartDTDEntity:
3545 * @writer: the xmlTextWriterPtr
3546 * @pe: TRUE if this is a parameter entity, FALSE if not
3547 * @name: the name of the DTD ATTLIST
3548 *
3549 * Start an xml DTD ATTLIST.
3550 *
3551 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3552 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003553int
3554xmlTextWriterStartDTDEntity(xmlTextWriterPtr writer,
3555 int pe, const xmlChar * name)
3556{
3557 int count;
3558 int sum;
3559 xmlLinkPtr lk;
3560 xmlTextWriterStackEntry *p;
3561
3562 if (writer == NULL || name == NULL || *name == '\0')
3563 return -1;
3564
3565 sum = 0;
3566 lk = xmlListFront(writer->nodes);
Daniel Veillard500a1de2004-03-22 15:22:58 +00003567 if (lk != 0) {
Daniel Veillard1d211e22003-10-20 22:32:39 +00003568
Daniel Veillard500a1de2004-03-22 15:22:58 +00003569 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3570 if (p != 0) {
3571 switch (p->state) {
3572 case XML_TEXTWRITER_DTD:
3573 count = xmlOutputBufferWriteString(writer->out, " [");
3574 if (count < 0)
3575 return -1;
3576 sum += count;
3577 if (writer->indent) {
3578 count =
3579 xmlOutputBufferWriteString(writer->out, "\n");
3580 if (count < 0)
3581 return -1;
3582 sum += count;
3583 }
3584 p->state = XML_TEXTWRITER_DTD_TEXT;
3585 /* fallthrough */
3586 case XML_TEXTWRITER_DTD_TEXT:
3587 case XML_TEXTWRITER_NONE:
3588 break;
3589 default:
3590 return -1;
3591 }
3592 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00003593 }
3594
3595 p = (xmlTextWriterStackEntry *)
3596 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3597 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003598 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003599 "xmlTextWriterStartDTDElement : out of memory!\n");
3600 return -1;
3601 }
3602
3603 p->name = xmlStrdup(name);
3604 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003605 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003606 "xmlTextWriterStartDTDElement : out of memory!\n");
3607 xmlFree(p);
3608 return -1;
3609 }
Daniel Veillard500a1de2004-03-22 15:22:58 +00003610
3611 if (pe != 0)
3612 p->state = XML_TEXTWRITER_DTD_PENT;
3613 else
3614 p->state = XML_TEXTWRITER_DTD_ENTY;
Daniel Veillard1d211e22003-10-20 22:32:39 +00003615
3616 xmlListPushFront(writer->nodes, p);
3617
Daniel Veillard500a1de2004-03-22 15:22:58 +00003618 if (writer->indent) {
3619 count = xmlTextWriterWriteIndent(writer);
3620 if (count < 0)
3621 return -1;
3622 sum += count;
3623 }
3624
Daniel Veillard1d211e22003-10-20 22:32:39 +00003625 count = xmlOutputBufferWriteString(writer->out, "<!ENTITY ");
3626 if (count < 0)
3627 return -1;
3628 sum += count;
3629
3630 if (pe != 0) {
Daniel Veillard500a1de2004-03-22 15:22:58 +00003631 count = xmlOutputBufferWriteString(writer->out, "% ");
Daniel Veillard1d211e22003-10-20 22:32:39 +00003632 if (count < 0)
3633 return -1;
3634 sum += count;
3635 }
3636
Daniel Veillardab69f362004-02-17 11:40:32 +00003637 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003638 if (count < 0)
3639 return -1;
3640 sum += count;
3641
3642 return sum;
3643}
3644
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003645/**
Daniel Veillard500a1de2004-03-22 15:22:58 +00003646 * xmlTextWriterEndDTDEntity:
3647 * @writer: the xmlTextWriterPtr
3648 *
3649 * End an xml DTD entity.
3650 *
3651 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3652 */
3653int
3654xmlTextWriterEndDTDEntity(xmlTextWriterPtr writer)
3655{
3656 int count;
3657 int sum;
3658 xmlLinkPtr lk;
3659 xmlTextWriterStackEntry *p;
3660
3661 if (writer == NULL)
3662 return -1;
3663
3664 sum = 0;
3665 lk = xmlListFront(writer->nodes);
3666 if (lk == 0)
3667 return -1;
3668
3669 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3670 if (p == 0)
3671 return -1;
3672
3673 switch (p->state) {
3674 case XML_TEXTWRITER_DTD_ENTY_TEXT:
3675 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3676 if (count < 0)
3677 return -1;
3678 sum += count;
3679 case XML_TEXTWRITER_DTD_ENTY:
3680 case XML_TEXTWRITER_DTD_PENT:
Daniel Veillard500a1de2004-03-22 15:22:58 +00003681 count = xmlOutputBufferWriteString(writer->out, ">");
3682 if (count < 0)
3683 return -1;
3684 sum += count;
3685 break;
3686 default:
3687 return -1;
3688 }
3689
3690 if (writer->indent) {
3691 count = xmlOutputBufferWriteString(writer->out, "\n");
3692 if (count < 0)
3693 return -1;
3694 sum += count;
3695 }
3696
3697 xmlListPopFront(writer->nodes);
3698 return sum;
3699}
3700
3701/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003702 * xmlTextWriterWriteFormatDTDInternalEntity:
3703 * @writer: the xmlTextWriterPtr
3704 * @pe: TRUE if this is a parameter entity, FALSE if not
3705 * @name: the name of the DTD entity
3706 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003707 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003708 *
3709 * Write a formatted DTD internal entity.
3710 *
3711 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3712 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00003713int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00003714xmlTextWriterWriteFormatDTDInternalEntity(xmlTextWriterPtr writer,
3715 int pe,
3716 const xmlChar * name,
3717 const char *format, ...)
3718{
3719 int rc;
3720 va_list ap;
3721
3722 va_start(ap, format);
3723
3724 rc = xmlTextWriterWriteVFormatDTDInternalEntity(writer, pe, name,
3725 format, ap);
3726
3727 va_end(ap);
3728 return rc;
3729}
3730
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003731/**
3732 * xmlTextWriterWriteVFormatDTDInternalEntity:
3733 * @writer: the xmlTextWriterPtr
3734 * @pe: TRUE if this is a parameter entity, FALSE if not
3735 * @name: the name of the DTD entity
3736 * @format: format string (see printf)
3737 * @argptr: pointer to the first member of the variable argument list.
3738 *
3739 * Write a formatted DTD internal entity.
3740 *
3741 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3742 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003743int
3744xmlTextWriterWriteVFormatDTDInternalEntity(xmlTextWriterPtr writer,
3745 int pe,
3746 const xmlChar * name,
3747 const char *format,
3748 va_list argptr)
3749{
3750 int rc;
3751 xmlChar *buf;
3752
3753 if (writer == NULL)
3754 return -1;
3755
3756 buf = xmlTextWriterVSprintf(format, argptr);
3757 if (buf == 0)
3758 return 0;
3759
3760 rc = xmlTextWriterWriteDTDInternalEntity(writer, pe, name, buf);
3761
3762 xmlFree(buf);
3763 return rc;
3764}
3765
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003766/**
3767 * xmlTextWriterWriteDTDEntity:
3768 * @writer: the xmlTextWriterPtr
3769 * @pe: TRUE if this is a parameter entity, FALSE if not
3770 * @name: the name of the DTD entity
3771 * @pubid: the public identifier, which is an alternative to the system identifier
3772 * @sysid: the system identifier, which is the URI of the DTD
3773 * @ndataid: the xml notation name.
3774 * @content: content of the entity
3775 *
3776 * Write a DTD entity.
3777 *
3778 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3779 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003780int
3781xmlTextWriterWriteDTDEntity(xmlTextWriterPtr writer,
3782 int pe,
3783 const xmlChar * name,
3784 const xmlChar * pubid,
3785 const xmlChar * sysid,
3786 const xmlChar * ndataid,
3787 const xmlChar * content)
3788{
Daniel Veillard500a1de2004-03-22 15:22:58 +00003789 if ((content == NULL) && (pubid == NULL) && (sysid == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00003790 return -1;
3791 if ((pe != 0) && (ndataid != NULL))
3792 return -1;
3793
Daniel Veillard500a1de2004-03-22 15:22:58 +00003794 if ((pubid == NULL) && (sysid == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00003795 return xmlTextWriterWriteDTDInternalEntity(writer, pe, name,
3796 content);
3797
3798 return xmlTextWriterWriteDTDExternalEntity(writer, pe, name, pubid,
3799 sysid, ndataid);
3800}
3801
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003802/**
3803 * xmlTextWriterWriteDTDInternalEntity:
3804 * @writer: the xmlTextWriterPtr
3805 * @pe: TRUE if this is a parameter entity, FALSE if not
3806 * @name: the name of the DTD entity
3807 * @content: content of the entity
3808 *
3809 * Write a DTD internal entity.
3810 *
3811 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3812 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003813int
3814xmlTextWriterWriteDTDInternalEntity(xmlTextWriterPtr writer,
3815 int pe,
3816 const xmlChar * name,
3817 const xmlChar * content)
3818{
3819 int count;
3820 int sum;
3821
3822 if ((name == NULL) || (*name == '\0') || (content == NULL))
3823 return -1;
3824
3825 sum = 0;
3826 count = xmlTextWriterStartDTDEntity(writer, pe, name);
3827 if (count == -1)
3828 return -1;
3829 sum += count;
3830
Daniel Veillard1d211e22003-10-20 22:32:39 +00003831 count = xmlTextWriterWriteString(writer, content);
3832 if (count == -1)
3833 return -1;
3834 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00003835
3836 count = xmlTextWriterEndDTDEntity(writer);
3837 if (count == -1)
3838 return -1;
3839 sum += count;
3840
3841 return sum;
3842}
3843
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003844/**
3845 * xmlTextWriterWriteDTDExternalEntity:
3846 * @writer: the xmlTextWriterPtr
3847 * @pe: TRUE if this is a parameter entity, FALSE if not
3848 * @name: the name of the DTD entity
3849 * @pubid: the public identifier, which is an alternative to the system identifier
3850 * @sysid: the system identifier, which is the URI of the DTD
3851 * @ndataid: the xml notation name.
3852 *
Daniel Veillard500a1de2004-03-22 15:22:58 +00003853 * Write a DTD external entity. The entity must have been started with xmlTextWriterStartDTDEntity
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003854 *
3855 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3856 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003857int
3858xmlTextWriterWriteDTDExternalEntity(xmlTextWriterPtr writer,
3859 int pe,
3860 const xmlChar * name,
3861 const xmlChar * pubid,
3862 const xmlChar * sysid,
3863 const xmlChar * ndataid)
3864{
3865 int count;
3866 int sum;
3867
Daniel Veillard500a1de2004-03-22 15:22:58 +00003868 if (((pubid == NULL) && (sysid == NULL)))
Daniel Veillard1d211e22003-10-20 22:32:39 +00003869 return -1;
3870 if ((pe != 0) && (ndataid != NULL))
3871 return -1;
3872
3873 sum = 0;
3874 count = xmlTextWriterStartDTDEntity(writer, pe, name);
3875 if (count == -1)
3876 return -1;
3877 sum += count;
3878
Daniel Veillard500a1de2004-03-22 15:22:58 +00003879 count =
3880 xmlTextWriterWriteDTDExternalEntityContents(writer, pubid, sysid,
3881 ndataid);
3882 if (count < 0)
3883 return -1;
3884 sum += count;
3885
3886 count = xmlTextWriterEndDTDEntity(writer);
3887 if (count == -1)
3888 return -1;
3889 sum += count;
3890
3891 return sum;
3892}
3893
3894/**
3895 * xmlTextWriterWriteDTDExternalEntityContents:
3896 * @writer: the xmlTextWriterPtr
3897 * @pubid: the public identifier, which is an alternative to the system identifier
3898 * @sysid: the system identifier, which is the URI of the DTD
3899 * @ndataid: the xml notation name.
3900 *
3901 * Write the contents of a DTD external entity.
3902 *
3903 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3904 */
3905int
3906xmlTextWriterWriteDTDExternalEntityContents(xmlTextWriterPtr writer,
3907 const xmlChar * pubid,
3908 const xmlChar * sysid,
3909 const xmlChar * ndataid)
3910{
3911 int count;
3912 int sum;
3913 xmlLinkPtr lk;
3914 xmlTextWriterStackEntry *p;
3915
3916 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003917 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003918 "xmlTextWriterWriteDTDExternalEntityContents: xmlTextWriterPtr invalid!\n");
3919 return -1;
3920 }
3921
3922 sum = 0;
3923 lk = xmlListFront(writer->nodes);
3924 if (lk == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003925 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003926 "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n");
3927 return -1;
3928 }
3929
3930 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3931 if (p == 0)
3932 return -1;
3933
3934 switch (p->state) {
3935 case XML_TEXTWRITER_DTD_ENTY:
3936 break;
3937 case XML_TEXTWRITER_DTD_PENT:
3938 if (ndataid != NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003939 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003940 "xmlTextWriterWriteDTDExternalEntityContents: notation not allowed with parameter entities!\n");
3941 return -1;
3942 }
3943 break;
3944 default:
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003945 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003946 "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n");
3947 return -1;
3948 }
3949
Daniel Veillard1d211e22003-10-20 22:32:39 +00003950 if (pubid != 0) {
3951 if (sysid == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003952 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003953 "xmlTextWriterWriteDTDExternalEntityContents: system identifier needed!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +00003954 return -1;
3955 }
3956
3957 count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
3958 if (count < 0)
3959 return -1;
3960 sum += count;
3961
3962 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3963 if (count < 0)
3964 return -1;
3965 sum += count;
3966
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003967 count =
3968 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003969 if (count < 0)
3970 return -1;
3971 sum += count;
3972
3973 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3974 if (count < 0)
3975 return -1;
3976 sum += count;
3977 }
3978
3979 if (sysid != 0) {
3980 if (pubid == 0) {
3981 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
3982 if (count < 0)
3983 return -1;
3984 sum += count;
3985 }
3986
3987 count = xmlOutputBufferWriteString(writer->out, " ");
3988 if (count < 0)
3989 return -1;
3990 sum += count;
3991
3992 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3993 if (count < 0)
3994 return -1;
3995 sum += count;
3996
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003997 count =
3998 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003999 if (count < 0)
4000 return -1;
4001 sum += count;
4002
4003 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4004 if (count < 0)
4005 return -1;
4006 sum += count;
4007 }
4008
4009 if (ndataid != NULL) {
4010 count = xmlOutputBufferWriteString(writer->out, " NDATA ");
4011 if (count < 0)
4012 return -1;
4013 sum += count;
4014
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004015 count =
4016 xmlOutputBufferWriteString(writer->out,
4017 (const char *) ndataid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004018 if (count < 0)
4019 return -1;
4020 sum += count;
4021 }
4022
Daniel Veillard1d211e22003-10-20 22:32:39 +00004023 return sum;
4024}
4025
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004026/**
4027 * xmlTextWriterWriteDTDNotation:
4028 * @writer: the xmlTextWriterPtr
4029 * @name: the name of the xml notation
4030 * @pubid: the public identifier, which is an alternative to the system identifier
4031 * @sysid: the system identifier, which is the URI of the DTD
4032 *
4033 * Write a DTD entity.
4034 *
4035 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
4036 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00004037int
4038xmlTextWriterWriteDTDNotation(xmlTextWriterPtr writer,
4039 const xmlChar * name,
4040 const xmlChar * pubid, const xmlChar * sysid)
4041{
4042 int count;
4043 int sum;
4044 xmlLinkPtr lk;
4045 xmlTextWriterStackEntry *p;
4046
4047 if (writer == NULL || name == NULL || *name == '\0')
4048 return -1;
4049
4050 sum = 0;
4051 lk = xmlListFront(writer->nodes);
4052 if (lk == 0) {
4053 return -1;
4054 }
4055
4056 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
Daniel Veillard500a1de2004-03-22 15:22:58 +00004057 if (p != 0) {
4058 switch (p->state) {
4059 case XML_TEXTWRITER_DTD:
4060 count = xmlOutputBufferWriteString(writer->out, " [");
4061 if (count < 0)
4062 return -1;
4063 sum += count;
4064 if (writer->indent) {
4065 count = xmlOutputBufferWriteString(writer->out, "\n");
4066 if (count < 0)
4067 return -1;
4068 sum += count;
4069 }
4070 p->state = XML_TEXTWRITER_DTD_TEXT;
4071 /* fallthrough */
4072 case XML_TEXTWRITER_DTD_TEXT:
4073 break;
4074 default:
4075 return -1;
4076 }
4077 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00004078
Daniel Veillard500a1de2004-03-22 15:22:58 +00004079 if (writer->indent) {
4080 count = xmlTextWriterWriteIndent(writer);
4081 if (count < 0)
Daniel Veillard1d211e22003-10-20 22:32:39 +00004082 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00004083 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00004084 }
4085
4086 count = xmlOutputBufferWriteString(writer->out, "<!NOTATION ");
4087 if (count < 0)
4088 return -1;
4089 sum += count;
4090 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
4091 if (count < 0)
4092 return -1;
4093 sum += count;
4094
4095 if (pubid != 0) {
4096 count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
4097 if (count < 0)
4098 return -1;
4099 sum += count;
4100 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4101 if (count < 0)
4102 return -1;
4103 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004104 count =
4105 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004106 if (count < 0)
4107 return -1;
4108 sum += count;
4109 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4110 if (count < 0)
4111 return -1;
4112 sum += count;
4113 }
4114
4115 if (sysid != 0) {
4116 if (pubid == 0) {
4117 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
4118 if (count < 0)
4119 return -1;
4120 sum += count;
4121 }
4122 count = xmlOutputBufferWriteString(writer->out, " ");
4123 if (count < 0)
4124 return -1;
4125 sum += count;
4126 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4127 if (count < 0)
4128 return -1;
4129 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004130 count =
4131 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004132 if (count < 0)
4133 return -1;
4134 sum += count;
4135 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4136 if (count < 0)
4137 return -1;
4138 sum += count;
4139 }
4140
4141 count = xmlOutputBufferWriteString(writer->out, ">");
4142 if (count < 0)
4143 return -1;
4144 sum += count;
4145
4146 return sum;
4147}
4148
4149/**
4150 * xmlTextWriterFlush:
4151 * @writer: the xmlTextWriterPtr
4152 *
4153 * Flush the output buffer.
4154 *
4155 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
4156 */
4157int
4158xmlTextWriterFlush(xmlTextWriterPtr writer)
4159{
4160 int count;
4161
4162 if (writer == NULL)
4163 return -1;
4164
4165 if (writer->out == NULL)
4166 count = 0;
4167 else
4168 count = xmlOutputBufferFlush(writer->out);
4169
4170 return count;
4171}
4172
4173/**
4174 * misc
4175 */
4176
4177/**
4178 * xmlFreeTextWriterStackEntry:
4179 * @lk: the xmlLinkPtr
4180 *
4181 * Free callback for the xmlList.
4182 */
4183static void
4184xmlFreeTextWriterStackEntry(xmlLinkPtr lk)
4185{
4186 xmlTextWriterStackEntry *p;
4187
4188 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
4189 if (p == 0)
4190 return;
4191
4192 if (p->name != 0)
4193 xmlFree(p->name);
4194 xmlFree(p);
4195}
4196
4197/**
4198 * xmlCmpTextWriterStackEntry:
4199 * @data0: the first data
4200 * @data1: the second data
4201 *
4202 * Compare callback for the xmlList.
4203 *
4204 * Returns -1, 0, 1
4205 */
4206static int
4207xmlCmpTextWriterStackEntry(const void *data0, const void *data1)
4208{
4209 xmlTextWriterStackEntry *p0;
4210 xmlTextWriterStackEntry *p1;
4211
4212 if (data0 == data1)
4213 return 0;
4214
4215 if (data0 == 0)
4216 return -1;
4217
4218 if (data1 == 0)
4219 return 1;
4220
4221 p0 = (xmlTextWriterStackEntry *) data0;
4222 p1 = (xmlTextWriterStackEntry *) data1;
4223
4224 return xmlStrcmp(p0->name, p1->name);
4225}
4226
4227/**
4228 * misc
4229 */
4230
4231/**
4232 * xmlFreeTextWriterNsStackEntry:
4233 * @lk: the xmlLinkPtr
4234 *
4235 * Free callback for the xmlList.
4236 */
4237static void
4238xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk)
4239{
4240 xmlTextWriterNsStackEntry *p;
4241
4242 p = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
4243 if (p == 0)
4244 return;
4245
4246 if (p->prefix != 0)
4247 xmlFree(p->prefix);
4248 if (p->uri != 0)
4249 xmlFree(p->uri);
4250
4251 xmlFree(p);
4252}
4253
4254/**
4255 * xmlCmpTextWriterNsStackEntry:
4256 * @data0: the first data
4257 * @data1: the second data
4258 *
4259 * Compare callback for the xmlList.
4260 *
4261 * Returns -1, 0, 1
4262 */
4263static int
4264xmlCmpTextWriterNsStackEntry(const void *data0, const void *data1)
4265{
4266 xmlTextWriterNsStackEntry *p0;
4267 xmlTextWriterNsStackEntry *p1;
4268 int rc;
4269
4270 if (data0 == data1)
4271 return 0;
4272
4273 if (data0 == 0)
4274 return -1;
4275
4276 if (data1 == 0)
4277 return 1;
4278
4279 p0 = (xmlTextWriterNsStackEntry *) data0;
4280 p1 = (xmlTextWriterNsStackEntry *) data1;
4281
4282 rc = xmlStrcmp(p0->prefix, p1->prefix);
4283
4284 if (rc == 0)
4285 rc = p0->elem == p1->elem;
4286
4287 return rc;
4288}
4289
4290/**
4291 * xmlTextWriterWriteMemCallback:
4292 * @context: the xmlBufferPtr
4293 * @str: the data to write
4294 * @len: the length of the data
4295 *
4296 * Write callback for the xmlOutputBuffer with target xmlBuffer
4297 *
4298 * Returns -1, 0, 1
4299 */
4300static int
4301xmlTextWriterWriteMemCallback(void *context, const xmlChar * str, int len)
4302{
4303 xmlBufferPtr buf = (xmlBufferPtr) context;
4304
4305 xmlBufferAdd(buf, str, len);
4306
4307 return len;
4308}
4309
4310/**
4311 * xmlTextWriterCloseMemCallback:
4312 * @context: the xmlBufferPtr
4313 *
4314 * Close callback for the xmlOutputBuffer with target xmlBuffer
4315 *
4316 * Returns -1, 0, 1
4317 */
4318static int
4319xmlTextWriterCloseMemCallback(void *context ATTRIBUTE_UNUSED)
4320{
4321 return 0;
4322}
4323
4324/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004325 * xmlTextWriterWriteDocCallback:
4326 * @context: the xmlBufferPtr
4327 * @str: the data to write
4328 * @len: the length of the data
4329 *
4330 * Write callback for the xmlOutputBuffer with target xmlBuffer
4331 *
4332 * Returns -1, 0, 1
4333 */
4334static int
4335xmlTextWriterWriteDocCallback(void *context, const xmlChar * str, int len)
4336{
4337 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context;
4338 int rc;
4339
Daniel Veillard1d913862003-11-21 00:28:39 +00004340 if ((rc = xmlParseChunk(ctxt, (const char *) str, len, 0)) != 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004341 xmlWriterErrMsgInt(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004342 "xmlTextWriterWriteDocCallback : XML error %d !\n",
4343 rc);
4344 return -1;
4345 }
4346
4347 return len;
4348}
4349
4350/**
4351 * xmlTextWriterCloseDocCallback:
4352 * @context: the xmlBufferPtr
4353 *
4354 * Close callback for the xmlOutputBuffer with target xmlBuffer
4355 *
4356 * Returns -1, 0, 1
4357 */
4358static int
4359xmlTextWriterCloseDocCallback(void *context)
4360{
4361 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context;
4362 int rc;
4363
4364 if ((rc = xmlParseChunk(ctxt, NULL, 0, 1)) != 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004365 xmlWriterErrMsgInt(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004366 "xmlTextWriterWriteDocCallback : XML error %d !\n",
4367 rc);
4368 return -1;
4369 }
4370
4371 return 0;
4372}
4373
4374/**
Daniel Veillard1d211e22003-10-20 22:32:39 +00004375 * xmlTextWriterVSprintf:
4376 * @format: see printf
4377 * @argptr: pointer to the first member of the variable argument list.
4378 *
4379 * Utility function for formatted output
4380 *
4381 * Returns a new xmlChar buffer with the data or NULL on error. This buffer must be freed.
4382 */
4383static xmlChar *
4384xmlTextWriterVSprintf(const char *format, va_list argptr)
4385{
4386 int size;
4387 int count;
4388 xmlChar *buf;
William M. Brackf4caa5e2005-10-20 09:04:05 +00004389 va_list locarg;
Daniel Veillard1d211e22003-10-20 22:32:39 +00004390
4391 size = BUFSIZ;
4392 buf = (xmlChar *) xmlMalloc(size);
4393 if (buf == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004394 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00004395 "xmlTextWriterVSprintf : out of memory!\n");
4396 return NULL;
4397 }
4398
William M. Brackf4caa5e2005-10-20 09:04:05 +00004399 VA_COPY(locarg, argptr);
4400 while (((count = vsnprintf((char *) buf, size, format, locarg)) < 0)
Daniel Veillard1d211e22003-10-20 22:32:39 +00004401 || (count == size - 1) || (count == size) || (count > size)) {
William M. Brackf4caa5e2005-10-20 09:04:05 +00004402 va_end(locarg);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004403 xmlFree(buf);
4404 size += BUFSIZ;
4405 buf = (xmlChar *) xmlMalloc(size);
4406 if (buf == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004407 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00004408 "xmlTextWriterVSprintf : out of memory!\n");
4409 return NULL;
4410 }
William M. Brackf4caa5e2005-10-20 09:04:05 +00004411 VA_COPY(locarg, argptr);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004412 }
William M. Brackf4caa5e2005-10-20 09:04:05 +00004413 va_end(locarg);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004414
4415 return buf;
4416}
4417
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004418/**
4419 * xmlTextWriterStartDocumentCallback:
4420 * @ctx: the user data (XML parser context)
4421 *
4422 * called at the start of document processing.
4423 */
4424static void
4425xmlTextWriterStartDocumentCallback(void *ctx)
4426{
4427 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
4428 xmlDocPtr doc;
4429
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004430 if (ctxt->html) {
4431#ifdef LIBXML_HTML_ENABLED
4432 if (ctxt->myDoc == NULL)
4433 ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
4434 if (ctxt->myDoc == NULL) {
4435 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
4436 ctxt->sax->error(ctxt->userData,
4437 "SAX.startDocument(): out of memory\n");
4438 ctxt->errNo = XML_ERR_NO_MEMORY;
4439 ctxt->instate = XML_PARSER_EOF;
4440 ctxt->disableSAX = 1;
4441 return;
4442 }
4443#else
Daniel Veillardd0cf7f62004-11-09 16:17:02 +00004444 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004445 "libxml2 built without HTML support\n");
4446 ctxt->errNo = XML_ERR_INTERNAL_ERROR;
4447 ctxt->instate = XML_PARSER_EOF;
4448 ctxt->disableSAX = 1;
4449 return;
4450#endif
4451 } else {
4452 doc = ctxt->myDoc;
4453 if (doc == NULL)
4454 doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
4455 if (doc != NULL) {
4456 if (doc->children == NULL) {
4457 if (ctxt->encoding != NULL)
4458 doc->encoding = xmlStrdup(ctxt->encoding);
4459 else
4460 doc->encoding = NULL;
4461 doc->standalone = ctxt->standalone;
4462 }
4463 } else {
4464 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
4465 ctxt->sax->error(ctxt->userData,
4466 "SAX.startDocument(): out of memory\n");
4467 ctxt->errNo = XML_ERR_NO_MEMORY;
4468 ctxt->instate = XML_PARSER_EOF;
4469 ctxt->disableSAX = 1;
4470 return;
4471 }
4472 }
4473 if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) &&
4474 (ctxt->input != NULL) && (ctxt->input->filename != NULL)) {
4475 ctxt->myDoc->URL =
4476 xmlCanonicPath((const xmlChar *) ctxt->input->filename);
4477 if (ctxt->myDoc->URL == NULL)
4478 ctxt->myDoc->URL =
4479 xmlStrdup((const xmlChar *) ctxt->input->filename);
4480 }
4481}
4482
Daniel Veillard2cca4462004-01-02 20:04:23 +00004483/**
4484 * xmlTextWriterSetIndent:
4485 * @writer: the xmlTextWriterPtr
4486 * @indent: do indentation?
4487 *
4488 * Set indentation output. indent = 0 do not indentation. indent > 0 do indentation.
4489 *
4490 * Returns -1 on error or 0 otherwise.
4491 */
4492int
Daniel Veillardab69f362004-02-17 11:40:32 +00004493xmlTextWriterSetIndent(xmlTextWriterPtr writer, int indent)
Daniel Veillard2cca4462004-01-02 20:04:23 +00004494{
Daniel Veillarde43cc572004-11-03 11:50:29 +00004495 if ((writer == NULL) || (indent < 0))
Daniel Veillardab69f362004-02-17 11:40:32 +00004496 return -1;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004497
Daniel Veillardab69f362004-02-17 11:40:32 +00004498 writer->indent = indent;
4499 writer->doindent = 1;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004500
Daniel Veillardab69f362004-02-17 11:40:32 +00004501 return 0;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004502}
4503
4504/**
4505 * xmlTextWriterSetIndentString:
4506 * @writer: the xmlTextWriterPtr
4507 * @str: the xmlChar string
4508 *
4509 * Set string indentation.
4510 *
4511 * Returns -1 on error or 0 otherwise.
4512 */
4513int
Daniel Veillardab69f362004-02-17 11:40:32 +00004514xmlTextWriterSetIndentString(xmlTextWriterPtr writer, const xmlChar * str)
Daniel Veillard2cca4462004-01-02 20:04:23 +00004515{
Daniel Veillarde43cc572004-11-03 11:50:29 +00004516 if ((writer == NULL) || (!str))
Daniel Veillardab69f362004-02-17 11:40:32 +00004517 return -1;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004518
Daniel Veillardab69f362004-02-17 11:40:32 +00004519 if (writer->ichar != NULL)
4520 xmlFree(writer->ichar);
4521 writer->ichar = xmlStrdup(str);
4522
4523 if (!writer->ichar)
4524 return -1;
4525 else
4526 return 0;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004527}
4528
4529/**
4530 * xmlTextWriterWriteIndent:
4531 * @writer: the xmlTextWriterPtr
4532 *
4533 * Write indent string.
4534 *
4535 * Returns -1 on error or the number of strings written.
Daniel Veillardab69f362004-02-17 11:40:32 +00004536 */
Daniel Veillard2cca4462004-01-02 20:04:23 +00004537static int
Daniel Veillardab69f362004-02-17 11:40:32 +00004538xmlTextWriterWriteIndent(xmlTextWriterPtr writer)
Daniel Veillard2cca4462004-01-02 20:04:23 +00004539{
Daniel Veillardab69f362004-02-17 11:40:32 +00004540 int lksize;
4541 int i;
4542 int ret;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004543
Daniel Veillardab69f362004-02-17 11:40:32 +00004544 lksize = xmlListSize(writer->nodes);
4545 if (lksize < 1)
4546 return (-1); /* list is empty */
4547 for (i = 0; i < (lksize - 1); i++) {
4548 ret = xmlOutputBufferWriteString(writer->out,
4549 (const char *) writer->ichar);
4550 if (ret == -1)
4551 return (-1);
4552 }
4553
4554 return (lksize - 1);
Daniel Veillard2cca4462004-01-02 20:04:23 +00004555}
4556
Daniel Veillard500a1de2004-03-22 15:22:58 +00004557/**
4558 * xmlTextWriterHandleStateDependencies:
4559 * @writer: the xmlTextWriterPtr
4560 * @p: the xmlTextWriterStackEntry
4561 *
4562 * Write state dependent strings.
4563 *
4564 * Returns -1 on error or the number of characters written.
4565 */
4566static int
4567xmlTextWriterHandleStateDependencies(xmlTextWriterPtr writer,
4568 xmlTextWriterStackEntry * p)
4569{
4570 int count;
4571 int sum;
4572 char extra[3];
4573
4574 if (writer == NULL)
4575 return -1;
4576
4577 if (p == NULL)
4578 return 0;
4579
4580 sum = 0;
4581 extra[0] = extra[1] = extra[2] = '\0';
4582 if (p != 0) {
4583 sum = 0;
4584 switch (p->state) {
4585 case XML_TEXTWRITER_NAME:
4586 extra[0] = '>';
4587 p->state = XML_TEXTWRITER_TEXT;
4588 break;
4589 case XML_TEXTWRITER_PI:
4590 extra[0] = ' ';
4591 p->state = XML_TEXTWRITER_PI_TEXT;
4592 break;
4593 case XML_TEXTWRITER_DTD:
4594 extra[0] = ' ';
4595 extra[1] = '[';
4596 p->state = XML_TEXTWRITER_DTD_TEXT;
4597 break;
4598 case XML_TEXTWRITER_DTD_ELEM:
4599 extra[0] = ' ';
4600 p->state = XML_TEXTWRITER_DTD_ELEM_TEXT;
4601 break;
4602 case XML_TEXTWRITER_DTD_ATTL:
4603 extra[0] = ' ';
4604 p->state = XML_TEXTWRITER_DTD_ATTL_TEXT;
4605 break;
4606 case XML_TEXTWRITER_DTD_ENTY:
4607 case XML_TEXTWRITER_DTD_PENT:
4608 extra[0] = ' ';
4609 extra[1] = writer->qchar;
4610 p->state = XML_TEXTWRITER_DTD_ENTY_TEXT;
4611 break;
4612 default:
4613 break;
4614 }
4615 }
4616
4617 if (*extra != '\0') {
4618 count = xmlOutputBufferWriteString(writer->out, extra);
4619 if (count < 0)
4620 return -1;
4621 sum += count;
4622 }
4623
4624 return sum;
4625}
4626
Daniel Veillard5d4644e2005-04-01 13:11:58 +00004627#define bottom_xmlwriter
4628#include "elfgcchack.h"
Daniel Veillard1d211e22003-10-20 22:32:39 +00004629#endif