blob: 6224222d279ed74143a222310aeb674fbf9313f6 [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/*
28 * Types are kept private
29 */
30typedef enum {
31 XML_TEXTWRITER_NONE = 0,
32 XML_TEXTWRITER_NAME,
33 XML_TEXTWRITER_ATTRIBUTE,
34 XML_TEXTWRITER_TEXT,
35 XML_TEXTWRITER_PI,
36 XML_TEXTWRITER_PI_TEXT,
37 XML_TEXTWRITER_CDATA,
38 XML_TEXTWRITER_DTD,
39 XML_TEXTWRITER_DTD_TEXT,
40 XML_TEXTWRITER_DTD_ELEM,
Daniel Veillard500a1de2004-03-22 15:22:58 +000041 XML_TEXTWRITER_DTD_ELEM_TEXT,
Daniel Veillard1d211e22003-10-20 22:32:39 +000042 XML_TEXTWRITER_DTD_ATTL,
Daniel Veillard500a1de2004-03-22 15:22:58 +000043 XML_TEXTWRITER_DTD_ATTL_TEXT,
44 XML_TEXTWRITER_DTD_ENTY, /* entity */
45 XML_TEXTWRITER_DTD_ENTY_TEXT,
46 XML_TEXTWRITER_DTD_PENT, /* parameter entity */
William M. Brack87640d52004-04-17 14:58:15 +000047 XML_TEXTWRITER_COMMENT
Daniel Veillard1d211e22003-10-20 22:32:39 +000048} xmlTextWriterState;
49
50typedef struct _xmlTextWriterStackEntry xmlTextWriterStackEntry;
51
52struct _xmlTextWriterStackEntry {
53 xmlChar *name;
54 xmlTextWriterState state;
55};
56
57typedef struct _xmlTextWriterNsStackEntry xmlTextWriterNsStackEntry;
58struct _xmlTextWriterNsStackEntry {
59 xmlChar *prefix;
60 xmlChar *uri;
61 xmlLinkPtr elem;
62};
63
64struct _xmlTextWriter {
Daniel Veillardab69f362004-02-17 11:40:32 +000065 xmlOutputBufferPtr out; /* output buffer */
66 xmlListPtr nodes; /* element name stack */
67 xmlListPtr nsstack; /* name spaces stack */
Daniel Veillard1d211e22003-10-20 22:32:39 +000068 int level;
Daniel Veillardab69f362004-02-17 11:40:32 +000069 int indent; /* enable indent */
70 int doindent; /* internal indent flag */
71 xmlChar *ichar; /* indent character */
72 char qchar; /* character used for quoting attribute values */
Daniel Veillard20c5e782004-01-21 09:57:31 +000073 xmlParserCtxtPtr ctxt;
Daniel Veillarda521d282004-11-09 14:59:59 +000074 int no_doc_free;
Daniel Veillard1d211e22003-10-20 22:32:39 +000075};
76
77static void xmlFreeTextWriterStackEntry(xmlLinkPtr lk);
78static int xmlCmpTextWriterStackEntry(const void *data0,
79 const void *data1);
80static void xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk);
81static int xmlCmpTextWriterNsStackEntry(const void *data0,
82 const void *data1);
83static int xmlTextWriterWriteMemCallback(void *context,
84 const xmlChar * str, int len);
85static int xmlTextWriterCloseMemCallback(void *context);
Daniel Veillard5841f0e2003-11-20 11:59:09 +000086static int xmlTextWriterWriteDocCallback(void *context,
87 const xmlChar * str, int len);
88static int xmlTextWriterCloseDocCallback(void *context);
89
Daniel Veillard1d211e22003-10-20 22:32:39 +000090static xmlChar *xmlTextWriterVSprintf(const char *format, va_list argptr);
91static int xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len,
92 const unsigned char *data);
Daniel Veillard5841f0e2003-11-20 11:59:09 +000093static void xmlTextWriterStartDocumentCallback(void *ctx);
Daniel Veillardab69f362004-02-17 11:40:32 +000094static int xmlTextWriterWriteIndent(xmlTextWriterPtr writer);
Daniel Veillard500a1de2004-03-22 15:22:58 +000095static int
96 xmlTextWriterHandleStateDependencies(xmlTextWriterPtr writer,
97 xmlTextWriterStackEntry * p);
Daniel Veillard1d211e22003-10-20 22:32:39 +000098
99/**
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000100 * xmlWriterErrMsg:
101 * @ctxt: a writer context
102 * @error: the error number
103 * @msg: the error message
104 *
105 * Handle a writer error
106 */
107static void
108xmlWriterErrMsg(xmlTextWriterPtr ctxt, xmlParserErrors error,
109 const char *msg)
110{
111 if (ctxt != NULL) {
112 __xmlRaiseError(NULL, NULL, NULL, ctxt->ctxt,
113 NULL, XML_FROM_WRITER, error, XML_ERR_FATAL,
114 NULL, 0, NULL, NULL, NULL, 0, 0, msg);
115 } else {
116 __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_WRITER, error,
117 XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, 0, 0, msg);
118 }
119}
120
121/**
122 * xmlWriterErrMsgInt:
123 * @ctxt: a writer context
124 * @error: the error number
125 * @msg: the error message
126 * @val: an int
127 *
128 * Handle a writer error
129 */
130static void
131xmlWriterErrMsgInt(xmlTextWriterPtr ctxt, xmlParserErrors error,
132 const char *msg, int val)
133{
134 if (ctxt != NULL) {
135 __xmlRaiseError(NULL, NULL, NULL, ctxt->ctxt,
136 NULL, XML_FROM_WRITER, error, XML_ERR_FATAL,
137 NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
138 } else {
139 __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_WRITER, error,
140 XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
141 }
142}
143
144/**
Daniel Veillard1d211e22003-10-20 22:32:39 +0000145 * xmlNewTextWriter:
146 * @out: an xmlOutputBufferPtr
147 *
148 * Create a new xmlNewTextWriter structure using an xmlOutputBufferPtr
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000149 * NOTE: the @out parameter will be deallocated when the writer is closed
150 * (if the call succeed.)
Daniel Veillard1d211e22003-10-20 22:32:39 +0000151 *
152 * Returns the new xmlTextWriterPtr or NULL in case of error
153 */
154xmlTextWriterPtr
155xmlNewTextWriter(xmlOutputBufferPtr out)
156{
157 xmlTextWriterPtr ret;
158
159 ret = (xmlTextWriterPtr) xmlMalloc(sizeof(xmlTextWriter));
160 if (ret == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000161 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000162 "xmlNewTextWriter : out of memory!\n");
163 return NULL;
164 }
165 memset(ret, 0, (size_t) sizeof(xmlTextWriter));
166
167 ret->nodes = xmlListCreate((xmlListDeallocator)
168 xmlFreeTextWriterStackEntry,
169 (xmlListDataCompare)
170 xmlCmpTextWriterStackEntry);
171 if (ret->nodes == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000172 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000173 "xmlNewTextWriter : out of memory!\n");
174 xmlFree(ret);
175 return NULL;
176 }
177
178 ret->nsstack = xmlListCreate((xmlListDeallocator)
179 xmlFreeTextWriterNsStackEntry,
180 (xmlListDataCompare)
181 xmlCmpTextWriterNsStackEntry);
182 if (ret->nsstack == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000183 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000184 "xmlNewTextWriter : out of memory!\n");
Daniel Veillard500a1de2004-03-22 15:22:58 +0000185 xmlListDelete(ret->nodes);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000186 xmlFree(ret);
187 return NULL;
188 }
189
190 ret->out = out;
Daniel Veillardab69f362004-02-17 11:40:32 +0000191 ret->ichar = xmlStrdup(BAD_CAST " ");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000192 ret->qchar = '"';
193
Daniel Veillard500a1de2004-03-22 15:22:58 +0000194 if (!ret->ichar) {
195 xmlListDelete(ret->nodes);
196 xmlListDelete(ret->nsstack);
197 xmlFree(ret);
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000198 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000199 "xmlNewTextWriter : out of memory!\n");
Daniel Veillardab69f362004-02-17 11:40:32 +0000200 return NULL;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000201 }
Daniel Veillarda521d282004-11-09 14:59:59 +0000202 ret->no_doc_free = 0;
Daniel Veillardab69f362004-02-17 11:40:32 +0000203
Daniel Veillard1d211e22003-10-20 22:32:39 +0000204 return ret;
205}
206
207/**
208 * xmlNewTextWriterFilename:
209 * @uri: the URI of the resource for the output
210 * @compression: compress the output?
211 *
212 * Create a new xmlNewTextWriter structure with @uri as output
213 *
214 * Returns the new xmlTextWriterPtr or NULL in case of error
215 */
216xmlTextWriterPtr
217xmlNewTextWriterFilename(const char *uri, int compression)
218{
219 xmlTextWriterPtr ret;
220 xmlOutputBufferPtr out;
221
222 out = xmlOutputBufferCreateFilename(uri, NULL, compression);
223 if (out == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000224 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000225 "xmlNewTextWriterFilename : out of memory!\n");
226 return NULL;
227 }
228
229 ret = xmlNewTextWriter(out);
230 if (ret == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000231 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000232 "xmlNewTextWriterFilename : out of memory!\n");
233 xmlOutputBufferClose(out);
234 return NULL;
235 }
236
Daniel Veillard2cca4462004-01-02 20:04:23 +0000237 ret->indent = 0;
238 ret->doindent = 0;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000239 return ret;
240}
241
242/**
243 * xmlNewTextWriterMemory:
244 * @buf: xmlBufferPtr
245 * @compression: compress the output?
246 *
247 * Create a new xmlNewTextWriter structure with @buf as output
248 * TODO: handle compression
249 *
250 * Returns the new xmlTextWriterPtr or NULL in case of error
251 */
252xmlTextWriterPtr
253xmlNewTextWriterMemory(xmlBufferPtr buf, int compression ATTRIBUTE_UNUSED)
254{
255 xmlTextWriterPtr ret;
256 xmlOutputBufferPtr out;
257
258/*::todo handle compression */
259 out = xmlOutputBufferCreateIO((xmlOutputWriteCallback)
260 xmlTextWriterWriteMemCallback,
261 (xmlOutputCloseCallback)
262 xmlTextWriterCloseMemCallback,
263 (void *) buf, NULL);
264 if (out == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000265 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000266 "xmlNewTextWriterMemory : out of memory!\n");
267 return NULL;
268 }
269
270 ret = xmlNewTextWriter(out);
271 if (ret == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000272 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000273 "xmlNewTextWriterMemory : out of memory!\n");
274 xmlOutputBufferClose(out);
275 return NULL;
276 }
277
278 return ret;
279}
280
281/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000282 * xmlNewTextWriterPushParser:
283 * @ctxt: xmlParserCtxtPtr to hold the new XML document tree
284 * @compression: compress the output?
285 *
286 * Create a new xmlNewTextWriter structure with @ctxt as output
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000287 * NOTE: the @ctxt context will be freed with the resulting writer
288 * (if the call succeeds).
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000289 * TODO: handle compression
290 *
291 * Returns the new xmlTextWriterPtr or NULL in case of error
292 */
293xmlTextWriterPtr
Daniel Veillard1d913862003-11-21 00:28:39 +0000294xmlNewTextWriterPushParser(xmlParserCtxtPtr ctxt,
295 int compression ATTRIBUTE_UNUSED)
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000296{
297 xmlTextWriterPtr ret;
298 xmlOutputBufferPtr out;
299
Daniel Veillard500a1de2004-03-22 15:22:58 +0000300 if (ctxt == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000301 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000302 "xmlNewTextWriterPushParser : invalid context!\n");
303 return NULL;
304 }
305
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000306 out = xmlOutputBufferCreateIO((xmlOutputWriteCallback)
307 xmlTextWriterWriteDocCallback,
308 (xmlOutputCloseCallback)
309 xmlTextWriterCloseDocCallback,
310 (void *) ctxt, NULL);
311 if (out == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000312 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000313 "xmlNewTextWriterPushParser : error at xmlOutputBufferCreateIO!\n");
314 return NULL;
315 }
316
317 ret = xmlNewTextWriter(out);
318 if (ret == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000319 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000320 "xmlNewTextWriterPushParser : error at xmlNewTextWriter!\n");
321 xmlOutputBufferClose(out);
322 return NULL;
323 }
324
Daniel Veillard20c5e782004-01-21 09:57:31 +0000325 ret->ctxt = ctxt;
326
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000327 return ret;
328}
329
330/**
331 * xmlNewTextWriterDoc:
332 * @doc: address of a xmlDocPtr to hold the new XML document tree
333 * @compression: compress the output?
334 *
335 * Create a new xmlNewTextWriter structure with @*doc as output
336 *
337 * Returns the new xmlTextWriterPtr or NULL in case of error
338 */
339xmlTextWriterPtr
340xmlNewTextWriterDoc(xmlDocPtr * doc, int compression)
341{
342 xmlTextWriterPtr ret;
343 xmlSAXHandler saxHandler;
344 xmlParserCtxtPtr ctxt;
345
346 memset(&saxHandler, '\0', sizeof(saxHandler));
347 xmlSAX2InitDefaultSAXHandler(&saxHandler, 1);
348 saxHandler.startDocument = xmlTextWriterStartDocumentCallback;
349 saxHandler.startElement = xmlSAX2StartElement;
350 saxHandler.endElement = xmlSAX2EndElement;
351
352 ctxt = xmlCreatePushParserCtxt(&saxHandler, NULL, NULL, 0, NULL);
353 if (ctxt == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000354 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000355 "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\n");
356 return NULL;
357 }
Daniel Veillard03a53c32004-10-26 16:06:51 +0000358 /*
359 * For some reason this seems to completely break if node names
360 * are interned.
361 */
362 ctxt->dictNames = 0;
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000363
Daniel Veillard1d913862003-11-21 00:28:39 +0000364 ctxt->myDoc = xmlNewDoc(BAD_CAST XML_DEFAULT_VERSION);
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000365 if (ctxt->myDoc == NULL) {
366 xmlFreeParserCtxt(ctxt);
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 xmlNewDoc!\n");
369 return NULL;
370 }
371
372 ret = xmlNewTextWriterPushParser(ctxt, compression);
373 if (ret == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000374 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000375 "xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n");
376 return NULL;
377 }
378
Daniel Veillard500a1de2004-03-22 15:22:58 +0000379 xmlSetDocCompressMode(ctxt->myDoc, compression);
380
Daniel Veillarda521d282004-11-09 14:59:59 +0000381 if (doc != NULL) {
Daniel Veillard500a1de2004-03-22 15:22:58 +0000382 *doc = ctxt->myDoc;
Daniel Veillarda521d282004-11-09 14:59:59 +0000383 ret->no_doc_free = 1;
384 }
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000385
386 return ret;
387}
388
389/**
390 * xmlNewTextWriterTree:
391 * @doc: xmlDocPtr
392 * @node: xmlNodePtr or NULL for doc->children
393 * @compression: compress the output?
394 *
395 * Create a new xmlNewTextWriter structure with @doc as output
396 * starting at @node
397 *
398 * Returns the new xmlTextWriterPtr or NULL in case of error
399 */
400xmlTextWriterPtr
401xmlNewTextWriterTree(xmlDocPtr doc, xmlNodePtr node, int compression)
402{
403 xmlTextWriterPtr ret;
404 xmlSAXHandler saxHandler;
405 xmlParserCtxtPtr ctxt;
406
407 if (doc == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000408 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000409 "xmlNewTextWriterTree : invalid document tree!\n");
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000410 return NULL;
411 }
412
413 memset(&saxHandler, '\0', sizeof(saxHandler));
414 xmlSAX2InitDefaultSAXHandler(&saxHandler, 1);
415 saxHandler.startDocument = xmlTextWriterStartDocumentCallback;
416 saxHandler.startElement = xmlSAX2StartElement;
417 saxHandler.endElement = xmlSAX2EndElement;
418
419 ctxt = xmlCreatePushParserCtxt(&saxHandler, NULL, NULL, 0, NULL);
420 if (ctxt == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000421 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000422 "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\n");
423 return NULL;
424 }
Daniel Veillard03a53c32004-10-26 16:06:51 +0000425 /*
426 * For some reason this seems to completely break if node names
427 * are interned.
428 */
429 ctxt->dictNames = 0;
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000430
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000431 ret = xmlNewTextWriterPushParser(ctxt, compression);
432 if (ret == NULL) {
Daniel Veillard500a1de2004-03-22 15:22:58 +0000433 xmlFreeParserCtxt(ctxt);
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 xmlNewTextWriterPushParser!\n");
436 return NULL;
437 }
438
Daniel Veillard500a1de2004-03-22 15:22:58 +0000439 ctxt->myDoc = doc;
440 ctxt->node = node;
Daniel Veillarda521d282004-11-09 14:59:59 +0000441 ret->no_doc_free = 1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000442
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000443 xmlSetDocCompressMode(doc, compression);
444
445 return ret;
446}
447
448/**
Daniel Veillard1d211e22003-10-20 22:32:39 +0000449 * xmlFreeTextWriter:
450 * @writer: the xmlTextWriterPtr
451 *
452 * Deallocate all the resources associated to the writer
453 */
454void
455xmlFreeTextWriter(xmlTextWriterPtr writer)
456{
457 if (writer == NULL)
458 return;
459
460 if (writer->out != NULL)
461 xmlOutputBufferClose(writer->out);
462
463 if (writer->nodes != NULL)
464 xmlListDelete(writer->nodes);
465
466 if (writer->nsstack != NULL)
467 xmlListDelete(writer->nsstack);
468
Daniel Veillarda521d282004-11-09 14:59:59 +0000469 if (writer->ctxt != NULL) {
470 if ((writer->ctxt->myDoc != NULL) && (writer->no_doc_free == 0)) {
471 xmlFreeDoc(writer->ctxt->myDoc);
472 writer->ctxt->myDoc = NULL;
473 }
Daniel Veillard20c5e782004-01-21 09:57:31 +0000474 xmlFreeParserCtxt(writer->ctxt);
Daniel Veillarda521d282004-11-09 14:59:59 +0000475 }
Daniel Veillard20c5e782004-01-21 09:57:31 +0000476
Daniel Veillard4773df22004-01-23 13:15:13 +0000477 if (writer->ichar != NULL)
478 xmlFree(writer->ichar);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000479 xmlFree(writer);
480}
481
482/**
483 * xmlTextWriterStartDocument:
484 * @writer: the xmlTextWriterPtr
485 * @version: the xml version ("1.0") or NULL for default ("1.0")
486 * @encoding: the encoding or NULL for default
487 * @standalone: "yes" or "no" or NULL for default
488 *
489 * Start a new xml document
490 *
491 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
492 */
493int
494xmlTextWriterStartDocument(xmlTextWriterPtr writer, const char *version,
495 const char *encoding, const char *standalone)
496{
497 int count;
498 int sum;
499 xmlLinkPtr lk;
500 xmlCharEncodingHandlerPtr encoder;
501
Daniel Veillard500a1de2004-03-22 15:22:58 +0000502 if ((writer == NULL) || (writer->out == NULL)) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000503 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000504 "xmlTextWriterStartDocument : invalid writer!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000505 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000506 }
Daniel Veillard1d211e22003-10-20 22:32:39 +0000507
508 lk = xmlListFront(writer->nodes);
509 if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000510 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000511 "xmlTextWriterStartDocument : not allowed in this context!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000512 return -1;
513 }
514
515 encoder = NULL;
516 if (encoding != NULL) {
517 encoder = xmlFindCharEncodingHandler(encoding);
518 if (encoder == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000519 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000520 "xmlTextWriterStartDocument : out of memory!\n");
521 return -1;
522 }
523 }
524
525 writer->out->encoder = encoder;
526 if (encoder != NULL) {
527 writer->out->conv = xmlBufferCreateSize(4000);
528 xmlCharEncOutFunc(encoder, writer->out->conv, NULL);
529 } else
530 writer->out->conv = NULL;
531
532 sum = 0;
533 count = xmlOutputBufferWriteString(writer->out, "<?xml version=");
534 if (count < 0)
535 return -1;
536 sum += count;
537 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
538 if (count < 0)
539 return -1;
540 sum += count;
541 if (version != 0)
542 count = xmlOutputBufferWriteString(writer->out, version);
543 else
544 count = xmlOutputBufferWriteString(writer->out, "1.0");
545 if (count < 0)
546 return -1;
547 sum += count;
548 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
549 if (count < 0)
550 return -1;
551 sum += count;
552 if (writer->out->encoder != 0) {
553 count = xmlOutputBufferWriteString(writer->out, " encoding=");
554 if (count < 0)
555 return -1;
556 sum += count;
557 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
558 if (count < 0)
559 return -1;
560 sum += count;
561 count =
562 xmlOutputBufferWriteString(writer->out,
563 writer->out->encoder->name);
564 if (count < 0)
565 return -1;
566 sum += count;
567 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
568 if (count < 0)
569 return -1;
570 sum += count;
571 }
572
573 if (standalone != 0) {
574 count = xmlOutputBufferWriteString(writer->out, " standalone=");
575 if (count < 0)
576 return -1;
577 sum += count;
578 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
579 if (count < 0)
580 return -1;
581 sum += count;
582 count = xmlOutputBufferWriteString(writer->out, standalone);
583 if (count < 0)
584 return -1;
585 sum += count;
586 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
587 if (count < 0)
588 return -1;
589 sum += count;
590 }
591
592 count = xmlOutputBufferWriteString(writer->out, "?>\n");
593 if (count < 0)
594 return -1;
595 sum += count;
596
597 return sum;
598}
599
600/**
601 * xmlTextWriterEndDocument:
602 * @writer: the xmlTextWriterPtr
603 *
604 * End an xml document. All open elements are closed
605 *
606 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
607 */
608int
609xmlTextWriterEndDocument(xmlTextWriterPtr writer)
610{
611 int count;
612 int sum;
613 xmlLinkPtr lk;
614 xmlTextWriterStackEntry *p;
615
Daniel Veillard500a1de2004-03-22 15:22:58 +0000616 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000617 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000618 "xmlTextWriterEndDocument : invalid writer!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000619 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000620 }
Daniel Veillard1d211e22003-10-20 22:32:39 +0000621
622 sum = 0;
623 while ((lk = xmlListFront(writer->nodes)) != NULL) {
624 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
625 if (p == 0)
626 break;
627 switch (p->state) {
628 case XML_TEXTWRITER_NAME:
629 case XML_TEXTWRITER_ATTRIBUTE:
630 case XML_TEXTWRITER_TEXT:
631 count = xmlTextWriterEndElement(writer);
632 if (count < 0)
633 return -1;
634 sum += count;
635 break;
636 case XML_TEXTWRITER_PI:
637 case XML_TEXTWRITER_PI_TEXT:
638 count = xmlTextWriterEndPI(writer);
639 if (count < 0)
640 return -1;
641 sum += count;
642 break;
643 case XML_TEXTWRITER_CDATA:
644 count = xmlTextWriterEndCDATA(writer);
645 if (count < 0)
646 return -1;
647 sum += count;
648 break;
649 case XML_TEXTWRITER_DTD:
Daniel Veillard500a1de2004-03-22 15:22:58 +0000650 case XML_TEXTWRITER_DTD_TEXT:
651 case XML_TEXTWRITER_DTD_ELEM:
652 case XML_TEXTWRITER_DTD_ELEM_TEXT:
653 case XML_TEXTWRITER_DTD_ATTL:
654 case XML_TEXTWRITER_DTD_ATTL_TEXT:
655 case XML_TEXTWRITER_DTD_ENTY:
656 case XML_TEXTWRITER_DTD_ENTY_TEXT:
657 case XML_TEXTWRITER_DTD_PENT:
Daniel Veillard1d211e22003-10-20 22:32:39 +0000658 count = xmlTextWriterEndDTD(writer);
659 if (count < 0)
660 return -1;
661 sum += count;
662 break;
Daniel Veillardab69f362004-02-17 11:40:32 +0000663 case XML_TEXTWRITER_COMMENT:
664 count = xmlTextWriterEndComment(writer);
665 if (count < 0)
666 return -1;
667 sum += count;
668 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000669 default:
Daniel Veillardab69f362004-02-17 11:40:32 +0000670 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000671 }
672 }
673
Daniel Veillard2cca4462004-01-02 20:04:23 +0000674 if (!writer->indent) {
Daniel Veillardab69f362004-02-17 11:40:32 +0000675 count = xmlOutputBufferWriteString(writer->out, "\n");
676 if (count < 0)
677 return -1;
678 sum += count;
679 }
680 return sum;
681}
682
Daniel Veillardab69f362004-02-17 11:40:32 +0000683/**
684 * xmlTextWriterStartComment:
685 * @writer: the xmlTextWriterPtr
686 *
687 * Start an xml comment.
688 *
689 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
690 */
691int
692xmlTextWriterStartComment(xmlTextWriterPtr writer)
693{
694 int count;
695 int sum;
696 xmlLinkPtr lk;
697 xmlTextWriterStackEntry *p;
698
Daniel Veillard500a1de2004-03-22 15:22:58 +0000699 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000700 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000701 "xmlTextWriterStartComment : invalid writer!\n");
Daniel Veillardab69f362004-02-17 11:40:32 +0000702 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000703 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000704
705 sum = 0;
706 lk = xmlListFront(writer->nodes);
707 if (lk != 0) {
708 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
709 if (p != 0) {
710 switch (p->state) {
711 case XML_TEXTWRITER_TEXT:
712 case XML_TEXTWRITER_NONE:
713 break;
714 case XML_TEXTWRITER_NAME:
715 count = xmlOutputBufferWriteString(writer->out, ">");
716 if (count < 0)
717 return -1;
718 sum += count;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000719 if (writer->indent) {
720 count =
721 xmlOutputBufferWriteString(writer->out, "\n");
722 if (count < 0)
723 return -1;
724 sum += count;
725 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000726 p->state = XML_TEXTWRITER_TEXT;
727 break;
728 default:
729 return -1;
730 }
731 }
732 }
733
734 p = (xmlTextWriterStackEntry *)
735 xmlMalloc(sizeof(xmlTextWriterStackEntry));
736 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000737 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillardab69f362004-02-17 11:40:32 +0000738 "xmlTextWriterStartElement : out of memory!\n");
739 return -1;
740 }
741
742 p->name = 0;
743 p->state = XML_TEXTWRITER_COMMENT;
744
745 xmlListPushFront(writer->nodes, p);
746
747 if (writer->indent) {
Daniel Veillardab69f362004-02-17 11:40:32 +0000748 count = xmlTextWriterWriteIndent(writer);
749 if (count < 0)
750 return -1;
751 sum += count;
752 }
753
754 count = xmlOutputBufferWriteString(writer->out, "<!--");
755 if (count < 0)
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000756 return -1;
757 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +0000758
759 return sum;
760}
761
762/**
763 * xmlTextWriterEndComment:
764 * @writer: the xmlTextWriterPtr
765 *
766 * End the current xml coment.
767 *
768 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
769 */
770int
771xmlTextWriterEndComment(xmlTextWriterPtr writer)
772{
773 int count;
774 int sum;
775 xmlLinkPtr lk;
776 xmlTextWriterStackEntry *p;
777
Daniel Veillard500a1de2004-03-22 15:22:58 +0000778 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000779 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000780 "xmlTextWriterEndComment : invalid writer!\n");
Daniel Veillardab69f362004-02-17 11:40:32 +0000781 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000782 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000783
784 lk = xmlListFront(writer->nodes);
Daniel Veillard500a1de2004-03-22 15:22:58 +0000785 if (lk == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000786 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000787 "xmlTextWriterEndComment : not allowed in this context!\n");
Daniel Veillardab69f362004-02-17 11:40:32 +0000788 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000789 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000790
791 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
792 if (p == 0)
793 return -1;
794
795 sum = 0;
796 switch (p->state) {
797 case XML_TEXTWRITER_COMMENT:
798 count = xmlOutputBufferWriteString(writer->out, "-->");
799 if (count < 0)
800 return -1;
801 sum += count;
802 break;
803 default:
804 return -1;
Daniel Veillard2cca4462004-01-02 20:04:23 +0000805 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000806
807 if (writer->indent) {
808 count = xmlOutputBufferWriteString(writer->out, "\n");
809 if (count < 0)
810 return -1;
811 sum += count;
812 }
813
814 xmlListPopFront(writer->nodes);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000815 return sum;
816}
817
818/**
819 * xmlTextWriterWriteFormatComment:
820 * @writer: the xmlTextWriterPtr
821 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +0000822 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +0000823 *
824 * Write an xml comment.
825 *
826 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
827 */
Daniel Veillardffa3c742005-07-21 13:24:09 +0000828int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +0000829xmlTextWriterWriteFormatComment(xmlTextWriterPtr writer,
830 const char *format, ...)
831{
832 int rc;
833 va_list ap;
834
835 va_start(ap, format);
836
837 rc = xmlTextWriterWriteVFormatComment(writer, format, ap);
838
839 va_end(ap);
840 return rc;
841}
842
843/**
844 * xmlTextWriterWriteVFormatComment:
845 * @writer: the xmlTextWriterPtr
846 * @format: format string (see printf)
847 * @argptr: pointer to the first member of the variable argument list.
848 *
849 * Write an xml comment.
850 *
851 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
852 */
853int
854xmlTextWriterWriteVFormatComment(xmlTextWriterPtr writer,
855 const char *format, va_list argptr)
856{
857 int rc;
858 xmlChar *buf;
859
Daniel Veillard500a1de2004-03-22 15:22:58 +0000860 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000861 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000862 "xmlTextWriterWriteVFormatComment : invalid writer!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000863 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000864 }
Daniel Veillard1d211e22003-10-20 22:32:39 +0000865
866 buf = xmlTextWriterVSprintf(format, argptr);
867 if (buf == 0)
868 return 0;
869
870 rc = xmlTextWriterWriteComment(writer, buf);
871
872 xmlFree(buf);
873 return rc;
874}
875
876/**
877 * xmlTextWriterWriteComment:
878 * @writer: the xmlTextWriterPtr
879 * @content: comment string
880 *
881 * Write an xml comment.
882 *
883 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
884 */
885int
886xmlTextWriterWriteComment(xmlTextWriterPtr writer, const xmlChar * content)
887{
888 int count;
889 int sum;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000890
891 sum = 0;
Daniel Veillardab69f362004-02-17 11:40:32 +0000892 count = xmlTextWriterStartComment(writer);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000893 if (count < 0)
894 return -1;
895 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +0000896 count = xmlTextWriterWriteString(writer, content);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000897 if (count < 0)
898 return -1;
899 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +0000900 count = xmlTextWriterEndComment(writer);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000901 if (count < 0)
902 return -1;
903 sum += count;
904
905 return sum;
906}
907
908/**
909 * xmlTextWriterStartElement:
910 * @writer: the xmlTextWriterPtr
911 * @name: element name
912 *
913 * Start an xml element.
914 *
915 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
916 */
917int
918xmlTextWriterStartElement(xmlTextWriterPtr writer, const xmlChar * name)
919{
920 int count;
921 int sum;
922 xmlLinkPtr lk;
923 xmlTextWriterStackEntry *p;
924
925 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
926 return -1;
927
928 sum = 0;
929 lk = xmlListFront(writer->nodes);
930 if (lk != 0) {
931 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
932 if (p != 0) {
933 switch (p->state) {
934 case XML_TEXTWRITER_PI:
935 case XML_TEXTWRITER_PI_TEXT:
936 return -1;
937 case XML_TEXTWRITER_NONE:
938 break;
Daniel Veillard614fdc12005-02-23 14:05:37 +0000939 case XML_TEXTWRITER_ATTRIBUTE:
940 count = xmlTextWriterEndAttribute(writer);
941 if (count < 0)
942 return -1;
943 sum += count;
944 /* fallthrough */
Daniel Veillard1d211e22003-10-20 22:32:39 +0000945 case XML_TEXTWRITER_NAME:
946 count = xmlOutputBufferWriteString(writer->out, ">");
947 if (count < 0)
948 return -1;
949 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +0000950 if (writer->indent)
951 count =
952 xmlOutputBufferWriteString(writer->out, "\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000953 p->state = XML_TEXTWRITER_TEXT;
954 break;
Daniel Veillardab69f362004-02-17 11:40:32 +0000955 default:
956 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000957 }
958 }
959 }
960
961 p = (xmlTextWriterStackEntry *)
962 xmlMalloc(sizeof(xmlTextWriterStackEntry));
963 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000964 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000965 "xmlTextWriterStartElement : out of memory!\n");
966 return -1;
967 }
968
969 p->name = xmlStrdup(name);
970 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000971 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000972 "xmlTextWriterStartElement : out of memory!\n");
973 xmlFree(p);
974 return -1;
975 }
976 p->state = XML_TEXTWRITER_NAME;
977
978 xmlListPushFront(writer->nodes, p);
979
Daniel Veillardab69f362004-02-17 11:40:32 +0000980 if (writer->indent) {
981 count = xmlTextWriterWriteIndent(writer);
982 sum += count;
Daniel Veillard2cca4462004-01-02 20:04:23 +0000983 }
984
Daniel Veillard1d211e22003-10-20 22:32:39 +0000985 count = xmlOutputBufferWriteString(writer->out, "<");
986 if (count < 0)
987 return -1;
988 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000989 count =
990 xmlOutputBufferWriteString(writer->out, (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000991 if (count < 0)
992 return -1;
993 sum += count;
994
995 return sum;
996}
997
998/**
999 * xmlTextWriterStartElementNS:
1000 * @writer: the xmlTextWriterPtr
1001 * @prefix: namespace prefix or NULL
1002 * @name: element local name
1003 * @namespaceURI: namespace URI or NULL
1004 *
1005 * Start an xml element with namespace support.
1006 *
1007 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1008 */
1009int
1010xmlTextWriterStartElementNS(xmlTextWriterPtr writer,
1011 const xmlChar * prefix, const xmlChar * name,
1012 const xmlChar * namespaceURI)
1013{
1014 int count;
1015 int sum;
1016 xmlChar *buf;
1017
1018 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1019 return -1;
1020
1021 buf = 0;
1022 if (prefix != 0) {
1023 buf = xmlStrdup(prefix);
1024 buf = xmlStrcat(buf, BAD_CAST ":");
1025 }
1026 buf = xmlStrcat(buf, name);
1027
1028 sum = 0;
1029 count = xmlTextWriterStartElement(writer, buf);
1030 xmlFree(buf);
1031 if (count < 0)
1032 return -1;
1033 sum += count;
1034
1035 if (namespaceURI != 0) {
1036 buf = xmlStrdup(BAD_CAST "xmlns");
1037 if (prefix != 0) {
1038 buf = xmlStrcat(buf, BAD_CAST ":");
1039 buf = xmlStrcat(buf, prefix);
1040 }
1041
1042 count = xmlTextWriterWriteAttribute(writer, buf, namespaceURI);
1043 xmlFree(buf);
1044 if (count < 0)
1045 return -1;
1046 sum += count;
1047 }
1048
1049 return sum;
1050}
1051
1052/**
1053 * xmlTextWriterEndElement:
1054 * @writer: the xmlTextWriterPtr
1055 *
1056 * End the current xml element.
1057 *
1058 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1059 */
1060int
1061xmlTextWriterEndElement(xmlTextWriterPtr writer)
1062{
1063 int count;
1064 int sum;
1065 xmlLinkPtr lk;
1066 xmlTextWriterStackEntry *p;
1067
1068 if (writer == NULL)
1069 return -1;
1070
1071 lk = xmlListFront(writer->nodes);
1072 if (lk == 0)
1073 return -1;
1074
1075 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1076 if (p == 0)
1077 return -1;
1078
1079 sum = 0;
1080 switch (p->state) {
1081 case XML_TEXTWRITER_ATTRIBUTE:
1082 count = xmlTextWriterEndAttribute(writer);
1083 if (count < 0)
1084 return -1;
1085 sum += count;
1086 /* fallthrough */
1087 case XML_TEXTWRITER_NAME:
Daniel Veillardab69f362004-02-17 11:40:32 +00001088 if (writer->indent) /* next element needs indent */
1089 writer->doindent = 1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001090 count = xmlOutputBufferWriteString(writer->out, "/>");
1091 if (count < 0)
1092 return -1;
1093 sum += count;
1094 break;
1095 case XML_TEXTWRITER_TEXT:
Daniel Veillardab69f362004-02-17 11:40:32 +00001096 if ((writer->indent) && (writer->doindent)) {
1097 count = xmlTextWriterWriteIndent(writer);
1098 sum += count;
1099 writer->doindent = 1;
1100 } else
1101 writer->doindent = 1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001102 count = xmlOutputBufferWriteString(writer->out, "</");
1103 if (count < 0)
1104 return -1;
1105 sum += count;
1106 count = xmlOutputBufferWriteString(writer->out,
Daniel Veillardab69f362004-02-17 11:40:32 +00001107 (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001108 if (count < 0)
1109 return -1;
1110 sum += count;
1111 count = xmlOutputBufferWriteString(writer->out, ">");
1112 if (count < 0)
1113 return -1;
1114 sum += count;
1115 break;
1116 default:
1117 return -1;
1118 }
1119
Daniel Veillard2cca4462004-01-02 20:04:23 +00001120 if (writer->indent) {
Daniel Veillardab69f362004-02-17 11:40:32 +00001121 count = xmlOutputBufferWriteString(writer->out, "\n");
1122 sum += count;
Daniel Veillard2cca4462004-01-02 20:04:23 +00001123 }
1124
Daniel Veillard1d211e22003-10-20 22:32:39 +00001125 xmlListPopFront(writer->nodes);
1126 return sum;
1127}
1128
1129/**
1130 * xmlTextWriterFullEndElement:
1131 * @writer: the xmlTextWriterPtr
1132 *
1133 * End the current xml element. Writes an end tag even if the element is empty
1134 *
1135 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1136 */
1137int
1138xmlTextWriterFullEndElement(xmlTextWriterPtr writer)
1139{
1140 int count;
1141 int sum;
1142 xmlLinkPtr lk;
1143 xmlTextWriterStackEntry *p;
1144
1145 if (writer == NULL)
1146 return -1;
1147
1148 lk = xmlListFront(writer->nodes);
1149 if (lk == 0)
1150 return -1;
1151
1152 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1153 if (p == 0)
1154 return -1;
1155
1156 sum = 0;
1157 switch (p->state) {
1158 case XML_TEXTWRITER_ATTRIBUTE:
1159 count = xmlTextWriterEndAttribute(writer);
1160 if (count < 0)
1161 return -1;
1162 sum += count;
1163 /* fallthrough */
1164 case XML_TEXTWRITER_NAME:
1165 count = xmlOutputBufferWriteString(writer->out, ">");
1166 if (count < 0)
1167 return -1;
1168 sum += count;
1169 /* fallthrough */
1170 case XML_TEXTWRITER_TEXT:
1171 count = xmlOutputBufferWriteString(writer->out, "</");
1172 if (count < 0)
1173 return -1;
1174 sum += count;
1175 count = xmlOutputBufferWriteString(writer->out,
Daniel Veillardab69f362004-02-17 11:40:32 +00001176 (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001177 if (count < 0)
1178 return -1;
1179 sum += count;
1180 count = xmlOutputBufferWriteString(writer->out, ">");
1181 if (count < 0)
1182 return -1;
1183 sum += count;
1184 break;
1185 default:
1186 return -1;
1187 }
1188
1189 xmlListPopFront(writer->nodes);
1190 return sum;
1191}
1192
1193/**
1194 * xmlTextWriterWriteFormatRaw:
1195 * @writer: the xmlTextWriterPtr
1196 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001197 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001198 *
1199 * Write a formatted raw xml text.
1200 *
1201 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1202 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00001203int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00001204xmlTextWriterWriteFormatRaw(xmlTextWriterPtr writer, const char *format,
1205 ...)
1206{
1207 int rc;
1208 va_list ap;
1209
1210 va_start(ap, format);
1211
1212 rc = xmlTextWriterWriteVFormatRaw(writer, format, ap);
1213
1214 va_end(ap);
1215 return rc;
1216}
1217
1218/**
1219 * xmlTextWriterWriteVFormatRaw:
1220 * @writer: the xmlTextWriterPtr
1221 * @format: format string (see printf)
1222 * @argptr: pointer to the first member of the variable argument list.
1223 *
1224 * Write a formatted raw xml text.
1225 *
1226 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1227 */
1228int
1229xmlTextWriterWriteVFormatRaw(xmlTextWriterPtr writer, const char *format,
1230 va_list argptr)
1231{
1232 int rc;
1233 xmlChar *buf;
1234
1235 if (writer == NULL)
1236 return -1;
1237
1238 buf = xmlTextWriterVSprintf(format, argptr);
1239 if (buf == 0)
1240 return 0;
1241
1242 rc = xmlTextWriterWriteRaw(writer, buf);
1243
1244 xmlFree(buf);
1245 return rc;
1246}
1247
1248/**
Daniel Veillard1e906612003-12-05 14:57:46 +00001249 * xmlTextWriterWriteRawLen:
Daniel Veillard1d211e22003-10-20 22:32:39 +00001250 * @writer: the xmlTextWriterPtr
1251 * @content: text string
1252 * @len: length of the text string
1253 *
1254 * Write an xml text.
1255 * TODO: what about entities and special chars??
1256 *
1257 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1258 */
1259int
1260xmlTextWriterWriteRawLen(xmlTextWriterPtr writer, const xmlChar * content,
1261 int len)
1262{
1263 int count;
1264 int sum;
1265 xmlLinkPtr lk;
1266 xmlTextWriterStackEntry *p;
1267
Daniel Veillard500a1de2004-03-22 15:22:58 +00001268 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00001269 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00001270 "xmlTextWriterWriteRawLen : invalid writer!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +00001271 return -1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001272 }
1273
Daniel Veillarde43cc572004-11-03 11:50:29 +00001274 if ((content == NULL) || (len < 0)) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00001275 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00001276 "xmlTextWriterWriteRawLen : invalid content!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +00001277 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001278 }
1279
1280 sum = 0;
1281 lk = xmlListFront(writer->nodes);
1282 if (lk != 0) {
1283 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1284 count = xmlTextWriterHandleStateDependencies(writer, p);
1285 if (count < 0)
1286 return -1;
1287 sum += count;
1288 }
1289
1290 if (writer->indent)
1291 writer->doindent = 0;
1292
1293 if (content != NULL) {
1294 count =
1295 xmlOutputBufferWrite(writer->out, len, (const char *) content);
1296 if (count < 0)
1297 return -1;
1298 sum += count;
1299 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001300
1301 return sum;
1302}
1303
1304/**
1305 * xmlTextWriterWriteRaw:
1306 * @writer: the xmlTextWriterPtr
1307 * @content: text string
1308 *
1309 * Write a raw xml text.
1310 *
1311 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1312 */
1313int
1314xmlTextWriterWriteRaw(xmlTextWriterPtr writer, const xmlChar * content)
1315{
1316 return xmlTextWriterWriteRawLen(writer, content, xmlStrlen(content));
1317}
1318
1319/**
1320 * xmlTextWriterWriteFormatString:
1321 * @writer: the xmlTextWriterPtr
1322 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001323 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001324 *
1325 * Write a formatted xml text.
1326 *
1327 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1328 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00001329int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00001330xmlTextWriterWriteFormatString(xmlTextWriterPtr writer, const char *format,
1331 ...)
1332{
1333 int rc;
1334 va_list ap;
1335
Daniel Veillarde43cc572004-11-03 11:50:29 +00001336 if ((writer == NULL) || (format == NULL))
1337 return -1;
1338
Daniel Veillard1d211e22003-10-20 22:32:39 +00001339 va_start(ap, format);
1340
1341 rc = xmlTextWriterWriteVFormatString(writer, format, ap);
1342
1343 va_end(ap);
1344 return rc;
1345}
1346
1347/**
1348 * xmlTextWriterWriteVFormatString:
1349 * @writer: the xmlTextWriterPtr
1350 * @format: format string (see printf)
1351 * @argptr: pointer to the first member of the variable argument list.
1352 *
1353 * Write a formatted xml text.
1354 *
1355 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1356 */
1357int
1358xmlTextWriterWriteVFormatString(xmlTextWriterPtr writer,
1359 const char *format, va_list argptr)
1360{
1361 int rc;
1362 xmlChar *buf;
1363
Daniel Veillarde43cc572004-11-03 11:50:29 +00001364 if ((writer == NULL) || (format == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00001365 return -1;
1366
1367 buf = xmlTextWriterVSprintf(format, argptr);
1368 if (buf == 0)
1369 return 0;
1370
1371 rc = xmlTextWriterWriteString(writer, buf);
1372
1373 xmlFree(buf);
1374 return rc;
1375}
1376
1377/**
1378 * xmlTextWriterWriteString:
1379 * @writer: the xmlTextWriterPtr
1380 * @content: text string
1381 *
1382 * Write an xml text.
1383 *
1384 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1385 */
1386int
1387xmlTextWriterWriteString(xmlTextWriterPtr writer, const xmlChar * content)
1388{
Daniel Veillard500a1de2004-03-22 15:22:58 +00001389 int count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001390 int sum;
1391 xmlLinkPtr lk;
1392 xmlTextWriterStackEntry *p;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001393 xmlChar *buf;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001394
Daniel Veillarde43cc572004-11-03 11:50:29 +00001395 if ((writer == NULL) || (content == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00001396 return -1;
1397
Daniel Veillard1d211e22003-10-20 22:32:39 +00001398 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001399 buf = (xmlChar *) content;
1400 lk = xmlListFront(writer->nodes);
1401 if (lk != 0) {
1402 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1403 if (p != 0) {
1404 switch (p->state) {
1405 case XML_TEXTWRITER_NAME:
1406 case XML_TEXTWRITER_TEXT:
Daniel Veillard62040be2004-05-17 03:17:26 +00001407#if 0
1408 buf = NULL;
1409 xmlOutputBufferWriteEscape(writer->out, content, NULL);
1410#endif
Daniel Veillard500a1de2004-03-22 15:22:58 +00001411 buf = xmlEncodeSpecialChars(NULL, content);
1412 break;
1413 case XML_TEXTWRITER_ATTRIBUTE:
1414 buf = NULL;
1415 xmlAttrSerializeTxtContent(writer->out->buffer, NULL,
1416 NULL, content);
1417 break;
William M. Brack87640d52004-04-17 14:58:15 +00001418 default:
1419 break;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001420 }
1421 }
1422 }
1423
1424 if (buf != NULL) {
1425 count = xmlTextWriterWriteRaw(writer, buf);
1426 if (count < 0)
Daniel Veillard1d211e22003-10-20 22:32:39 +00001427 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001428 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001429
Daniel Veillard500a1de2004-03-22 15:22:58 +00001430 if (buf != content) /* buf was allocated by us, so free it */
1431 xmlFree(buf);
William M. Bracka9c612c2004-02-01 10:04:05 +00001432 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001433
1434 return sum;
1435}
1436
1437/**
1438 * xmlOutputBufferWriteBase64:
1439 * @out: the xmlOutputBufferPtr
1440 * @data: binary data
1441 * @len: the number of bytes to encode
1442 *
1443 * Write base64 encoded data to an xmlOutputBuffer.
1444 * Adapted from John Walker's base64.c (http://www.fourmilab.ch/).
1445 *
1446 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1447 */
1448static int
1449xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len,
1450 const unsigned char *data)
1451{
1452 static unsigned char dtable[64] =
William M. Brack47a31882004-09-11 16:09:09 +00001453 {'A','B','C','D','E','F','G','H','I','J','K','L','M',
1454 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
1455 'a','b','c','d','e','f','g','h','i','j','k','l','m',
1456 'n','o','p','q','r','s','t','u','v','w','x','y','z',
1457 '0','1','2','3','4','5','6','7','8','9','+','/'};
1458
Daniel Veillard1d211e22003-10-20 22:32:39 +00001459 int i;
1460 int linelen;
1461 int count;
1462 int sum;
1463
Daniel Veillarde43cc572004-11-03 11:50:29 +00001464 if ((out == NULL) || (len < 0) || (data == NULL))
1465 return(-1);
1466
Daniel Veillard1d211e22003-10-20 22:32:39 +00001467 linelen = 0;
1468 sum = 0;
1469
1470 i = 0;
1471 while (1) {
1472 unsigned char igroup[3];
1473 unsigned char ogroup[4];
1474 int c;
1475 int n;
1476
1477 igroup[0] = igroup[1] = igroup[2] = 0;
1478 for (n = 0; n < 3 && i < len; n++, i++) {
1479 c = data[i];
1480 igroup[n] = (unsigned char) c;
1481 }
1482
1483 if (n > 0) {
1484 ogroup[0] = dtable[igroup[0] >> 2];
1485 ogroup[1] = dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)];
1486 ogroup[2] =
1487 dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)];
1488 ogroup[3] = dtable[igroup[2] & 0x3F];
1489
1490 if (n < 3) {
1491 ogroup[3] = '=';
1492 if (n < 2) {
1493 ogroup[2] = '=';
1494 }
1495 }
1496
1497 if (linelen >= B64LINELEN) {
1498 count = xmlOutputBufferWrite(out, 2, B64CRLF);
1499 if (count == -1)
1500 return -1;
1501 sum += count;
1502 linelen = 0;
1503 }
1504 count = xmlOutputBufferWrite(out, 4, (const char *) ogroup);
1505 if (count == -1)
1506 return -1;
1507 sum += count;
1508
1509 linelen += 4;
1510 }
Daniel Veillard929714b2003-10-22 12:34:36 +00001511
1512 if (i >= len)
1513 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001514 }
1515
Daniel Veillard1d211e22003-10-20 22:32:39 +00001516 return sum;
1517}
1518
1519/**
1520 * xmlTextWriterWriteBase64:
1521 * @writer: the xmlTextWriterPtr
1522 * @data: binary data
1523 * @start: the position within the data of the first byte to encode
1524 * @len: the number of bytes to encode
1525 *
1526 * Write an base64 encoded xml text.
1527 *
1528 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1529 */
1530int
Daniel Veillardab69f362004-02-17 11:40:32 +00001531xmlTextWriterWriteBase64(xmlTextWriterPtr writer, const char *data,
Daniel Veillard1d211e22003-10-20 22:32:39 +00001532 int start, int len)
1533{
1534 int count;
1535 int sum;
1536 xmlLinkPtr lk;
1537 xmlTextWriterStackEntry *p;
1538
Daniel Veillarde43cc572004-11-03 11:50:29 +00001539 if ((writer == NULL) || (data == NULL) || (start < 0) || (len < 0))
Daniel Veillard1d211e22003-10-20 22:32:39 +00001540 return -1;
1541
Daniel Veillard1d211e22003-10-20 22:32:39 +00001542 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001543 lk = xmlListFront(writer->nodes);
1544 if (lk != 0) {
1545 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1546 if (p != 0) {
1547 count = xmlTextWriterHandleStateDependencies(writer, p);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001548 if (count < 0)
1549 return -1;
1550 sum += count;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001551 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001552 }
1553
Daniel Veillardab69f362004-02-17 11:40:32 +00001554 if (writer->indent)
1555 writer->doindent = 0;
1556
Daniel Veillard1d211e22003-10-20 22:32:39 +00001557 count =
1558 xmlOutputBufferWriteBase64(writer->out, len,
1559 (unsigned char *) data + start);
1560 if (count < 0)
1561 return -1;
1562 sum += count;
1563
1564 return sum;
1565}
1566
1567/**
1568 * xmlOutputBufferWriteBinHex:
1569 * @out: the xmlOutputBufferPtr
1570 * @data: binary data
1571 * @len: the number of bytes to encode
1572 *
1573 * Write hqx encoded data to an xmlOutputBuffer.
1574 * ::todo
1575 *
William M. Brack47a31882004-09-11 16:09:09 +00001576 * Returns the bytes written (may be 0 because of buffering)
1577 * or -1 in case of error
Daniel Veillard1d211e22003-10-20 22:32:39 +00001578 */
1579static int
Daniel Veillardab69f362004-02-17 11:40:32 +00001580xmlOutputBufferWriteBinHex(xmlOutputBufferPtr out,
1581 int len, const unsigned char *data)
Daniel Veillard1d211e22003-10-20 22:32:39 +00001582{
Daniel Veillardab69f362004-02-17 11:40:32 +00001583 int count;
1584 int sum;
William M. Brack47a31882004-09-11 16:09:09 +00001585 static char hex[16] =
1586 {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
Daniel Veillardab69f362004-02-17 11:40:32 +00001587 int i;
1588
Daniel Veillarde43cc572004-11-03 11:50:29 +00001589 if ((out == NULL) || (data == NULL) || (len < 0)) {
Daniel Veillardab69f362004-02-17 11:40:32 +00001590 return -1;
1591 }
1592
1593 sum = 0;
1594 for (i = 0; i < len; i++) {
1595 count =
1596 xmlOutputBufferWrite(out, 1,
1597 (const char *) &hex[data[i] >> 4]);
1598 if (count == -1)
1599 return -1;
1600 sum += count;
1601 count =
1602 xmlOutputBufferWrite(out, 1,
1603 (const char *) &hex[data[i] & 0xF]);
1604 if (count == -1)
1605 return -1;
1606 sum += count;
1607 }
1608
1609 return sum;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001610}
1611
1612/**
1613 * xmlTextWriterWriteBinHex:
1614 * @writer: the xmlTextWriterPtr
1615 * @data: binary data
1616 * @start: the position within the data of the first byte to encode
1617 * @len: the number of bytes to encode
1618 *
1619 * Write a BinHex encoded xml text.
1620 *
1621 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1622 */
1623int
Daniel Veillardab69f362004-02-17 11:40:32 +00001624xmlTextWriterWriteBinHex(xmlTextWriterPtr writer, const char *data,
Daniel Veillard1d211e22003-10-20 22:32:39 +00001625 int start, int len)
1626{
1627 int count;
1628 int sum;
1629 xmlLinkPtr lk;
1630 xmlTextWriterStackEntry *p;
1631
Daniel Veillarde43cc572004-11-03 11:50:29 +00001632 if ((writer == NULL) || (data == NULL) || (start < 0) || (len < 0))
Daniel Veillard1d211e22003-10-20 22:32:39 +00001633 return -1;
1634
Daniel Veillard1d211e22003-10-20 22:32:39 +00001635 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001636 lk = xmlListFront(writer->nodes);
1637 if (lk != 0) {
1638 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1639 if (p != 0) {
1640 count = xmlTextWriterHandleStateDependencies(writer, p);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001641 if (count < 0)
1642 return -1;
1643 sum += count;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001644 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001645 }
1646
Daniel Veillardab69f362004-02-17 11:40:32 +00001647 if (writer->indent)
1648 writer->doindent = 0;
1649
Daniel Veillard1d211e22003-10-20 22:32:39 +00001650 count =
1651 xmlOutputBufferWriteBinHex(writer->out, len,
1652 (unsigned char *) data + start);
1653 if (count < 0)
1654 return -1;
1655 sum += count;
1656
1657 return sum;
1658}
1659
1660/**
1661 * xmlTextWriterStartAttribute:
1662 * @writer: the xmlTextWriterPtr
1663 * @name: element name
1664 *
1665 * Start an xml attribute.
1666 *
1667 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1668 */
1669int
1670xmlTextWriterStartAttribute(xmlTextWriterPtr writer, const xmlChar * name)
1671{
1672 int count;
1673 int sum;
1674 xmlLinkPtr lk;
1675 xmlTextWriterStackEntry *p;
1676
1677 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1678 return -1;
1679
1680 sum = 0;
1681 lk = xmlListFront(writer->nodes);
1682 if (lk == 0)
1683 return -1;
1684
1685 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1686 if (p == 0)
1687 return -1;
1688
1689 switch (p->state) {
1690 case XML_TEXTWRITER_ATTRIBUTE:
1691 count = xmlTextWriterEndAttribute(writer);
1692 if (count < 0)
1693 return -1;
1694 sum += count;
1695 /* fallthrough */
1696 case XML_TEXTWRITER_NAME:
1697 count = xmlOutputBufferWriteString(writer->out, " ");
1698 if (count < 0)
1699 return -1;
1700 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00001701 count =
1702 xmlOutputBufferWriteString(writer->out,
1703 (const char *) name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001704 if (count < 0)
1705 return -1;
1706 sum += count;
1707 count = xmlOutputBufferWriteString(writer->out, "=");
1708 if (count < 0)
1709 return -1;
1710 sum += count;
1711 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
1712 if (count < 0)
1713 return -1;
1714 sum += count;
1715 p->state = XML_TEXTWRITER_ATTRIBUTE;
1716 break;
1717 default:
1718 return -1;
1719 }
1720
1721 return sum;
1722}
1723
1724/**
1725 * xmlTextWriterStartAttributeNS:
1726 * @writer: the xmlTextWriterPtr
1727 * @prefix: namespace prefix or NULL
1728 * @name: element local name
1729 * @namespaceURI: namespace URI or NULL
1730 *
1731 * Start an xml attribute with namespace support.
1732 *
1733 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1734 */
1735int
1736xmlTextWriterStartAttributeNS(xmlTextWriterPtr writer,
1737 const xmlChar * prefix, const xmlChar * name,
1738 const xmlChar * namespaceURI)
1739{
1740 int count;
1741 int sum;
1742 xmlChar *buf;
1743 xmlTextWriterNsStackEntry *p;
1744
1745 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1746 return -1;
1747
1748 buf = 0;
1749 if (prefix != 0) {
1750 buf = xmlStrdup(prefix);
1751 buf = xmlStrcat(buf, BAD_CAST ":");
1752 }
1753 buf = xmlStrcat(buf, name);
1754
1755 sum = 0;
1756 count = xmlTextWriterStartAttribute(writer, buf);
1757 xmlFree(buf);
1758 if (count < 0)
1759 return -1;
1760 sum += count;
1761
1762 if (namespaceURI != 0) {
1763 buf = xmlStrdup(BAD_CAST "xmlns");
1764 if (prefix != 0) {
1765 buf = xmlStrcat(buf, BAD_CAST ":");
1766 buf = xmlStrcat(buf, prefix);
1767 }
1768
1769 p = (xmlTextWriterNsStackEntry *)
1770 xmlMalloc(sizeof(xmlTextWriterNsStackEntry));
1771 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00001772 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00001773 "xmlTextWriterStartAttributeNS : out of memory!\n");
1774 return -1;
1775 }
1776
1777 p->prefix = buf;
1778 p->uri = xmlStrdup(namespaceURI);
1779 if (p->uri == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00001780 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00001781 "xmlTextWriterStartAttributeNS : out of memory!\n");
1782 xmlFree(p);
1783 return -1;
1784 }
1785 p->elem = xmlListFront(writer->nodes);
1786
1787 xmlListPushFront(writer->nsstack, p);
1788 }
1789
1790 return sum;
1791}
1792
1793/**
1794 * xmlTextWriterEndAttribute:
1795 * @writer: the xmlTextWriterPtr
1796 *
1797 * End the current xml element.
1798 *
1799 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1800 */
1801int
1802xmlTextWriterEndAttribute(xmlTextWriterPtr writer)
1803{
1804 int count;
1805 int sum;
1806 xmlLinkPtr lk;
1807 xmlTextWriterStackEntry *p;
1808 xmlTextWriterNsStackEntry *np;
1809
1810 if (writer == NULL)
1811 return -1;
1812
1813 lk = xmlListFront(writer->nodes);
1814 if (lk == 0) {
1815 xmlListDelete(writer->nsstack);
Daniel Veillarde43cc572004-11-03 11:50:29 +00001816 writer->nsstack = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001817 return -1;
1818 }
1819
1820 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1821 if (p == 0) {
1822 xmlListDelete(writer->nsstack);
Daniel Veillarde43cc572004-11-03 11:50:29 +00001823 writer->nsstack = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001824 return -1;
1825 }
1826
1827 sum = 0;
1828 switch (p->state) {
1829 case XML_TEXTWRITER_ATTRIBUTE:
1830 p->state = XML_TEXTWRITER_NAME;
1831
1832 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
1833 if (count < 0) {
1834 xmlListDelete(writer->nsstack);
Daniel Veillarde43cc572004-11-03 11:50:29 +00001835 writer->nsstack = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001836 return -1;
1837 }
1838 sum += count;
1839
1840 while (!xmlListEmpty(writer->nsstack)) {
Daniel Veillardbd8fb0a2005-02-21 13:49:46 +00001841 xmlChar *namespaceURI = NULL;
1842 xmlChar *prefix = NULL;
1843
Daniel Veillard1d211e22003-10-20 22:32:39 +00001844 lk = xmlListFront(writer->nsstack);
1845 np = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
Daniel Veillardbd8fb0a2005-02-21 13:49:46 +00001846
1847 if (np != 0) {
Daniel Veillard614fdc12005-02-23 14:05:37 +00001848 namespaceURI = xmlStrdup(np->uri);
1849 prefix = xmlStrdup(np->prefix);
Daniel Veillardbd8fb0a2005-02-21 13:49:46 +00001850 }
1851
1852 xmlListPopFront(writer->nsstack);
1853
Daniel Veillard1d211e22003-10-20 22:32:39 +00001854 if (np != 0) {
1855 count =
Daniel Veillardbd8fb0a2005-02-21 13:49:46 +00001856 xmlTextWriterWriteAttribute(writer, prefix,
1857 namespaceURI);
1858 xmlFree(namespaceURI);
1859 xmlFree(prefix);
1860
Daniel Veillard1d211e22003-10-20 22:32:39 +00001861 if (count < 0) {
1862 xmlListDelete(writer->nsstack);
Daniel Veillarde43cc572004-11-03 11:50:29 +00001863 writer->nsstack = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001864 return -1;
1865 }
1866 sum += count;
1867 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001868 }
1869 break;
1870
1871 default:
1872 xmlListClear(writer->nsstack);
1873 return -1;
1874 }
1875
1876 return sum;
1877}
1878
1879/**
1880 * xmlTextWriterWriteFormatAttribute:
1881 * @writer: the xmlTextWriterPtr
1882 * @name: attribute name
1883 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001884 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001885 *
1886 * Write a formatted xml attribute.
1887 *
1888 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1889 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00001890int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00001891xmlTextWriterWriteFormatAttribute(xmlTextWriterPtr writer,
1892 const xmlChar * name, const char *format,
1893 ...)
1894{
1895 int rc;
1896 va_list ap;
1897
1898 va_start(ap, format);
1899
1900 rc = xmlTextWriterWriteVFormatAttribute(writer, name, format, ap);
1901
1902 va_end(ap);
1903 return rc;
1904}
1905
1906/**
1907 * xmlTextWriterWriteVFormatAttribute:
1908 * @writer: the xmlTextWriterPtr
1909 * @name: attribute name
1910 * @format: format string (see printf)
1911 * @argptr: pointer to the first member of the variable argument list.
1912 *
1913 * Write a formatted xml attribute.
1914 *
1915 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1916 */
1917int
1918xmlTextWriterWriteVFormatAttribute(xmlTextWriterPtr writer,
1919 const xmlChar * name,
1920 const char *format, va_list argptr)
1921{
1922 int rc;
1923 xmlChar *buf;
1924
1925 if (writer == NULL)
1926 return -1;
1927
1928 buf = xmlTextWriterVSprintf(format, argptr);
1929 if (buf == 0)
1930 return 0;
1931
1932 rc = xmlTextWriterWriteAttribute(writer, name, buf);
1933
1934 xmlFree(buf);
1935 return rc;
1936}
1937
1938/**
1939 * xmlTextWriterWriteAttribute:
1940 * @writer: the xmlTextWriterPtr
1941 * @name: attribute name
1942 * @content: attribute content
1943 *
1944 * Write an xml attribute.
1945 *
1946 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1947 */
1948int
1949xmlTextWriterWriteAttribute(xmlTextWriterPtr writer, const xmlChar * name,
1950 const xmlChar * content)
1951{
1952 int count;
1953 int sum;
1954
1955 sum = 0;
1956 count = xmlTextWriterStartAttribute(writer, name);
1957 if (count < 0)
1958 return -1;
1959 sum += count;
1960 count = xmlTextWriterWriteString(writer, content);
1961 if (count < 0)
1962 return -1;
1963 sum += count;
1964 count = xmlTextWriterEndAttribute(writer);
1965 if (count < 0)
1966 return -1;
1967 sum += count;
1968
1969 return sum;
1970}
1971
1972/**
1973 * xmlTextWriterWriteFormatAttributeNS:
1974 * @writer: the xmlTextWriterPtr
1975 * @prefix: namespace prefix
1976 * @name: attribute local name
1977 * @namespaceURI: namespace URI
1978 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001979 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001980 *
1981 * Write a formatted xml attribute.with namespace support
1982 *
1983 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1984 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00001985int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00001986xmlTextWriterWriteFormatAttributeNS(xmlTextWriterPtr writer,
1987 const xmlChar * prefix,
1988 const xmlChar * name,
1989 const xmlChar * namespaceURI,
1990 const char *format, ...)
1991{
1992 int rc;
1993 va_list ap;
1994
1995 va_start(ap, format);
1996
1997 rc = xmlTextWriterWriteVFormatAttributeNS(writer, prefix, name,
1998 namespaceURI, format, ap);
1999
2000 va_end(ap);
2001 return rc;
2002}
2003
2004/**
2005 * xmlTextWriterWriteVFormatAttributeNS:
2006 * @writer: the xmlTextWriterPtr
2007 * @prefix: namespace prefix
2008 * @name: attribute local name
2009 * @namespaceURI: namespace URI
2010 * @format: format string (see printf)
2011 * @argptr: pointer to the first member of the variable argument list.
2012 *
2013 * Write a formatted xml attribute.with namespace support
2014 *
2015 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2016 */
2017int
2018xmlTextWriterWriteVFormatAttributeNS(xmlTextWriterPtr writer,
2019 const xmlChar * prefix,
2020 const xmlChar * name,
2021 const xmlChar * namespaceURI,
2022 const char *format, va_list argptr)
2023{
2024 int rc;
2025 xmlChar *buf;
2026
2027 if (writer == NULL)
2028 return -1;
2029
2030 buf = xmlTextWriterVSprintf(format, argptr);
2031 if (buf == 0)
2032 return 0;
2033
2034 rc = xmlTextWriterWriteAttributeNS(writer, prefix, name, namespaceURI,
2035 buf);
2036
2037 xmlFree(buf);
2038 return rc;
2039}
2040
2041/**
2042 * xmlTextWriterWriteAttributeNS:
2043 * @writer: the xmlTextWriterPtr
2044 * @prefix: namespace prefix
2045 * @name: attribute local name
2046 * @namespaceURI: namespace URI
2047 * @content: attribute content
2048 *
2049 * Write an xml attribute.
2050 *
2051 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2052 */
2053int
2054xmlTextWriterWriteAttributeNS(xmlTextWriterPtr writer,
2055 const xmlChar * prefix, const xmlChar * name,
2056 const xmlChar * namespaceURI,
2057 const xmlChar * content)
2058{
2059 int count;
2060 int sum;
2061 xmlChar *buf;
2062
2063 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
2064 return -1;
2065
2066 buf = 0;
2067 if (prefix != NULL) {
2068 buf = xmlStrdup(prefix);
2069 buf = xmlStrcat(buf, BAD_CAST ":");
2070 }
2071 buf = xmlStrcat(buf, name);
2072
2073 sum = 0;
2074 count = xmlTextWriterWriteAttribute(writer, buf, content);
2075 xmlFree(buf);
2076 if (count < 0)
2077 return -1;
2078 sum += count;
2079
2080 if (namespaceURI != NULL) {
2081 buf = 0;
2082 buf = xmlStrdup(BAD_CAST "xmlns");
2083 if (prefix != NULL) {
2084 buf = xmlStrcat(buf, BAD_CAST ":");
2085 buf = xmlStrcat(buf, prefix);
2086 }
2087 count = xmlTextWriterWriteAttribute(writer, buf, namespaceURI);
2088 xmlFree(buf);
2089 if (count < 0)
2090 return -1;
2091 sum += count;
2092 }
2093 return sum;
2094}
2095
2096/**
2097 * xmlTextWriterWriteFormatElement:
2098 * @writer: the xmlTextWriterPtr
2099 * @name: element name
2100 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002101 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002102 *
2103 * Write a formatted xml element.
2104 *
2105 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2106 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00002107int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00002108xmlTextWriterWriteFormatElement(xmlTextWriterPtr writer,
2109 const xmlChar * name, const char *format,
2110 ...)
2111{
2112 int rc;
2113 va_list ap;
2114
2115 va_start(ap, format);
2116
2117 rc = xmlTextWriterWriteVFormatElement(writer, name, format, ap);
2118
2119 va_end(ap);
2120 return rc;
2121}
2122
2123/**
2124 * xmlTextWriterWriteVFormatElement:
2125 * @writer: the xmlTextWriterPtr
2126 * @name: element name
2127 * @format: format string (see printf)
2128 * @argptr: pointer to the first member of the variable argument list.
2129 *
2130 * Write a formatted xml element.
2131 *
2132 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2133 */
2134int
2135xmlTextWriterWriteVFormatElement(xmlTextWriterPtr writer,
2136 const xmlChar * name, const char *format,
2137 va_list argptr)
2138{
2139 int rc;
2140 xmlChar *buf;
2141
2142 if (writer == NULL)
2143 return -1;
2144
2145 buf = xmlTextWriterVSprintf(format, argptr);
2146 if (buf == 0)
2147 return 0;
2148
2149 rc = xmlTextWriterWriteElement(writer, name, buf);
2150
2151 xmlFree(buf);
2152 return rc;
2153}
2154
2155/**
2156 * xmlTextWriterWriteElement:
2157 * @writer: the xmlTextWriterPtr
2158 * @name: element name
2159 * @content: element content
2160 *
2161 * Write an xml element.
2162 *
2163 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2164 */
2165int
2166xmlTextWriterWriteElement(xmlTextWriterPtr writer, const xmlChar * name,
2167 const xmlChar * content)
2168{
2169 int count;
2170 int sum;
2171
2172 sum = 0;
2173 count = xmlTextWriterStartElement(writer, name);
2174 if (count == -1)
2175 return -1;
2176 sum += count;
2177 count = xmlTextWriterWriteString(writer, content);
2178 if (count == -1)
2179 return -1;
2180 sum += count;
2181 count = xmlTextWriterEndElement(writer);
2182 if (count == -1)
2183 return -1;
2184 sum += count;
2185
2186 return sum;
2187}
2188
2189/**
2190 * xmlTextWriterWriteFormatElementNS:
2191 * @writer: the xmlTextWriterPtr
2192 * @prefix: namespace prefix
2193 * @name: element local name
2194 * @namespaceURI: namespace URI
2195 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002196 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002197 *
2198 * Write a formatted xml element with namespace support.
2199 *
2200 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2201 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00002202int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00002203xmlTextWriterWriteFormatElementNS(xmlTextWriterPtr writer,
2204 const xmlChar * prefix,
2205 const xmlChar * name,
2206 const xmlChar * namespaceURI,
2207 const char *format, ...)
2208{
2209 int rc;
2210 va_list ap;
2211
2212 va_start(ap, format);
2213
2214 rc = xmlTextWriterWriteVFormatElementNS(writer, prefix, name,
2215 namespaceURI, format, ap);
2216
2217 va_end(ap);
2218 return rc;
2219}
2220
2221/**
2222 * xmlTextWriterWriteVFormatElementNS:
2223 * @writer: the xmlTextWriterPtr
2224 * @prefix: namespace prefix
2225 * @name: element local name
2226 * @namespaceURI: namespace URI
2227 * @format: format string (see printf)
2228 * @argptr: pointer to the first member of the variable argument list.
2229 *
2230 * Write a formatted xml element with namespace support.
2231 *
2232 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2233 */
2234int
2235xmlTextWriterWriteVFormatElementNS(xmlTextWriterPtr writer,
2236 const xmlChar * prefix,
2237 const xmlChar * name,
2238 const xmlChar * namespaceURI,
2239 const char *format, va_list argptr)
2240{
2241 int rc;
2242 xmlChar *buf;
2243
2244 if (writer == NULL)
2245 return -1;
2246
2247 buf = xmlTextWriterVSprintf(format, argptr);
2248 if (buf == 0)
2249 return 0;
2250
2251 rc = xmlTextWriterWriteElementNS(writer, prefix, name, namespaceURI,
2252 buf);
2253
2254 xmlFree(buf);
2255 return rc;
2256}
2257
2258/**
2259 * xmlTextWriterWriteElementNS:
2260 * @writer: the xmlTextWriterPtr
2261 * @prefix: namespace prefix
2262 * @name: element local name
2263 * @namespaceURI: namespace URI
2264 * @content: element content
2265 *
2266 * Write an xml element with namespace support.
2267 *
2268 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2269 */
2270int
2271xmlTextWriterWriteElementNS(xmlTextWriterPtr writer,
2272 const xmlChar * prefix, const xmlChar * name,
2273 const xmlChar * namespaceURI,
2274 const xmlChar * content)
2275{
2276 int count;
2277 int sum;
2278
2279 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
2280 return -1;
2281
2282 sum = 0;
2283 count =
2284 xmlTextWriterStartElementNS(writer, prefix, name, namespaceURI);
2285 if (count < 0)
2286 return -1;
2287 sum += count;
2288 count = xmlTextWriterWriteString(writer, content);
2289 if (count == -1)
2290 return -1;
2291 sum += count;
2292 count = xmlTextWriterEndElement(writer);
2293 if (count == -1)
2294 return -1;
2295 sum += count;
2296
2297 return sum;
2298}
2299
2300/**
2301 * xmlTextWriterStartPI:
2302 * @writer: the xmlTextWriterPtr
2303 * @target: PI target
2304 *
2305 * Start an xml PI.
2306 *
2307 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2308 */
2309int
2310xmlTextWriterStartPI(xmlTextWriterPtr writer, const xmlChar * target)
2311{
2312 int count;
2313 int sum;
2314 xmlLinkPtr lk;
2315 xmlTextWriterStackEntry *p;
2316
2317 if ((writer == NULL) || (target == NULL) || (*target == '\0'))
2318 return -1;
2319
2320 if (xmlStrcasecmp(target, (const xmlChar *) "xml") == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002321 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002322 "xmlTextWriterStartPI : target name [Xx][Mm][Ll] is reserved for xml standardization!\n");
2323 return -1;
2324 }
2325
2326 sum = 0;
2327 lk = xmlListFront(writer->nodes);
2328 if (lk != 0) {
2329 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2330 if (p != 0) {
2331 switch (p->state) {
2332 case XML_TEXTWRITER_ATTRIBUTE:
2333 count = xmlTextWriterEndAttribute(writer);
2334 if (count < 0)
2335 return -1;
2336 sum += count;
2337 /* fallthrough */
2338 case XML_TEXTWRITER_NAME:
2339 count = xmlOutputBufferWriteString(writer->out, ">");
2340 if (count < 0)
2341 return -1;
2342 sum += count;
2343 p->state = XML_TEXTWRITER_TEXT;
2344 break;
Daniel Veillardab69f362004-02-17 11:40:32 +00002345 case XML_TEXTWRITER_NONE:
2346 case XML_TEXTWRITER_TEXT:
2347 case XML_TEXTWRITER_DTD:
2348 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002349 case XML_TEXTWRITER_PI:
2350 case XML_TEXTWRITER_PI_TEXT:
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002351 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002352 "xmlTextWriterStartPI : nested PI!\n");
2353 return -1;
2354 default:
2355 return -1;
2356 }
2357 }
2358 }
2359
2360 p = (xmlTextWriterStackEntry *)
2361 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2362 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002363 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002364 "xmlTextWriterStartPI : out of memory!\n");
2365 return -1;
2366 }
2367
2368 p->name = xmlStrdup(target);
2369 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002370 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002371 "xmlTextWriterStartPI : out of memory!\n");
2372 xmlFree(p);
2373 return -1;
2374 }
2375 p->state = XML_TEXTWRITER_PI;
2376
2377 xmlListPushFront(writer->nodes, p);
2378
2379 count = xmlOutputBufferWriteString(writer->out, "<?");
2380 if (count < 0)
2381 return -1;
2382 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002383 count =
2384 xmlOutputBufferWriteString(writer->out, (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002385 if (count < 0)
2386 return -1;
2387 sum += count;
2388
2389 return sum;
2390}
2391
2392/**
2393 * xmlTextWriterEndPI:
2394 * @writer: the xmlTextWriterPtr
2395 *
2396 * End the current xml PI.
2397 *
2398 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2399 */
2400int
2401xmlTextWriterEndPI(xmlTextWriterPtr writer)
2402{
2403 int count;
2404 int sum;
2405 xmlLinkPtr lk;
2406 xmlTextWriterStackEntry *p;
2407
2408 if (writer == NULL)
2409 return -1;
2410
2411 lk = xmlListFront(writer->nodes);
2412 if (lk == 0)
2413 return 0;
2414
2415 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2416 if (p == 0)
2417 return 0;
2418
2419 sum = 0;
2420 switch (p->state) {
2421 case XML_TEXTWRITER_PI:
2422 case XML_TEXTWRITER_PI_TEXT:
2423 count = xmlOutputBufferWriteString(writer->out, "?>");
2424 if (count < 0)
2425 return -1;
2426 sum += count;
2427 break;
2428 default:
2429 return -1;
2430 }
2431
2432 xmlListPopFront(writer->nodes);
2433 return sum;
2434}
2435
2436/**
2437 * xmlTextWriterWriteFormatPI:
2438 * @writer: the xmlTextWriterPtr
2439 * @target: PI target
2440 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002441 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002442 *
2443 * Write a formatted PI.
2444 *
2445 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2446 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00002447int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00002448xmlTextWriterWriteFormatPI(xmlTextWriterPtr writer, const xmlChar * target,
2449 const char *format, ...)
2450{
2451 int rc;
2452 va_list ap;
2453
2454 va_start(ap, format);
2455
2456 rc = xmlTextWriterWriteVFormatPI(writer, target, format, ap);
2457
2458 va_end(ap);
2459 return rc;
2460}
2461
2462/**
2463 * xmlTextWriterWriteVFormatPI:
2464 * @writer: the xmlTextWriterPtr
2465 * @target: PI target
2466 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002467 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00002468 *
2469 * Write a formatted xml PI.
2470 *
2471 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2472 */
2473int
2474xmlTextWriterWriteVFormatPI(xmlTextWriterPtr writer,
2475 const xmlChar * target, const char *format,
2476 va_list argptr)
2477{
2478 int rc;
2479 xmlChar *buf;
2480
2481 if (writer == NULL)
2482 return -1;
2483
2484 buf = xmlTextWriterVSprintf(format, argptr);
2485 if (buf == 0)
2486 return 0;
2487
2488 rc = xmlTextWriterWritePI(writer, target, buf);
2489
2490 xmlFree(buf);
2491 return rc;
2492}
2493
2494/**
2495 * xmlTextWriterWritePI:
2496 * @writer: the xmlTextWriterPtr
2497 * @target: PI target
2498 * @content: PI content
2499 *
2500 * Write an xml PI.
2501 *
2502 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2503 */
2504int
2505xmlTextWriterWritePI(xmlTextWriterPtr writer, const xmlChar * target,
2506 const xmlChar * content)
2507{
2508 int count;
2509 int sum;
2510
2511 sum = 0;
2512 count = xmlTextWriterStartPI(writer, target);
2513 if (count == -1)
2514 return -1;
2515 sum += count;
2516 if (content != 0) {
2517 count = xmlTextWriterWriteString(writer, content);
2518 if (count == -1)
2519 return -1;
2520 sum += count;
2521 }
2522 count = xmlTextWriterEndPI(writer);
2523 if (count == -1)
2524 return -1;
2525 sum += count;
2526
2527 return sum;
2528}
2529
2530/**
2531 * xmlTextWriterStartCDATA:
2532 * @writer: the xmlTextWriterPtr
2533 *
2534 * Start an xml CDATA section.
2535 *
2536 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2537 */
2538int
2539xmlTextWriterStartCDATA(xmlTextWriterPtr writer)
2540{
2541 int count;
2542 int sum;
2543 xmlLinkPtr lk;
2544 xmlTextWriterStackEntry *p;
2545
2546 if (writer == NULL)
2547 return -1;
2548
2549 sum = 0;
2550 lk = xmlListFront(writer->nodes);
2551 if (lk != 0) {
2552 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2553 if (p != 0) {
2554 switch (p->state) {
2555 case XML_TEXTWRITER_NONE:
2556 case XML_TEXTWRITER_PI:
2557 case XML_TEXTWRITER_PI_TEXT:
2558 break;
2559 case XML_TEXTWRITER_ATTRIBUTE:
2560 count = xmlTextWriterEndAttribute(writer);
2561 if (count < 0)
2562 return -1;
2563 sum += count;
2564 /* fallthrough */
2565 case XML_TEXTWRITER_NAME:
2566 count = xmlOutputBufferWriteString(writer->out, ">");
2567 if (count < 0)
2568 return -1;
2569 sum += count;
2570 p->state = XML_TEXTWRITER_TEXT;
2571 break;
2572 case XML_TEXTWRITER_CDATA:
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002573 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002574 "xmlTextWriterStartCDATA : CDATA not allowed in this context!\n");
2575 return -1;
2576 default:
2577 return -1;
2578 }
2579 }
2580 }
2581
2582 p = (xmlTextWriterStackEntry *)
2583 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2584 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002585 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002586 "xmlTextWriterStartCDATA : out of memory!\n");
2587 return -1;
2588 }
2589
2590 p->name = 0;
2591 p->state = XML_TEXTWRITER_CDATA;
2592
2593 xmlListPushFront(writer->nodes, p);
2594
2595 count = xmlOutputBufferWriteString(writer->out, "<![CDATA[");
2596 if (count < 0)
2597 return -1;
2598 sum += count;
2599
2600 return sum;
2601}
2602
2603/**
2604 * xmlTextWriterEndCDATA:
2605 * @writer: the xmlTextWriterPtr
2606 *
2607 * End an xml CDATA section.
2608 *
2609 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2610 */
2611int
2612xmlTextWriterEndCDATA(xmlTextWriterPtr writer)
2613{
2614 int count;
2615 int sum;
2616 xmlLinkPtr lk;
2617 xmlTextWriterStackEntry *p;
2618
2619 if (writer == NULL)
2620 return -1;
2621
2622 lk = xmlListFront(writer->nodes);
2623 if (lk == 0)
2624 return -1;
2625
2626 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2627 if (p == 0)
2628 return -1;
2629
2630 sum = 0;
2631 switch (p->state) {
2632 case XML_TEXTWRITER_CDATA:
2633 count = xmlOutputBufferWriteString(writer->out, "]]>");
2634 if (count < 0)
2635 return -1;
2636 sum += count;
2637 break;
2638 default:
2639 return -1;
2640 }
2641
2642 xmlListPopFront(writer->nodes);
2643 return sum;
2644}
2645
2646/**
2647 * xmlTextWriterWriteFormatCDATA:
2648 * @writer: the xmlTextWriterPtr
2649 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002650 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002651 *
2652 * Write a formatted xml CDATA.
2653 *
2654 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2655 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00002656int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00002657xmlTextWriterWriteFormatCDATA(xmlTextWriterPtr writer, const char *format,
2658 ...)
2659{
2660 int rc;
2661 va_list ap;
2662
2663 va_start(ap, format);
2664
2665 rc = xmlTextWriterWriteVFormatCDATA(writer, format, ap);
2666
2667 va_end(ap);
2668 return rc;
2669}
2670
2671/**
2672 * xmlTextWriterWriteVFormatCDATA:
2673 * @writer: the xmlTextWriterPtr
2674 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002675 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00002676 *
2677 * Write a formatted xml CDATA.
2678 *
2679 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2680 */
2681int
2682xmlTextWriterWriteVFormatCDATA(xmlTextWriterPtr writer, const char *format,
2683 va_list argptr)
2684{
2685 int rc;
2686 xmlChar *buf;
2687
2688 if (writer == NULL)
2689 return -1;
2690
2691 buf = xmlTextWriterVSprintf(format, argptr);
2692 if (buf == 0)
2693 return 0;
2694
2695 rc = xmlTextWriterWriteCDATA(writer, buf);
2696
2697 xmlFree(buf);
2698 return rc;
2699}
2700
2701/**
2702 * xmlTextWriterWriteCDATA:
2703 * @writer: the xmlTextWriterPtr
2704 * @content: CDATA content
2705 *
2706 * Write an xml CDATA.
2707 *
2708 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2709 */
2710int
2711xmlTextWriterWriteCDATA(xmlTextWriterPtr writer, const xmlChar * content)
2712{
2713 int count;
2714 int sum;
2715
2716 sum = 0;
2717 count = xmlTextWriterStartCDATA(writer);
2718 if (count == -1)
2719 return -1;
2720 sum += count;
2721 if (content != 0) {
2722 count = xmlTextWriterWriteString(writer, content);
2723 if (count == -1)
2724 return -1;
2725 sum += count;
2726 }
2727 count = xmlTextWriterEndCDATA(writer);
2728 if (count == -1)
2729 return -1;
2730 sum += count;
2731
2732 return sum;
2733}
2734
2735/**
2736 * xmlTextWriterStartDTD:
2737 * @writer: the xmlTextWriterPtr
2738 * @name: the name of the DTD
2739 * @pubid: the public identifier, which is an alternative to the system identifier
2740 * @sysid: the system identifier, which is the URI of the DTD
2741 *
2742 * Start an xml DTD.
2743 *
2744 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2745 */
2746int
2747xmlTextWriterStartDTD(xmlTextWriterPtr writer,
2748 const xmlChar * name,
2749 const xmlChar * pubid, const xmlChar * sysid)
2750{
2751 int count;
2752 int sum;
2753 xmlLinkPtr lk;
2754 xmlTextWriterStackEntry *p;
2755
2756 if (writer == NULL || name == NULL || *name == '\0')
2757 return -1;
2758
2759 sum = 0;
2760 lk = xmlListFront(writer->nodes);
Daniel Veillardab69f362004-02-17 11:40:32 +00002761 if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002762 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002763 "xmlTextWriterStartDTD : DTD allowed only in prolog!\n");
2764 return -1;
2765 }
2766
2767 p = (xmlTextWriterStackEntry *)
2768 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2769 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002770 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002771 "xmlTextWriterStartDTD : out of memory!\n");
2772 return -1;
2773 }
2774
2775 p->name = xmlStrdup(name);
2776 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002777 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002778 "xmlTextWriterStartDTD : out of memory!\n");
2779 xmlFree(p);
2780 return -1;
2781 }
2782 p->state = XML_TEXTWRITER_DTD;
2783
2784 xmlListPushFront(writer->nodes, p);
2785
2786 count = xmlOutputBufferWriteString(writer->out, "<!DOCTYPE ");
2787 if (count < 0)
2788 return -1;
2789 sum += count;
2790 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
2791 if (count < 0)
2792 return -1;
2793 sum += count;
2794
2795 if (pubid != 0) {
2796 if (sysid == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002797 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002798 "xmlTextWriterStartDTD : system identifier needed!\n");
2799 return -1;
2800 }
2801
Daniel Veillard500a1de2004-03-22 15:22:58 +00002802 if (writer->indent)
2803 count = xmlOutputBufferWrite(writer->out, 1, "\n");
2804 else
2805 count = xmlOutputBufferWrite(writer->out, 1, " ");
2806 if (count < 0)
2807 return -1;
2808 sum += count;
2809
2810 count = xmlOutputBufferWriteString(writer->out, "PUBLIC ");
2811 if (count < 0)
2812 return -1;
2813 sum += count;
2814
2815 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002816 if (count < 0)
2817 return -1;
2818 sum += count;
2819
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002820 count =
2821 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002822 if (count < 0)
2823 return -1;
2824 sum += count;
2825
Daniel Veillard500a1de2004-03-22 15:22:58 +00002826 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002827 if (count < 0)
2828 return -1;
2829 sum += count;
2830 }
2831
2832 if (sysid != 0) {
2833 if (pubid == 0) {
Daniel Veillard500a1de2004-03-22 15:22:58 +00002834 if (writer->indent)
2835 count = xmlOutputBufferWrite(writer->out, 1, "\n");
2836 else
2837 count = xmlOutputBufferWrite(writer->out, 1, " ");
2838 if (count < 0)
2839 return -1;
2840 sum += count;
2841 count = xmlOutputBufferWriteString(writer->out, "SYSTEM ");
2842 if (count < 0)
2843 return -1;
2844 sum += count;
2845 } else if (writer->indent) {
2846 count = xmlOutputBufferWriteString(writer->out, "\n ");
Daniel Veillard1d211e22003-10-20 22:32:39 +00002847 if (count < 0)
2848 return -1;
2849 sum += count;
2850 }
2851
Daniel Veillard500a1de2004-03-22 15:22:58 +00002852 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002853 if (count < 0)
2854 return -1;
2855 sum += count;
2856
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002857 count =
2858 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002859 if (count < 0)
2860 return -1;
2861 sum += count;
2862
Daniel Veillard500a1de2004-03-22 15:22:58 +00002863 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002864 if (count < 0)
2865 return -1;
2866 sum += count;
2867 }
2868
2869 return sum;
2870}
2871
2872/**
2873 * xmlTextWriterEndDTD:
2874 * @writer: the xmlTextWriterPtr
2875 *
2876 * End an xml DTD.
2877 *
2878 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2879 */
2880int
2881xmlTextWriterEndDTD(xmlTextWriterPtr writer)
2882{
Daniel Veillard500a1de2004-03-22 15:22:58 +00002883 int loop;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002884 int count;
2885 int sum;
2886 xmlLinkPtr lk;
2887 xmlTextWriterStackEntry *p;
2888
2889 if (writer == NULL)
2890 return -1;
2891
2892 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00002893 loop = 1;
2894 while (loop) {
2895 lk = xmlListFront(writer->nodes);
2896 if (lk == NULL)
Daniel Veillard1d211e22003-10-20 22:32:39 +00002897 break;
Daniel Veillard500a1de2004-03-22 15:22:58 +00002898 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2899 if (p == 0)
2900 break;
2901 switch (p->state) {
2902 case XML_TEXTWRITER_DTD_TEXT:
2903 count = xmlOutputBufferWriteString(writer->out, "]");
2904 if (count < 0)
2905 return -1;
2906 sum += count;
2907 /* fallthrough */
2908 case XML_TEXTWRITER_DTD:
2909 count = xmlOutputBufferWriteString(writer->out, ">");
2910
2911 if (writer->indent) {
2912 if (count < 0)
2913 return -1;
2914 sum += count;
2915 count = xmlOutputBufferWriteString(writer->out, "\n");
2916 }
2917
2918 xmlListPopFront(writer->nodes);
2919 break;
2920 case XML_TEXTWRITER_DTD_ELEM:
2921 case XML_TEXTWRITER_DTD_ELEM_TEXT:
2922 count = xmlTextWriterEndDTDElement(writer);
2923 break;
2924 case XML_TEXTWRITER_DTD_ATTL:
2925 case XML_TEXTWRITER_DTD_ATTL_TEXT:
2926 count = xmlTextWriterEndDTDAttlist(writer);
2927 break;
2928 case XML_TEXTWRITER_DTD_ENTY:
2929 case XML_TEXTWRITER_DTD_PENT:
2930 case XML_TEXTWRITER_DTD_ENTY_TEXT:
2931 count = xmlTextWriterEndDTDEntity(writer);
2932 break;
2933 case XML_TEXTWRITER_COMMENT:
2934 count = xmlTextWriterEndComment(writer);
2935 break;
2936 default:
2937 loop = 0;
2938 continue;
2939 }
2940
2941 if (count < 0)
Daniel Veillard1d211e22003-10-20 22:32:39 +00002942 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00002943 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002944 }
2945
Daniel Veillard1d211e22003-10-20 22:32:39 +00002946 return sum;
2947}
2948
2949/**
2950 * xmlTextWriterWriteFormatDTD:
2951 * @writer: the xmlTextWriterPtr
2952 * @name: the name of the DTD
2953 * @pubid: the public identifier, which is an alternative to the system identifier
2954 * @sysid: the system identifier, which is the URI of the DTD
2955 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002956 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002957 *
2958 * Write a DTD with a formatted markup declarations part.
2959 *
2960 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2961 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00002962int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00002963xmlTextWriterWriteFormatDTD(xmlTextWriterPtr writer,
2964 const xmlChar * name,
2965 const xmlChar * pubid,
2966 const xmlChar * sysid, const char *format, ...)
2967{
2968 int rc;
2969 va_list ap;
2970
2971 va_start(ap, format);
2972
2973 rc = xmlTextWriterWriteVFormatDTD(writer, name, pubid, sysid, format,
2974 ap);
2975
2976 va_end(ap);
2977 return rc;
2978}
2979
2980/**
2981 * xmlTextWriterWriteVFormatDTD:
2982 * @writer: the xmlTextWriterPtr
2983 * @name: the name of the DTD
2984 * @pubid: the public identifier, which is an alternative to the system identifier
2985 * @sysid: the system identifier, which is the URI of the DTD
2986 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002987 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00002988 *
2989 * Write a DTD with a formatted markup declarations part.
2990 *
2991 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2992 */
2993int
2994xmlTextWriterWriteVFormatDTD(xmlTextWriterPtr writer,
2995 const xmlChar * name,
2996 const xmlChar * pubid,
2997 const xmlChar * sysid,
2998 const char *format, va_list argptr)
2999{
3000 int rc;
3001 xmlChar *buf;
3002
3003 if (writer == NULL)
3004 return -1;
3005
3006 buf = xmlTextWriterVSprintf(format, argptr);
3007 if (buf == 0)
3008 return 0;
3009
3010 rc = xmlTextWriterWriteDTD(writer, name, pubid, sysid, buf);
3011
3012 xmlFree(buf);
3013 return rc;
3014}
3015
3016/**
3017 * xmlTextWriterWriteDTD:
3018 * @writer: the xmlTextWriterPtr
3019 * @name: the name of the DTD
3020 * @pubid: the public identifier, which is an alternative to the system identifier
3021 * @sysid: the system identifier, which is the URI of the DTD
William M. Brackb1d53162003-11-18 06:54:40 +00003022 * @subset: string content of the DTD
Daniel Veillard1d211e22003-10-20 22:32:39 +00003023 *
3024 * Write a DTD.
3025 *
3026 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3027 */
3028int
3029xmlTextWriterWriteDTD(xmlTextWriterPtr writer,
3030 const xmlChar * name,
3031 const xmlChar * pubid,
3032 const xmlChar * sysid, const xmlChar * subset)
3033{
3034 int count;
3035 int sum;
3036
3037 sum = 0;
3038 count = xmlTextWriterStartDTD(writer, name, pubid, sysid);
3039 if (count == -1)
3040 return -1;
3041 sum += count;
3042 if (subset != 0) {
3043 count = xmlTextWriterWriteString(writer, subset);
3044 if (count == -1)
3045 return -1;
3046 sum += count;
3047 }
3048 count = xmlTextWriterEndDTD(writer);
3049 if (count == -1)
3050 return -1;
3051 sum += count;
3052
3053 return sum;
3054}
3055
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003056/**
3057 * xmlTextWriterStartDTDElement:
3058 * @writer: the xmlTextWriterPtr
3059 * @name: the name of the DTD element
3060 *
3061 * Start an xml DTD element.
3062 *
3063 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3064 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003065int
3066xmlTextWriterStartDTDElement(xmlTextWriterPtr writer, const xmlChar * name)
3067{
3068 int count;
3069 int sum;
3070 xmlLinkPtr lk;
3071 xmlTextWriterStackEntry *p;
3072
3073 if (writer == NULL || name == NULL || *name == '\0')
3074 return -1;
3075
3076 sum = 0;
3077 lk = xmlListFront(writer->nodes);
3078 if (lk == 0) {
3079 return -1;
3080 }
3081
3082 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
Daniel Veillard500a1de2004-03-22 15:22:58 +00003083 if (p != 0) {
3084 switch (p->state) {
3085 case XML_TEXTWRITER_DTD:
3086 count = xmlOutputBufferWriteString(writer->out, " [");
3087 if (count < 0)
3088 return -1;
3089 sum += count;
3090 if (writer->indent) {
3091 count = xmlOutputBufferWriteString(writer->out, "\n");
3092 if (count < 0)
3093 return -1;
3094 sum += count;
3095 }
3096 p->state = XML_TEXTWRITER_DTD_TEXT;
3097 /* fallthrough */
3098 case XML_TEXTWRITER_DTD_TEXT:
3099 case XML_TEXTWRITER_NONE:
3100 break;
3101 default:
Daniel Veillard1d211e22003-10-20 22:32:39 +00003102 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00003103 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00003104 }
3105
3106 p = (xmlTextWriterStackEntry *)
3107 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3108 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003109 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003110 "xmlTextWriterStartDTDElement : out of memory!\n");
3111 return -1;
3112 }
3113
3114 p->name = xmlStrdup(name);
3115 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003116 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003117 "xmlTextWriterStartDTDElement : out of memory!\n");
3118 xmlFree(p);
3119 return -1;
3120 }
3121 p->state = XML_TEXTWRITER_DTD_ELEM;
3122
3123 xmlListPushFront(writer->nodes, p);
3124
Daniel Veillard500a1de2004-03-22 15:22:58 +00003125 if (writer->indent) {
3126 count = xmlTextWriterWriteIndent(writer);
3127 if (count < 0)
3128 return -1;
3129 sum += count;
3130 }
3131
Daniel Veillard1d211e22003-10-20 22:32:39 +00003132 count = xmlOutputBufferWriteString(writer->out, "<!ELEMENT ");
3133 if (count < 0)
3134 return -1;
3135 sum += count;
3136 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
3137 if (count < 0)
3138 return -1;
3139 sum += count;
3140
3141 return sum;
3142}
3143
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003144/**
Daniel Veillard500a1de2004-03-22 15:22:58 +00003145 * xmlTextWriterEndDTDElement:
3146 * @writer: the xmlTextWriterPtr
3147 *
3148 * End an xml DTD element.
3149 *
3150 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3151 */
3152int
3153xmlTextWriterEndDTDElement(xmlTextWriterPtr writer)
3154{
3155 int count;
3156 int sum;
3157 xmlLinkPtr lk;
3158 xmlTextWriterStackEntry *p;
3159
3160 if (writer == NULL)
3161 return -1;
3162
3163 sum = 0;
3164 lk = xmlListFront(writer->nodes);
3165 if (lk == 0)
3166 return -1;
3167
3168 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3169 if (p == 0)
3170 return -1;
3171
3172 switch (p->state) {
3173 case XML_TEXTWRITER_DTD_ELEM:
3174 case XML_TEXTWRITER_DTD_ELEM_TEXT:
3175 count = xmlOutputBufferWriteString(writer->out, ">");
3176 if (count < 0)
3177 return -1;
3178 sum += count;
3179 break;
3180 default:
3181 return -1;
3182 }
3183
3184 if (writer->indent) {
3185 count = xmlOutputBufferWriteString(writer->out, "\n");
3186 if (count < 0)
3187 return -1;
3188 sum += count;
3189 }
3190
3191 xmlListPopFront(writer->nodes);
3192 return sum;
3193}
3194
3195/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003196 * xmlTextWriterWriteFormatDTDElement:
3197 * @writer: the xmlTextWriterPtr
3198 * @name: the name of the DTD element
3199 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003200 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003201 *
3202 * Write a formatted DTD element.
3203 *
3204 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3205 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00003206int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00003207xmlTextWriterWriteFormatDTDElement(xmlTextWriterPtr writer,
3208 const xmlChar * name,
3209 const char *format, ...)
3210{
3211 int rc;
3212 va_list ap;
3213
3214 va_start(ap, format);
3215
3216 rc = xmlTextWriterWriteVFormatDTDElement(writer, name, format, ap);
3217
3218 va_end(ap);
3219 return rc;
3220}
3221
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003222/**
3223 * xmlTextWriterWriteVFormatDTDElement:
3224 * @writer: the xmlTextWriterPtr
3225 * @name: the name of the DTD element
3226 * @format: format string (see printf)
3227 * @argptr: pointer to the first member of the variable argument list.
3228 *
3229 * Write a formatted DTD element.
3230 *
3231 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3232 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003233int
3234xmlTextWriterWriteVFormatDTDElement(xmlTextWriterPtr writer,
3235 const xmlChar * name,
3236 const char *format, va_list argptr)
3237{
3238 int rc;
3239 xmlChar *buf;
3240
3241 if (writer == NULL)
3242 return -1;
3243
3244 buf = xmlTextWriterVSprintf(format, argptr);
3245 if (buf == 0)
3246 return 0;
3247
3248 rc = xmlTextWriterWriteDTDElement(writer, name, buf);
3249
3250 xmlFree(buf);
3251 return rc;
3252}
3253
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003254/**
3255 * xmlTextWriterWriteDTDElement:
3256 * @writer: the xmlTextWriterPtr
3257 * @name: the name of the DTD element
3258 * @content: content of the element
3259 *
3260 * Write a DTD element.
3261 *
3262 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3263 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003264int
3265xmlTextWriterWriteDTDElement(xmlTextWriterPtr writer,
3266 const xmlChar * name, const xmlChar * content)
3267{
3268 int count;
3269 int sum;
3270
3271 if (content == NULL)
3272 return -1;
3273
3274 sum = 0;
3275 count = xmlTextWriterStartDTDElement(writer, name);
3276 if (count == -1)
3277 return -1;
3278 sum += count;
3279
Daniel Veillard1d211e22003-10-20 22:32:39 +00003280 count = xmlTextWriterWriteString(writer, content);
3281 if (count == -1)
3282 return -1;
3283 sum += count;
3284
3285 count = xmlTextWriterEndDTDElement(writer);
3286 if (count == -1)
3287 return -1;
3288 sum += count;
3289
3290 return sum;
3291}
3292
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003293/**
3294 * xmlTextWriterStartDTDAttlist:
3295 * @writer: the xmlTextWriterPtr
3296 * @name: the name of the DTD ATTLIST
3297 *
3298 * Start an xml DTD ATTLIST.
3299 *
3300 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3301 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003302int
3303xmlTextWriterStartDTDAttlist(xmlTextWriterPtr writer, const xmlChar * name)
3304{
3305 int count;
3306 int sum;
3307 xmlLinkPtr lk;
3308 xmlTextWriterStackEntry *p;
3309
3310 if (writer == NULL || name == NULL || *name == '\0')
3311 return -1;
3312
3313 sum = 0;
3314 lk = xmlListFront(writer->nodes);
3315 if (lk == 0) {
3316 return -1;
3317 }
3318
3319 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
Daniel Veillard500a1de2004-03-22 15:22:58 +00003320 if (p != 0) {
3321 switch (p->state) {
3322 case XML_TEXTWRITER_DTD:
3323 count = xmlOutputBufferWriteString(writer->out, " [");
3324 if (count < 0)
3325 return -1;
3326 sum += count;
3327 if (writer->indent) {
3328 count = xmlOutputBufferWriteString(writer->out, "\n");
3329 if (count < 0)
3330 return -1;
3331 sum += count;
3332 }
3333 p->state = XML_TEXTWRITER_DTD_TEXT;
3334 /* fallthrough */
3335 case XML_TEXTWRITER_DTD_TEXT:
3336 case XML_TEXTWRITER_NONE:
3337 break;
3338 default:
Daniel Veillard1d211e22003-10-20 22:32:39 +00003339 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00003340 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00003341 }
3342
3343 p = (xmlTextWriterStackEntry *)
3344 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3345 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003346 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003347 "xmlTextWriterStartDTDAttlist : out of memory!\n");
3348 return -1;
3349 }
3350
3351 p->name = xmlStrdup(name);
3352 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003353 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003354 "xmlTextWriterStartDTDAttlist : out of memory!\n");
3355 xmlFree(p);
3356 return -1;
3357 }
3358 p->state = XML_TEXTWRITER_DTD_ATTL;
3359
3360 xmlListPushFront(writer->nodes, p);
3361
Daniel Veillard500a1de2004-03-22 15:22:58 +00003362 if (writer->indent) {
3363 count = xmlTextWriterWriteIndent(writer);
3364 if (count < 0)
3365 return -1;
3366 sum += count;
3367 }
3368
Daniel Veillard1d211e22003-10-20 22:32:39 +00003369 count = xmlOutputBufferWriteString(writer->out, "<!ATTLIST ");
3370 if (count < 0)
3371 return -1;
3372 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +00003373 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003374 if (count < 0)
3375 return -1;
3376 sum += count;
3377
3378 return sum;
3379}
3380
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003381/**
Daniel Veillard500a1de2004-03-22 15:22:58 +00003382 * xmlTextWriterEndDTDAttlist:
3383 * @writer: the xmlTextWriterPtr
3384 *
3385 * End an xml DTD attribute list.
3386 *
3387 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3388 */
3389int
3390xmlTextWriterEndDTDAttlist(xmlTextWriterPtr writer)
3391{
3392 int count;
3393 int sum;
3394 xmlLinkPtr lk;
3395 xmlTextWriterStackEntry *p;
3396
3397 if (writer == NULL)
3398 return -1;
3399
3400 sum = 0;
3401 lk = xmlListFront(writer->nodes);
3402 if (lk == 0)
3403 return -1;
3404
3405 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3406 if (p == 0)
3407 return -1;
3408
3409 switch (p->state) {
3410 case XML_TEXTWRITER_DTD_ATTL:
3411 case XML_TEXTWRITER_DTD_ATTL_TEXT:
3412 count = xmlOutputBufferWriteString(writer->out, ">");
3413 if (count < 0)
3414 return -1;
3415 sum += count;
3416 break;
3417 default:
3418 return -1;
3419 }
3420
3421 if (writer->indent) {
3422 count = xmlOutputBufferWriteString(writer->out, "\n");
3423 if (count < 0)
3424 return -1;
3425 sum += count;
3426 }
3427
3428 xmlListPopFront(writer->nodes);
3429 return sum;
3430}
3431
3432/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003433 * xmlTextWriterWriteFormatDTDAttlist:
3434 * @writer: the xmlTextWriterPtr
3435 * @name: the name of the DTD ATTLIST
3436 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003437 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003438 *
3439 * Write a formatted DTD ATTLIST.
3440 *
3441 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3442 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00003443int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00003444xmlTextWriterWriteFormatDTDAttlist(xmlTextWriterPtr writer,
3445 const xmlChar * name,
3446 const char *format, ...)
3447{
3448 int rc;
3449 va_list ap;
3450
3451 va_start(ap, format);
3452
3453 rc = xmlTextWriterWriteVFormatDTDAttlist(writer, name, format, ap);
3454
3455 va_end(ap);
3456 return rc;
3457}
3458
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003459/**
3460 * xmlTextWriterWriteVFormatDTDAttlist:
3461 * @writer: the xmlTextWriterPtr
3462 * @name: the name of the DTD ATTLIST
3463 * @format: format string (see printf)
3464 * @argptr: pointer to the first member of the variable argument list.
3465 *
3466 * Write a formatted DTD ATTLIST.
3467 *
3468 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3469 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003470int
3471xmlTextWriterWriteVFormatDTDAttlist(xmlTextWriterPtr writer,
3472 const xmlChar * name,
3473 const char *format, va_list argptr)
3474{
3475 int rc;
3476 xmlChar *buf;
3477
3478 if (writer == NULL)
3479 return -1;
3480
3481 buf = xmlTextWriterVSprintf(format, argptr);
3482 if (buf == 0)
3483 return 0;
3484
3485 rc = xmlTextWriterWriteDTDAttlist(writer, name, buf);
3486
3487 xmlFree(buf);
3488 return rc;
3489}
3490
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003491/**
3492 * xmlTextWriterWriteDTDAttlist:
3493 * @writer: the xmlTextWriterPtr
3494 * @name: the name of the DTD ATTLIST
3495 * @content: content of the ATTLIST
3496 *
3497 * Write a DTD ATTLIST.
3498 *
3499 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3500 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003501int
3502xmlTextWriterWriteDTDAttlist(xmlTextWriterPtr writer,
3503 const xmlChar * name, const xmlChar * content)
3504{
3505 int count;
3506 int sum;
3507
3508 if (content == NULL)
3509 return -1;
3510
3511 sum = 0;
3512 count = xmlTextWriterStartDTDAttlist(writer, name);
3513 if (count == -1)
3514 return -1;
3515 sum += count;
3516
Daniel Veillard1d211e22003-10-20 22:32:39 +00003517 count = xmlTextWriterWriteString(writer, content);
3518 if (count == -1)
3519 return -1;
3520 sum += count;
3521
3522 count = xmlTextWriterEndDTDAttlist(writer);
3523 if (count == -1)
3524 return -1;
3525 sum += count;
3526
3527 return sum;
3528}
3529
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003530/**
3531 * xmlTextWriterStartDTDEntity:
3532 * @writer: the xmlTextWriterPtr
3533 * @pe: TRUE if this is a parameter entity, FALSE if not
3534 * @name: the name of the DTD ATTLIST
3535 *
3536 * Start an xml DTD ATTLIST.
3537 *
3538 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3539 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003540int
3541xmlTextWriterStartDTDEntity(xmlTextWriterPtr writer,
3542 int pe, const xmlChar * name)
3543{
3544 int count;
3545 int sum;
3546 xmlLinkPtr lk;
3547 xmlTextWriterStackEntry *p;
3548
3549 if (writer == NULL || name == NULL || *name == '\0')
3550 return -1;
3551
3552 sum = 0;
3553 lk = xmlListFront(writer->nodes);
Daniel Veillard500a1de2004-03-22 15:22:58 +00003554 if (lk != 0) {
Daniel Veillard1d211e22003-10-20 22:32:39 +00003555
Daniel Veillard500a1de2004-03-22 15:22:58 +00003556 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3557 if (p != 0) {
3558 switch (p->state) {
3559 case XML_TEXTWRITER_DTD:
3560 count = xmlOutputBufferWriteString(writer->out, " [");
3561 if (count < 0)
3562 return -1;
3563 sum += count;
3564 if (writer->indent) {
3565 count =
3566 xmlOutputBufferWriteString(writer->out, "\n");
3567 if (count < 0)
3568 return -1;
3569 sum += count;
3570 }
3571 p->state = XML_TEXTWRITER_DTD_TEXT;
3572 /* fallthrough */
3573 case XML_TEXTWRITER_DTD_TEXT:
3574 case XML_TEXTWRITER_NONE:
3575 break;
3576 default:
3577 return -1;
3578 }
3579 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00003580 }
3581
3582 p = (xmlTextWriterStackEntry *)
3583 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3584 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003585 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003586 "xmlTextWriterStartDTDElement : out of memory!\n");
3587 return -1;
3588 }
3589
3590 p->name = xmlStrdup(name);
3591 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003592 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003593 "xmlTextWriterStartDTDElement : out of memory!\n");
3594 xmlFree(p);
3595 return -1;
3596 }
Daniel Veillard500a1de2004-03-22 15:22:58 +00003597
3598 if (pe != 0)
3599 p->state = XML_TEXTWRITER_DTD_PENT;
3600 else
3601 p->state = XML_TEXTWRITER_DTD_ENTY;
Daniel Veillard1d211e22003-10-20 22:32:39 +00003602
3603 xmlListPushFront(writer->nodes, p);
3604
Daniel Veillard500a1de2004-03-22 15:22:58 +00003605 if (writer->indent) {
3606 count = xmlTextWriterWriteIndent(writer);
3607 if (count < 0)
3608 return -1;
3609 sum += count;
3610 }
3611
Daniel Veillard1d211e22003-10-20 22:32:39 +00003612 count = xmlOutputBufferWriteString(writer->out, "<!ENTITY ");
3613 if (count < 0)
3614 return -1;
3615 sum += count;
3616
3617 if (pe != 0) {
Daniel Veillard500a1de2004-03-22 15:22:58 +00003618 count = xmlOutputBufferWriteString(writer->out, "% ");
Daniel Veillard1d211e22003-10-20 22:32:39 +00003619 if (count < 0)
3620 return -1;
3621 sum += count;
3622 }
3623
Daniel Veillardab69f362004-02-17 11:40:32 +00003624 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003625 if (count < 0)
3626 return -1;
3627 sum += count;
3628
3629 return sum;
3630}
3631
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003632/**
Daniel Veillard500a1de2004-03-22 15:22:58 +00003633 * xmlTextWriterEndDTDEntity:
3634 * @writer: the xmlTextWriterPtr
3635 *
3636 * End an xml DTD entity.
3637 *
3638 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3639 */
3640int
3641xmlTextWriterEndDTDEntity(xmlTextWriterPtr writer)
3642{
3643 int count;
3644 int sum;
3645 xmlLinkPtr lk;
3646 xmlTextWriterStackEntry *p;
3647
3648 if (writer == NULL)
3649 return -1;
3650
3651 sum = 0;
3652 lk = xmlListFront(writer->nodes);
3653 if (lk == 0)
3654 return -1;
3655
3656 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3657 if (p == 0)
3658 return -1;
3659
3660 switch (p->state) {
3661 case XML_TEXTWRITER_DTD_ENTY_TEXT:
3662 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3663 if (count < 0)
3664 return -1;
3665 sum += count;
3666 case XML_TEXTWRITER_DTD_ENTY:
3667 case XML_TEXTWRITER_DTD_PENT:
Daniel Veillard500a1de2004-03-22 15:22:58 +00003668 count = xmlOutputBufferWriteString(writer->out, ">");
3669 if (count < 0)
3670 return -1;
3671 sum += count;
3672 break;
3673 default:
3674 return -1;
3675 }
3676
3677 if (writer->indent) {
3678 count = xmlOutputBufferWriteString(writer->out, "\n");
3679 if (count < 0)
3680 return -1;
3681 sum += count;
3682 }
3683
3684 xmlListPopFront(writer->nodes);
3685 return sum;
3686}
3687
3688/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003689 * xmlTextWriterWriteFormatDTDInternalEntity:
3690 * @writer: the xmlTextWriterPtr
3691 * @pe: TRUE if this is a parameter entity, FALSE if not
3692 * @name: the name of the DTD entity
3693 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003694 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003695 *
3696 * Write a formatted DTD internal entity.
3697 *
3698 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3699 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00003700int XMLCDECL
Daniel Veillard1d211e22003-10-20 22:32:39 +00003701xmlTextWriterWriteFormatDTDInternalEntity(xmlTextWriterPtr writer,
3702 int pe,
3703 const xmlChar * name,
3704 const char *format, ...)
3705{
3706 int rc;
3707 va_list ap;
3708
3709 va_start(ap, format);
3710
3711 rc = xmlTextWriterWriteVFormatDTDInternalEntity(writer, pe, name,
3712 format, ap);
3713
3714 va_end(ap);
3715 return rc;
3716}
3717
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003718/**
3719 * xmlTextWriterWriteVFormatDTDInternalEntity:
3720 * @writer: the xmlTextWriterPtr
3721 * @pe: TRUE if this is a parameter entity, FALSE if not
3722 * @name: the name of the DTD entity
3723 * @format: format string (see printf)
3724 * @argptr: pointer to the first member of the variable argument list.
3725 *
3726 * Write a formatted DTD internal entity.
3727 *
3728 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3729 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003730int
3731xmlTextWriterWriteVFormatDTDInternalEntity(xmlTextWriterPtr writer,
3732 int pe,
3733 const xmlChar * name,
3734 const char *format,
3735 va_list argptr)
3736{
3737 int rc;
3738 xmlChar *buf;
3739
3740 if (writer == NULL)
3741 return -1;
3742
3743 buf = xmlTextWriterVSprintf(format, argptr);
3744 if (buf == 0)
3745 return 0;
3746
3747 rc = xmlTextWriterWriteDTDInternalEntity(writer, pe, name, buf);
3748
3749 xmlFree(buf);
3750 return rc;
3751}
3752
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003753/**
3754 * xmlTextWriterWriteDTDEntity:
3755 * @writer: the xmlTextWriterPtr
3756 * @pe: TRUE if this is a parameter entity, FALSE if not
3757 * @name: the name of the DTD entity
3758 * @pubid: the public identifier, which is an alternative to the system identifier
3759 * @sysid: the system identifier, which is the URI of the DTD
3760 * @ndataid: the xml notation name.
3761 * @content: content of the entity
3762 *
3763 * Write a DTD entity.
3764 *
3765 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3766 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003767int
3768xmlTextWriterWriteDTDEntity(xmlTextWriterPtr writer,
3769 int pe,
3770 const xmlChar * name,
3771 const xmlChar * pubid,
3772 const xmlChar * sysid,
3773 const xmlChar * ndataid,
3774 const xmlChar * content)
3775{
Daniel Veillard500a1de2004-03-22 15:22:58 +00003776 if ((content == NULL) && (pubid == NULL) && (sysid == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00003777 return -1;
3778 if ((pe != 0) && (ndataid != NULL))
3779 return -1;
3780
Daniel Veillard500a1de2004-03-22 15:22:58 +00003781 if ((pubid == NULL) && (sysid == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00003782 return xmlTextWriterWriteDTDInternalEntity(writer, pe, name,
3783 content);
3784
3785 return xmlTextWriterWriteDTDExternalEntity(writer, pe, name, pubid,
3786 sysid, ndataid);
3787}
3788
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003789/**
3790 * xmlTextWriterWriteDTDInternalEntity:
3791 * @writer: the xmlTextWriterPtr
3792 * @pe: TRUE if this is a parameter entity, FALSE if not
3793 * @name: the name of the DTD entity
3794 * @content: content of the entity
3795 *
3796 * Write a DTD internal entity.
3797 *
3798 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3799 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003800int
3801xmlTextWriterWriteDTDInternalEntity(xmlTextWriterPtr writer,
3802 int pe,
3803 const xmlChar * name,
3804 const xmlChar * content)
3805{
3806 int count;
3807 int sum;
3808
3809 if ((name == NULL) || (*name == '\0') || (content == NULL))
3810 return -1;
3811
3812 sum = 0;
3813 count = xmlTextWriterStartDTDEntity(writer, pe, name);
3814 if (count == -1)
3815 return -1;
3816 sum += count;
3817
Daniel Veillard1d211e22003-10-20 22:32:39 +00003818 count = xmlTextWriterWriteString(writer, content);
3819 if (count == -1)
3820 return -1;
3821 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00003822
3823 count = xmlTextWriterEndDTDEntity(writer);
3824 if (count == -1)
3825 return -1;
3826 sum += count;
3827
3828 return sum;
3829}
3830
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003831/**
3832 * xmlTextWriterWriteDTDExternalEntity:
3833 * @writer: the xmlTextWriterPtr
3834 * @pe: TRUE if this is a parameter entity, FALSE if not
3835 * @name: the name of the DTD entity
3836 * @pubid: the public identifier, which is an alternative to the system identifier
3837 * @sysid: the system identifier, which is the URI of the DTD
3838 * @ndataid: the xml notation name.
3839 *
Daniel Veillard500a1de2004-03-22 15:22:58 +00003840 * Write a DTD external entity. The entity must have been started with xmlTextWriterStartDTDEntity
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003841 *
3842 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3843 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003844int
3845xmlTextWriterWriteDTDExternalEntity(xmlTextWriterPtr writer,
3846 int pe,
3847 const xmlChar * name,
3848 const xmlChar * pubid,
3849 const xmlChar * sysid,
3850 const xmlChar * ndataid)
3851{
3852 int count;
3853 int sum;
3854
Daniel Veillard500a1de2004-03-22 15:22:58 +00003855 if (((pubid == NULL) && (sysid == NULL)))
Daniel Veillard1d211e22003-10-20 22:32:39 +00003856 return -1;
3857 if ((pe != 0) && (ndataid != NULL))
3858 return -1;
3859
3860 sum = 0;
3861 count = xmlTextWriterStartDTDEntity(writer, pe, name);
3862 if (count == -1)
3863 return -1;
3864 sum += count;
3865
Daniel Veillard500a1de2004-03-22 15:22:58 +00003866 count =
3867 xmlTextWriterWriteDTDExternalEntityContents(writer, pubid, sysid,
3868 ndataid);
3869 if (count < 0)
3870 return -1;
3871 sum += count;
3872
3873 count = xmlTextWriterEndDTDEntity(writer);
3874 if (count == -1)
3875 return -1;
3876 sum += count;
3877
3878 return sum;
3879}
3880
3881/**
3882 * xmlTextWriterWriteDTDExternalEntityContents:
3883 * @writer: the xmlTextWriterPtr
3884 * @pubid: the public identifier, which is an alternative to the system identifier
3885 * @sysid: the system identifier, which is the URI of the DTD
3886 * @ndataid: the xml notation name.
3887 *
3888 * Write the contents of a DTD external entity.
3889 *
3890 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3891 */
3892int
3893xmlTextWriterWriteDTDExternalEntityContents(xmlTextWriterPtr writer,
3894 const xmlChar * pubid,
3895 const xmlChar * sysid,
3896 const xmlChar * ndataid)
3897{
3898 int count;
3899 int sum;
3900 xmlLinkPtr lk;
3901 xmlTextWriterStackEntry *p;
3902
3903 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003904 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003905 "xmlTextWriterWriteDTDExternalEntityContents: xmlTextWriterPtr invalid!\n");
3906 return -1;
3907 }
3908
3909 sum = 0;
3910 lk = xmlListFront(writer->nodes);
3911 if (lk == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003912 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003913 "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n");
3914 return -1;
3915 }
3916
3917 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3918 if (p == 0)
3919 return -1;
3920
3921 switch (p->state) {
3922 case XML_TEXTWRITER_DTD_ENTY:
3923 break;
3924 case XML_TEXTWRITER_DTD_PENT:
3925 if (ndataid != NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003926 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003927 "xmlTextWriterWriteDTDExternalEntityContents: notation not allowed with parameter entities!\n");
3928 return -1;
3929 }
3930 break;
3931 default:
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003932 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003933 "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n");
3934 return -1;
3935 }
3936
Daniel Veillard1d211e22003-10-20 22:32:39 +00003937 if (pubid != 0) {
3938 if (sysid == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003939 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003940 "xmlTextWriterWriteDTDExternalEntityContents: system identifier needed!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +00003941 return -1;
3942 }
3943
3944 count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
3945 if (count < 0)
3946 return -1;
3947 sum += count;
3948
3949 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3950 if (count < 0)
3951 return -1;
3952 sum += count;
3953
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003954 count =
3955 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003956 if (count < 0)
3957 return -1;
3958 sum += count;
3959
3960 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3961 if (count < 0)
3962 return -1;
3963 sum += count;
3964 }
3965
3966 if (sysid != 0) {
3967 if (pubid == 0) {
3968 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
3969 if (count < 0)
3970 return -1;
3971 sum += count;
3972 }
3973
3974 count = xmlOutputBufferWriteString(writer->out, " ");
3975 if (count < 0)
3976 return -1;
3977 sum += count;
3978
3979 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3980 if (count < 0)
3981 return -1;
3982 sum += count;
3983
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003984 count =
3985 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003986 if (count < 0)
3987 return -1;
3988 sum += count;
3989
3990 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3991 if (count < 0)
3992 return -1;
3993 sum += count;
3994 }
3995
3996 if (ndataid != NULL) {
3997 count = xmlOutputBufferWriteString(writer->out, " NDATA ");
3998 if (count < 0)
3999 return -1;
4000 sum += count;
4001
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004002 count =
4003 xmlOutputBufferWriteString(writer->out,
4004 (const char *) ndataid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004005 if (count < 0)
4006 return -1;
4007 sum += count;
4008 }
4009
Daniel Veillard1d211e22003-10-20 22:32:39 +00004010 return sum;
4011}
4012
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004013/**
4014 * xmlTextWriterWriteDTDNotation:
4015 * @writer: the xmlTextWriterPtr
4016 * @name: the name of the xml notation
4017 * @pubid: the public identifier, which is an alternative to the system identifier
4018 * @sysid: the system identifier, which is the URI of the DTD
4019 *
4020 * Write a DTD entity.
4021 *
4022 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
4023 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00004024int
4025xmlTextWriterWriteDTDNotation(xmlTextWriterPtr writer,
4026 const xmlChar * name,
4027 const xmlChar * pubid, const xmlChar * sysid)
4028{
4029 int count;
4030 int sum;
4031 xmlLinkPtr lk;
4032 xmlTextWriterStackEntry *p;
4033
4034 if (writer == NULL || name == NULL || *name == '\0')
4035 return -1;
4036
4037 sum = 0;
4038 lk = xmlListFront(writer->nodes);
4039 if (lk == 0) {
4040 return -1;
4041 }
4042
4043 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
Daniel Veillard500a1de2004-03-22 15:22:58 +00004044 if (p != 0) {
4045 switch (p->state) {
4046 case XML_TEXTWRITER_DTD:
4047 count = xmlOutputBufferWriteString(writer->out, " [");
4048 if (count < 0)
4049 return -1;
4050 sum += count;
4051 if (writer->indent) {
4052 count = xmlOutputBufferWriteString(writer->out, "\n");
4053 if (count < 0)
4054 return -1;
4055 sum += count;
4056 }
4057 p->state = XML_TEXTWRITER_DTD_TEXT;
4058 /* fallthrough */
4059 case XML_TEXTWRITER_DTD_TEXT:
4060 break;
4061 default:
4062 return -1;
4063 }
4064 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00004065
Daniel Veillard500a1de2004-03-22 15:22:58 +00004066 if (writer->indent) {
4067 count = xmlTextWriterWriteIndent(writer);
4068 if (count < 0)
Daniel Veillard1d211e22003-10-20 22:32:39 +00004069 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00004070 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00004071 }
4072
4073 count = xmlOutputBufferWriteString(writer->out, "<!NOTATION ");
4074 if (count < 0)
4075 return -1;
4076 sum += count;
4077 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
4078 if (count < 0)
4079 return -1;
4080 sum += count;
4081
4082 if (pubid != 0) {
4083 count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
4084 if (count < 0)
4085 return -1;
4086 sum += count;
4087 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4088 if (count < 0)
4089 return -1;
4090 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004091 count =
4092 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004093 if (count < 0)
4094 return -1;
4095 sum += count;
4096 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4097 if (count < 0)
4098 return -1;
4099 sum += count;
4100 }
4101
4102 if (sysid != 0) {
4103 if (pubid == 0) {
4104 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
4105 if (count < 0)
4106 return -1;
4107 sum += count;
4108 }
4109 count = xmlOutputBufferWriteString(writer->out, " ");
4110 if (count < 0)
4111 return -1;
4112 sum += count;
4113 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4114 if (count < 0)
4115 return -1;
4116 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004117 count =
4118 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004119 if (count < 0)
4120 return -1;
4121 sum += count;
4122 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4123 if (count < 0)
4124 return -1;
4125 sum += count;
4126 }
4127
4128 count = xmlOutputBufferWriteString(writer->out, ">");
4129 if (count < 0)
4130 return -1;
4131 sum += count;
4132
4133 return sum;
4134}
4135
4136/**
4137 * xmlTextWriterFlush:
4138 * @writer: the xmlTextWriterPtr
4139 *
4140 * Flush the output buffer.
4141 *
4142 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
4143 */
4144int
4145xmlTextWriterFlush(xmlTextWriterPtr writer)
4146{
4147 int count;
4148
4149 if (writer == NULL)
4150 return -1;
4151
4152 if (writer->out == NULL)
4153 count = 0;
4154 else
4155 count = xmlOutputBufferFlush(writer->out);
4156
4157 return count;
4158}
4159
4160/**
4161 * misc
4162 */
4163
4164/**
4165 * xmlFreeTextWriterStackEntry:
4166 * @lk: the xmlLinkPtr
4167 *
4168 * Free callback for the xmlList.
4169 */
4170static void
4171xmlFreeTextWriterStackEntry(xmlLinkPtr lk)
4172{
4173 xmlTextWriterStackEntry *p;
4174
4175 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
4176 if (p == 0)
4177 return;
4178
4179 if (p->name != 0)
4180 xmlFree(p->name);
4181 xmlFree(p);
4182}
4183
4184/**
4185 * xmlCmpTextWriterStackEntry:
4186 * @data0: the first data
4187 * @data1: the second data
4188 *
4189 * Compare callback for the xmlList.
4190 *
4191 * Returns -1, 0, 1
4192 */
4193static int
4194xmlCmpTextWriterStackEntry(const void *data0, const void *data1)
4195{
4196 xmlTextWriterStackEntry *p0;
4197 xmlTextWriterStackEntry *p1;
4198
4199 if (data0 == data1)
4200 return 0;
4201
4202 if (data0 == 0)
4203 return -1;
4204
4205 if (data1 == 0)
4206 return 1;
4207
4208 p0 = (xmlTextWriterStackEntry *) data0;
4209 p1 = (xmlTextWriterStackEntry *) data1;
4210
4211 return xmlStrcmp(p0->name, p1->name);
4212}
4213
4214/**
4215 * misc
4216 */
4217
4218/**
4219 * xmlFreeTextWriterNsStackEntry:
4220 * @lk: the xmlLinkPtr
4221 *
4222 * Free callback for the xmlList.
4223 */
4224static void
4225xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk)
4226{
4227 xmlTextWriterNsStackEntry *p;
4228
4229 p = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
4230 if (p == 0)
4231 return;
4232
4233 if (p->prefix != 0)
4234 xmlFree(p->prefix);
4235 if (p->uri != 0)
4236 xmlFree(p->uri);
4237
4238 xmlFree(p);
4239}
4240
4241/**
4242 * xmlCmpTextWriterNsStackEntry:
4243 * @data0: the first data
4244 * @data1: the second data
4245 *
4246 * Compare callback for the xmlList.
4247 *
4248 * Returns -1, 0, 1
4249 */
4250static int
4251xmlCmpTextWriterNsStackEntry(const void *data0, const void *data1)
4252{
4253 xmlTextWriterNsStackEntry *p0;
4254 xmlTextWriterNsStackEntry *p1;
4255 int rc;
4256
4257 if (data0 == data1)
4258 return 0;
4259
4260 if (data0 == 0)
4261 return -1;
4262
4263 if (data1 == 0)
4264 return 1;
4265
4266 p0 = (xmlTextWriterNsStackEntry *) data0;
4267 p1 = (xmlTextWriterNsStackEntry *) data1;
4268
4269 rc = xmlStrcmp(p0->prefix, p1->prefix);
4270
4271 if (rc == 0)
4272 rc = p0->elem == p1->elem;
4273
4274 return rc;
4275}
4276
4277/**
4278 * xmlTextWriterWriteMemCallback:
4279 * @context: the xmlBufferPtr
4280 * @str: the data to write
4281 * @len: the length of the data
4282 *
4283 * Write callback for the xmlOutputBuffer with target xmlBuffer
4284 *
4285 * Returns -1, 0, 1
4286 */
4287static int
4288xmlTextWriterWriteMemCallback(void *context, const xmlChar * str, int len)
4289{
4290 xmlBufferPtr buf = (xmlBufferPtr) context;
4291
4292 xmlBufferAdd(buf, str, len);
4293
4294 return len;
4295}
4296
4297/**
4298 * xmlTextWriterCloseMemCallback:
4299 * @context: the xmlBufferPtr
4300 *
4301 * Close callback for the xmlOutputBuffer with target xmlBuffer
4302 *
4303 * Returns -1, 0, 1
4304 */
4305static int
4306xmlTextWriterCloseMemCallback(void *context ATTRIBUTE_UNUSED)
4307{
4308 return 0;
4309}
4310
4311/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004312 * xmlTextWriterWriteDocCallback:
4313 * @context: the xmlBufferPtr
4314 * @str: the data to write
4315 * @len: the length of the data
4316 *
4317 * Write callback for the xmlOutputBuffer with target xmlBuffer
4318 *
4319 * Returns -1, 0, 1
4320 */
4321static int
4322xmlTextWriterWriteDocCallback(void *context, const xmlChar * str, int len)
4323{
4324 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context;
4325 int rc;
4326
Daniel Veillard1d913862003-11-21 00:28:39 +00004327 if ((rc = xmlParseChunk(ctxt, (const char *) str, len, 0)) != 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004328 xmlWriterErrMsgInt(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004329 "xmlTextWriterWriteDocCallback : XML error %d !\n",
4330 rc);
4331 return -1;
4332 }
4333
4334 return len;
4335}
4336
4337/**
4338 * xmlTextWriterCloseDocCallback:
4339 * @context: the xmlBufferPtr
4340 *
4341 * Close callback for the xmlOutputBuffer with target xmlBuffer
4342 *
4343 * Returns -1, 0, 1
4344 */
4345static int
4346xmlTextWriterCloseDocCallback(void *context)
4347{
4348 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context;
4349 int rc;
4350
4351 if ((rc = xmlParseChunk(ctxt, NULL, 0, 1)) != 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004352 xmlWriterErrMsgInt(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004353 "xmlTextWriterWriteDocCallback : XML error %d !\n",
4354 rc);
4355 return -1;
4356 }
4357
4358 return 0;
4359}
4360
4361/**
Daniel Veillard1d211e22003-10-20 22:32:39 +00004362 * xmlTextWriterVSprintf:
4363 * @format: see printf
4364 * @argptr: pointer to the first member of the variable argument list.
4365 *
4366 * Utility function for formatted output
4367 *
4368 * Returns a new xmlChar buffer with the data or NULL on error. This buffer must be freed.
4369 */
4370static xmlChar *
4371xmlTextWriterVSprintf(const char *format, va_list argptr)
4372{
4373 int size;
4374 int count;
4375 xmlChar *buf;
4376
4377 size = BUFSIZ;
4378 buf = (xmlChar *) xmlMalloc(size);
4379 if (buf == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004380 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00004381 "xmlTextWriterVSprintf : out of memory!\n");
4382 return NULL;
4383 }
4384
4385 while (((count = vsnprintf((char *) buf, size, format, argptr)) < 0)
4386 || (count == size - 1) || (count == size) || (count > size)) {
4387 xmlFree(buf);
4388 size += BUFSIZ;
4389 buf = (xmlChar *) xmlMalloc(size);
4390 if (buf == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004391 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00004392 "xmlTextWriterVSprintf : out of memory!\n");
4393 return NULL;
4394 }
4395 }
4396
4397 return buf;
4398}
4399
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004400/**
4401 * xmlTextWriterStartDocumentCallback:
4402 * @ctx: the user data (XML parser context)
4403 *
4404 * called at the start of document processing.
4405 */
4406static void
4407xmlTextWriterStartDocumentCallback(void *ctx)
4408{
4409 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
4410 xmlDocPtr doc;
4411
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004412 if (ctxt->html) {
4413#ifdef LIBXML_HTML_ENABLED
4414 if (ctxt->myDoc == NULL)
4415 ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
4416 if (ctxt->myDoc == NULL) {
4417 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
4418 ctxt->sax->error(ctxt->userData,
4419 "SAX.startDocument(): out of memory\n");
4420 ctxt->errNo = XML_ERR_NO_MEMORY;
4421 ctxt->instate = XML_PARSER_EOF;
4422 ctxt->disableSAX = 1;
4423 return;
4424 }
4425#else
Daniel Veillardd0cf7f62004-11-09 16:17:02 +00004426 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004427 "libxml2 built without HTML support\n");
4428 ctxt->errNo = XML_ERR_INTERNAL_ERROR;
4429 ctxt->instate = XML_PARSER_EOF;
4430 ctxt->disableSAX = 1;
4431 return;
4432#endif
4433 } else {
4434 doc = ctxt->myDoc;
4435 if (doc == NULL)
4436 doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
4437 if (doc != NULL) {
4438 if (doc->children == NULL) {
4439 if (ctxt->encoding != NULL)
4440 doc->encoding = xmlStrdup(ctxt->encoding);
4441 else
4442 doc->encoding = NULL;
4443 doc->standalone = ctxt->standalone;
4444 }
4445 } else {
4446 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
4447 ctxt->sax->error(ctxt->userData,
4448 "SAX.startDocument(): out of memory\n");
4449 ctxt->errNo = XML_ERR_NO_MEMORY;
4450 ctxt->instate = XML_PARSER_EOF;
4451 ctxt->disableSAX = 1;
4452 return;
4453 }
4454 }
4455 if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) &&
4456 (ctxt->input != NULL) && (ctxt->input->filename != NULL)) {
4457 ctxt->myDoc->URL =
4458 xmlCanonicPath((const xmlChar *) ctxt->input->filename);
4459 if (ctxt->myDoc->URL == NULL)
4460 ctxt->myDoc->URL =
4461 xmlStrdup((const xmlChar *) ctxt->input->filename);
4462 }
4463}
4464
Daniel Veillard2cca4462004-01-02 20:04:23 +00004465/**
4466 * xmlTextWriterSetIndent:
4467 * @writer: the xmlTextWriterPtr
4468 * @indent: do indentation?
4469 *
4470 * Set indentation output. indent = 0 do not indentation. indent > 0 do indentation.
4471 *
4472 * Returns -1 on error or 0 otherwise.
4473 */
4474int
Daniel Veillardab69f362004-02-17 11:40:32 +00004475xmlTextWriterSetIndent(xmlTextWriterPtr writer, int indent)
Daniel Veillard2cca4462004-01-02 20:04:23 +00004476{
Daniel Veillarde43cc572004-11-03 11:50:29 +00004477 if ((writer == NULL) || (indent < 0))
Daniel Veillardab69f362004-02-17 11:40:32 +00004478 return -1;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004479
Daniel Veillardab69f362004-02-17 11:40:32 +00004480 writer->indent = indent;
4481 writer->doindent = 1;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004482
Daniel Veillardab69f362004-02-17 11:40:32 +00004483 return 0;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004484}
4485
4486/**
4487 * xmlTextWriterSetIndentString:
4488 * @writer: the xmlTextWriterPtr
4489 * @str: the xmlChar string
4490 *
4491 * Set string indentation.
4492 *
4493 * Returns -1 on error or 0 otherwise.
4494 */
4495int
Daniel Veillardab69f362004-02-17 11:40:32 +00004496xmlTextWriterSetIndentString(xmlTextWriterPtr writer, const xmlChar * str)
Daniel Veillard2cca4462004-01-02 20:04:23 +00004497{
Daniel Veillarde43cc572004-11-03 11:50:29 +00004498 if ((writer == NULL) || (!str))
Daniel Veillardab69f362004-02-17 11:40:32 +00004499 return -1;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004500
Daniel Veillardab69f362004-02-17 11:40:32 +00004501 if (writer->ichar != NULL)
4502 xmlFree(writer->ichar);
4503 writer->ichar = xmlStrdup(str);
4504
4505 if (!writer->ichar)
4506 return -1;
4507 else
4508 return 0;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004509}
4510
4511/**
4512 * xmlTextWriterWriteIndent:
4513 * @writer: the xmlTextWriterPtr
4514 *
4515 * Write indent string.
4516 *
4517 * Returns -1 on error or the number of strings written.
Daniel Veillardab69f362004-02-17 11:40:32 +00004518 */
Daniel Veillard2cca4462004-01-02 20:04:23 +00004519static int
Daniel Veillardab69f362004-02-17 11:40:32 +00004520xmlTextWriterWriteIndent(xmlTextWriterPtr writer)
Daniel Veillard2cca4462004-01-02 20:04:23 +00004521{
Daniel Veillardab69f362004-02-17 11:40:32 +00004522 int lksize;
4523 int i;
4524 int ret;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004525
Daniel Veillardab69f362004-02-17 11:40:32 +00004526 lksize = xmlListSize(writer->nodes);
4527 if (lksize < 1)
4528 return (-1); /* list is empty */
4529 for (i = 0; i < (lksize - 1); i++) {
4530 ret = xmlOutputBufferWriteString(writer->out,
4531 (const char *) writer->ichar);
4532 if (ret == -1)
4533 return (-1);
4534 }
4535
4536 return (lksize - 1);
Daniel Veillard2cca4462004-01-02 20:04:23 +00004537}
4538
Daniel Veillard500a1de2004-03-22 15:22:58 +00004539/**
4540 * xmlTextWriterHandleStateDependencies:
4541 * @writer: the xmlTextWriterPtr
4542 * @p: the xmlTextWriterStackEntry
4543 *
4544 * Write state dependent strings.
4545 *
4546 * Returns -1 on error or the number of characters written.
4547 */
4548static int
4549xmlTextWriterHandleStateDependencies(xmlTextWriterPtr writer,
4550 xmlTextWriterStackEntry * p)
4551{
4552 int count;
4553 int sum;
4554 char extra[3];
4555
4556 if (writer == NULL)
4557 return -1;
4558
4559 if (p == NULL)
4560 return 0;
4561
4562 sum = 0;
4563 extra[0] = extra[1] = extra[2] = '\0';
4564 if (p != 0) {
4565 sum = 0;
4566 switch (p->state) {
4567 case XML_TEXTWRITER_NAME:
4568 extra[0] = '>';
4569 p->state = XML_TEXTWRITER_TEXT;
4570 break;
4571 case XML_TEXTWRITER_PI:
4572 extra[0] = ' ';
4573 p->state = XML_TEXTWRITER_PI_TEXT;
4574 break;
4575 case XML_TEXTWRITER_DTD:
4576 extra[0] = ' ';
4577 extra[1] = '[';
4578 p->state = XML_TEXTWRITER_DTD_TEXT;
4579 break;
4580 case XML_TEXTWRITER_DTD_ELEM:
4581 extra[0] = ' ';
4582 p->state = XML_TEXTWRITER_DTD_ELEM_TEXT;
4583 break;
4584 case XML_TEXTWRITER_DTD_ATTL:
4585 extra[0] = ' ';
4586 p->state = XML_TEXTWRITER_DTD_ATTL_TEXT;
4587 break;
4588 case XML_TEXTWRITER_DTD_ENTY:
4589 case XML_TEXTWRITER_DTD_PENT:
4590 extra[0] = ' ';
4591 extra[1] = writer->qchar;
4592 p->state = XML_TEXTWRITER_DTD_ENTY_TEXT;
4593 break;
4594 default:
4595 break;
4596 }
4597 }
4598
4599 if (*extra != '\0') {
4600 count = xmlOutputBufferWriteString(writer->out, extra);
4601 if (count < 0)
4602 return -1;
4603 sum += count;
4604 }
4605
4606 return sum;
4607}
4608
Daniel Veillard5d4644e2005-04-01 13:11:58 +00004609#define bottom_xmlwriter
4610#include "elfgcchack.h"
Daniel Veillard1d211e22003-10-20 22:32:39 +00004611#endif