blob: 3255c674a0d022fcb10ca25a0426a8ec348fc058 [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 */
828int
829xmlTextWriterWriteFormatComment(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;
939 case XML_TEXTWRITER_NAME:
940 count = xmlOutputBufferWriteString(writer->out, ">");
941 if (count < 0)
942 return -1;
943 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +0000944 if (writer->indent)
945 count =
946 xmlOutputBufferWriteString(writer->out, "\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000947 p->state = XML_TEXTWRITER_TEXT;
948 break;
Daniel Veillardab69f362004-02-17 11:40:32 +0000949 default:
950 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000951 }
952 }
953 }
954
955 p = (xmlTextWriterStackEntry *)
956 xmlMalloc(sizeof(xmlTextWriterStackEntry));
957 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000958 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000959 "xmlTextWriterStartElement : out of memory!\n");
960 return -1;
961 }
962
963 p->name = xmlStrdup(name);
964 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000965 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000966 "xmlTextWriterStartElement : out of memory!\n");
967 xmlFree(p);
968 return -1;
969 }
970 p->state = XML_TEXTWRITER_NAME;
971
972 xmlListPushFront(writer->nodes, p);
973
Daniel Veillardab69f362004-02-17 11:40:32 +0000974 if (writer->indent) {
975 count = xmlTextWriterWriteIndent(writer);
976 sum += count;
Daniel Veillard2cca4462004-01-02 20:04:23 +0000977 }
978
Daniel Veillard1d211e22003-10-20 22:32:39 +0000979 count = xmlOutputBufferWriteString(writer->out, "<");
980 if (count < 0)
981 return -1;
982 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000983 count =
984 xmlOutputBufferWriteString(writer->out, (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000985 if (count < 0)
986 return -1;
987 sum += count;
988
989 return sum;
990}
991
992/**
993 * xmlTextWriterStartElementNS:
994 * @writer: the xmlTextWriterPtr
995 * @prefix: namespace prefix or NULL
996 * @name: element local name
997 * @namespaceURI: namespace URI or NULL
998 *
999 * Start an xml element with namespace support.
1000 *
1001 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1002 */
1003int
1004xmlTextWriterStartElementNS(xmlTextWriterPtr writer,
1005 const xmlChar * prefix, const xmlChar * name,
1006 const xmlChar * namespaceURI)
1007{
1008 int count;
1009 int sum;
1010 xmlChar *buf;
1011
1012 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1013 return -1;
1014
1015 buf = 0;
1016 if (prefix != 0) {
1017 buf = xmlStrdup(prefix);
1018 buf = xmlStrcat(buf, BAD_CAST ":");
1019 }
1020 buf = xmlStrcat(buf, name);
1021
1022 sum = 0;
1023 count = xmlTextWriterStartElement(writer, buf);
1024 xmlFree(buf);
1025 if (count < 0)
1026 return -1;
1027 sum += count;
1028
1029 if (namespaceURI != 0) {
1030 buf = xmlStrdup(BAD_CAST "xmlns");
1031 if (prefix != 0) {
1032 buf = xmlStrcat(buf, BAD_CAST ":");
1033 buf = xmlStrcat(buf, prefix);
1034 }
1035
1036 count = xmlTextWriterWriteAttribute(writer, buf, namespaceURI);
1037 xmlFree(buf);
1038 if (count < 0)
1039 return -1;
1040 sum += count;
1041 }
1042
1043 return sum;
1044}
1045
1046/**
1047 * xmlTextWriterEndElement:
1048 * @writer: the xmlTextWriterPtr
1049 *
1050 * End the current xml element.
1051 *
1052 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1053 */
1054int
1055xmlTextWriterEndElement(xmlTextWriterPtr writer)
1056{
1057 int count;
1058 int sum;
1059 xmlLinkPtr lk;
1060 xmlTextWriterStackEntry *p;
1061
1062 if (writer == NULL)
1063 return -1;
1064
1065 lk = xmlListFront(writer->nodes);
1066 if (lk == 0)
1067 return -1;
1068
1069 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1070 if (p == 0)
1071 return -1;
1072
1073 sum = 0;
1074 switch (p->state) {
1075 case XML_TEXTWRITER_ATTRIBUTE:
1076 count = xmlTextWriterEndAttribute(writer);
1077 if (count < 0)
1078 return -1;
1079 sum += count;
1080 /* fallthrough */
1081 case XML_TEXTWRITER_NAME:
Daniel Veillardab69f362004-02-17 11:40:32 +00001082 if (writer->indent) /* next element needs indent */
1083 writer->doindent = 1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001084 count = xmlOutputBufferWriteString(writer->out, "/>");
1085 if (count < 0)
1086 return -1;
1087 sum += count;
1088 break;
1089 case XML_TEXTWRITER_TEXT:
Daniel Veillardab69f362004-02-17 11:40:32 +00001090 if ((writer->indent) && (writer->doindent)) {
1091 count = xmlTextWriterWriteIndent(writer);
1092 sum += count;
1093 writer->doindent = 1;
1094 } else
1095 writer->doindent = 1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001096 count = xmlOutputBufferWriteString(writer->out, "</");
1097 if (count < 0)
1098 return -1;
1099 sum += count;
1100 count = xmlOutputBufferWriteString(writer->out,
Daniel Veillardab69f362004-02-17 11:40:32 +00001101 (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001102 if (count < 0)
1103 return -1;
1104 sum += count;
1105 count = xmlOutputBufferWriteString(writer->out, ">");
1106 if (count < 0)
1107 return -1;
1108 sum += count;
1109 break;
1110 default:
1111 return -1;
1112 }
1113
Daniel Veillard2cca4462004-01-02 20:04:23 +00001114 if (writer->indent) {
Daniel Veillardab69f362004-02-17 11:40:32 +00001115 count = xmlOutputBufferWriteString(writer->out, "\n");
1116 sum += count;
Daniel Veillard2cca4462004-01-02 20:04:23 +00001117 }
1118
Daniel Veillard1d211e22003-10-20 22:32:39 +00001119 xmlListPopFront(writer->nodes);
1120 return sum;
1121}
1122
1123/**
1124 * xmlTextWriterFullEndElement:
1125 * @writer: the xmlTextWriterPtr
1126 *
1127 * End the current xml element. Writes an end tag even if the element is empty
1128 *
1129 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1130 */
1131int
1132xmlTextWriterFullEndElement(xmlTextWriterPtr writer)
1133{
1134 int count;
1135 int sum;
1136 xmlLinkPtr lk;
1137 xmlTextWriterStackEntry *p;
1138
1139 if (writer == NULL)
1140 return -1;
1141
1142 lk = xmlListFront(writer->nodes);
1143 if (lk == 0)
1144 return -1;
1145
1146 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1147 if (p == 0)
1148 return -1;
1149
1150 sum = 0;
1151 switch (p->state) {
1152 case XML_TEXTWRITER_ATTRIBUTE:
1153 count = xmlTextWriterEndAttribute(writer);
1154 if (count < 0)
1155 return -1;
1156 sum += count;
1157 /* fallthrough */
1158 case XML_TEXTWRITER_NAME:
1159 count = xmlOutputBufferWriteString(writer->out, ">");
1160 if (count < 0)
1161 return -1;
1162 sum += count;
1163 /* fallthrough */
1164 case XML_TEXTWRITER_TEXT:
1165 count = xmlOutputBufferWriteString(writer->out, "</");
1166 if (count < 0)
1167 return -1;
1168 sum += count;
1169 count = xmlOutputBufferWriteString(writer->out,
Daniel Veillardab69f362004-02-17 11:40:32 +00001170 (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001171 if (count < 0)
1172 return -1;
1173 sum += count;
1174 count = xmlOutputBufferWriteString(writer->out, ">");
1175 if (count < 0)
1176 return -1;
1177 sum += count;
1178 break;
1179 default:
1180 return -1;
1181 }
1182
1183 xmlListPopFront(writer->nodes);
1184 return sum;
1185}
1186
1187/**
1188 * xmlTextWriterWriteFormatRaw:
1189 * @writer: the xmlTextWriterPtr
1190 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001191 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001192 *
1193 * Write a formatted raw xml text.
1194 *
1195 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1196 */
1197int
1198xmlTextWriterWriteFormatRaw(xmlTextWriterPtr writer, const char *format,
1199 ...)
1200{
1201 int rc;
1202 va_list ap;
1203
1204 va_start(ap, format);
1205
1206 rc = xmlTextWriterWriteVFormatRaw(writer, format, ap);
1207
1208 va_end(ap);
1209 return rc;
1210}
1211
1212/**
1213 * xmlTextWriterWriteVFormatRaw:
1214 * @writer: the xmlTextWriterPtr
1215 * @format: format string (see printf)
1216 * @argptr: pointer to the first member of the variable argument list.
1217 *
1218 * Write a formatted raw xml text.
1219 *
1220 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1221 */
1222int
1223xmlTextWriterWriteVFormatRaw(xmlTextWriterPtr writer, const char *format,
1224 va_list argptr)
1225{
1226 int rc;
1227 xmlChar *buf;
1228
1229 if (writer == NULL)
1230 return -1;
1231
1232 buf = xmlTextWriterVSprintf(format, argptr);
1233 if (buf == 0)
1234 return 0;
1235
1236 rc = xmlTextWriterWriteRaw(writer, buf);
1237
1238 xmlFree(buf);
1239 return rc;
1240}
1241
1242/**
Daniel Veillard1e906612003-12-05 14:57:46 +00001243 * xmlTextWriterWriteRawLen:
Daniel Veillard1d211e22003-10-20 22:32:39 +00001244 * @writer: the xmlTextWriterPtr
1245 * @content: text string
1246 * @len: length of the text string
1247 *
1248 * Write an xml text.
1249 * TODO: what about entities and special chars??
1250 *
1251 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1252 */
1253int
1254xmlTextWriterWriteRawLen(xmlTextWriterPtr writer, const xmlChar * content,
1255 int len)
1256{
1257 int count;
1258 int sum;
1259 xmlLinkPtr lk;
1260 xmlTextWriterStackEntry *p;
1261
Daniel Veillard500a1de2004-03-22 15:22:58 +00001262 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00001263 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00001264 "xmlTextWriterWriteRawLen : invalid writer!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +00001265 return -1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001266 }
1267
Daniel Veillarde43cc572004-11-03 11:50:29 +00001268 if ((content == NULL) || (len < 0)) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00001269 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00001270 "xmlTextWriterWriteRawLen : invalid content!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +00001271 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001272 }
1273
1274 sum = 0;
1275 lk = xmlListFront(writer->nodes);
1276 if (lk != 0) {
1277 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1278 count = xmlTextWriterHandleStateDependencies(writer, p);
1279 if (count < 0)
1280 return -1;
1281 sum += count;
1282 }
1283
1284 if (writer->indent)
1285 writer->doindent = 0;
1286
1287 if (content != NULL) {
1288 count =
1289 xmlOutputBufferWrite(writer->out, len, (const char *) content);
1290 if (count < 0)
1291 return -1;
1292 sum += count;
1293 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001294
1295 return sum;
1296}
1297
1298/**
1299 * xmlTextWriterWriteRaw:
1300 * @writer: the xmlTextWriterPtr
1301 * @content: text string
1302 *
1303 * Write a raw xml text.
1304 *
1305 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1306 */
1307int
1308xmlTextWriterWriteRaw(xmlTextWriterPtr writer, const xmlChar * content)
1309{
1310 return xmlTextWriterWriteRawLen(writer, content, xmlStrlen(content));
1311}
1312
1313/**
1314 * xmlTextWriterWriteFormatString:
1315 * @writer: the xmlTextWriterPtr
1316 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001317 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001318 *
1319 * Write a formatted xml text.
1320 *
1321 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1322 */
1323int
1324xmlTextWriterWriteFormatString(xmlTextWriterPtr writer, const char *format,
1325 ...)
1326{
1327 int rc;
1328 va_list ap;
1329
Daniel Veillarde43cc572004-11-03 11:50:29 +00001330 if ((writer == NULL) || (format == NULL))
1331 return -1;
1332
Daniel Veillard1d211e22003-10-20 22:32:39 +00001333 va_start(ap, format);
1334
1335 rc = xmlTextWriterWriteVFormatString(writer, format, ap);
1336
1337 va_end(ap);
1338 return rc;
1339}
1340
1341/**
1342 * xmlTextWriterWriteVFormatString:
1343 * @writer: the xmlTextWriterPtr
1344 * @format: format string (see printf)
1345 * @argptr: pointer to the first member of the variable argument list.
1346 *
1347 * Write a formatted xml text.
1348 *
1349 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1350 */
1351int
1352xmlTextWriterWriteVFormatString(xmlTextWriterPtr writer,
1353 const char *format, va_list argptr)
1354{
1355 int rc;
1356 xmlChar *buf;
1357
Daniel Veillarde43cc572004-11-03 11:50:29 +00001358 if ((writer == NULL) || (format == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00001359 return -1;
1360
1361 buf = xmlTextWriterVSprintf(format, argptr);
1362 if (buf == 0)
1363 return 0;
1364
1365 rc = xmlTextWriterWriteString(writer, buf);
1366
1367 xmlFree(buf);
1368 return rc;
1369}
1370
1371/**
1372 * xmlTextWriterWriteString:
1373 * @writer: the xmlTextWriterPtr
1374 * @content: text string
1375 *
1376 * Write an xml text.
1377 *
1378 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1379 */
1380int
1381xmlTextWriterWriteString(xmlTextWriterPtr writer, const xmlChar * content)
1382{
Daniel Veillard500a1de2004-03-22 15:22:58 +00001383 int count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001384 int sum;
1385 xmlLinkPtr lk;
1386 xmlTextWriterStackEntry *p;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001387 xmlChar *buf;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001388
Daniel Veillarde43cc572004-11-03 11:50:29 +00001389 if ((writer == NULL) || (content == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00001390 return -1;
1391
Daniel Veillard1d211e22003-10-20 22:32:39 +00001392 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001393 buf = (xmlChar *) content;
1394 lk = xmlListFront(writer->nodes);
1395 if (lk != 0) {
1396 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1397 if (p != 0) {
1398 switch (p->state) {
1399 case XML_TEXTWRITER_NAME:
1400 case XML_TEXTWRITER_TEXT:
Daniel Veillard62040be2004-05-17 03:17:26 +00001401#if 0
1402 buf = NULL;
1403 xmlOutputBufferWriteEscape(writer->out, content, NULL);
1404#endif
Daniel Veillard500a1de2004-03-22 15:22:58 +00001405 buf = xmlEncodeSpecialChars(NULL, content);
1406 break;
1407 case XML_TEXTWRITER_ATTRIBUTE:
1408 buf = NULL;
1409 xmlAttrSerializeTxtContent(writer->out->buffer, NULL,
1410 NULL, content);
1411 break;
William M. Brack87640d52004-04-17 14:58:15 +00001412 default:
1413 break;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001414 }
1415 }
1416 }
1417
1418 if (buf != NULL) {
1419 count = xmlTextWriterWriteRaw(writer, buf);
1420 if (count < 0)
Daniel Veillard1d211e22003-10-20 22:32:39 +00001421 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001422 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001423
Daniel Veillard500a1de2004-03-22 15:22:58 +00001424 if (buf != content) /* buf was allocated by us, so free it */
1425 xmlFree(buf);
William M. Bracka9c612c2004-02-01 10:04:05 +00001426 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001427
1428 return sum;
1429}
1430
1431/**
1432 * xmlOutputBufferWriteBase64:
1433 * @out: the xmlOutputBufferPtr
1434 * @data: binary data
1435 * @len: the number of bytes to encode
1436 *
1437 * Write base64 encoded data to an xmlOutputBuffer.
1438 * Adapted from John Walker's base64.c (http://www.fourmilab.ch/).
1439 *
1440 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1441 */
1442static int
1443xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len,
1444 const unsigned char *data)
1445{
1446 static unsigned char dtable[64] =
William M. Brack47a31882004-09-11 16:09:09 +00001447 {'A','B','C','D','E','F','G','H','I','J','K','L','M',
1448 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
1449 'a','b','c','d','e','f','g','h','i','j','k','l','m',
1450 'n','o','p','q','r','s','t','u','v','w','x','y','z',
1451 '0','1','2','3','4','5','6','7','8','9','+','/'};
1452
Daniel Veillard1d211e22003-10-20 22:32:39 +00001453 int i;
1454 int linelen;
1455 int count;
1456 int sum;
1457
Daniel Veillarde43cc572004-11-03 11:50:29 +00001458 if ((out == NULL) || (len < 0) || (data == NULL))
1459 return(-1);
1460
Daniel Veillard1d211e22003-10-20 22:32:39 +00001461 linelen = 0;
1462 sum = 0;
1463
1464 i = 0;
1465 while (1) {
1466 unsigned char igroup[3];
1467 unsigned char ogroup[4];
1468 int c;
1469 int n;
1470
1471 igroup[0] = igroup[1] = igroup[2] = 0;
1472 for (n = 0; n < 3 && i < len; n++, i++) {
1473 c = data[i];
1474 igroup[n] = (unsigned char) c;
1475 }
1476
1477 if (n > 0) {
1478 ogroup[0] = dtable[igroup[0] >> 2];
1479 ogroup[1] = dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)];
1480 ogroup[2] =
1481 dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)];
1482 ogroup[3] = dtable[igroup[2] & 0x3F];
1483
1484 if (n < 3) {
1485 ogroup[3] = '=';
1486 if (n < 2) {
1487 ogroup[2] = '=';
1488 }
1489 }
1490
1491 if (linelen >= B64LINELEN) {
1492 count = xmlOutputBufferWrite(out, 2, B64CRLF);
1493 if (count == -1)
1494 return -1;
1495 sum += count;
1496 linelen = 0;
1497 }
1498 count = xmlOutputBufferWrite(out, 4, (const char *) ogroup);
1499 if (count == -1)
1500 return -1;
1501 sum += count;
1502
1503 linelen += 4;
1504 }
Daniel Veillard929714b2003-10-22 12:34:36 +00001505
1506 if (i >= len)
1507 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001508 }
1509
Daniel Veillard1d211e22003-10-20 22:32:39 +00001510 return sum;
1511}
1512
1513/**
1514 * xmlTextWriterWriteBase64:
1515 * @writer: the xmlTextWriterPtr
1516 * @data: binary data
1517 * @start: the position within the data of the first byte to encode
1518 * @len: the number of bytes to encode
1519 *
1520 * Write an base64 encoded xml text.
1521 *
1522 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1523 */
1524int
Daniel Veillardab69f362004-02-17 11:40:32 +00001525xmlTextWriterWriteBase64(xmlTextWriterPtr writer, const char *data,
Daniel Veillard1d211e22003-10-20 22:32:39 +00001526 int start, int len)
1527{
1528 int count;
1529 int sum;
1530 xmlLinkPtr lk;
1531 xmlTextWriterStackEntry *p;
1532
Daniel Veillarde43cc572004-11-03 11:50:29 +00001533 if ((writer == NULL) || (data == NULL) || (start < 0) || (len < 0))
Daniel Veillard1d211e22003-10-20 22:32:39 +00001534 return -1;
1535
Daniel Veillard1d211e22003-10-20 22:32:39 +00001536 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001537 lk = xmlListFront(writer->nodes);
1538 if (lk != 0) {
1539 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1540 if (p != 0) {
1541 count = xmlTextWriterHandleStateDependencies(writer, p);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001542 if (count < 0)
1543 return -1;
1544 sum += count;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001545 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001546 }
1547
Daniel Veillardab69f362004-02-17 11:40:32 +00001548 if (writer->indent)
1549 writer->doindent = 0;
1550
Daniel Veillard1d211e22003-10-20 22:32:39 +00001551 count =
1552 xmlOutputBufferWriteBase64(writer->out, len,
1553 (unsigned char *) data + start);
1554 if (count < 0)
1555 return -1;
1556 sum += count;
1557
1558 return sum;
1559}
1560
1561/**
1562 * xmlOutputBufferWriteBinHex:
1563 * @out: the xmlOutputBufferPtr
1564 * @data: binary data
1565 * @len: the number of bytes to encode
1566 *
1567 * Write hqx encoded data to an xmlOutputBuffer.
1568 * ::todo
1569 *
William M. Brack47a31882004-09-11 16:09:09 +00001570 * Returns the bytes written (may be 0 because of buffering)
1571 * or -1 in case of error
Daniel Veillard1d211e22003-10-20 22:32:39 +00001572 */
1573static int
Daniel Veillardab69f362004-02-17 11:40:32 +00001574xmlOutputBufferWriteBinHex(xmlOutputBufferPtr out,
1575 int len, const unsigned char *data)
Daniel Veillard1d211e22003-10-20 22:32:39 +00001576{
Daniel Veillardab69f362004-02-17 11:40:32 +00001577 int count;
1578 int sum;
William M. Brack47a31882004-09-11 16:09:09 +00001579 static char hex[16] =
1580 {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
Daniel Veillardab69f362004-02-17 11:40:32 +00001581 int i;
1582
Daniel Veillarde43cc572004-11-03 11:50:29 +00001583 if ((out == NULL) || (data == NULL) || (len < 0)) {
Daniel Veillardab69f362004-02-17 11:40:32 +00001584 return -1;
1585 }
1586
1587 sum = 0;
1588 for (i = 0; i < len; i++) {
1589 count =
1590 xmlOutputBufferWrite(out, 1,
1591 (const char *) &hex[data[i] >> 4]);
1592 if (count == -1)
1593 return -1;
1594 sum += count;
1595 count =
1596 xmlOutputBufferWrite(out, 1,
1597 (const char *) &hex[data[i] & 0xF]);
1598 if (count == -1)
1599 return -1;
1600 sum += count;
1601 }
1602
1603 return sum;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001604}
1605
1606/**
1607 * xmlTextWriterWriteBinHex:
1608 * @writer: the xmlTextWriterPtr
1609 * @data: binary data
1610 * @start: the position within the data of the first byte to encode
1611 * @len: the number of bytes to encode
1612 *
1613 * Write a BinHex encoded xml text.
1614 *
1615 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1616 */
1617int
Daniel Veillardab69f362004-02-17 11:40:32 +00001618xmlTextWriterWriteBinHex(xmlTextWriterPtr writer, const char *data,
Daniel Veillard1d211e22003-10-20 22:32:39 +00001619 int start, int len)
1620{
1621 int count;
1622 int sum;
1623 xmlLinkPtr lk;
1624 xmlTextWriterStackEntry *p;
1625
Daniel Veillarde43cc572004-11-03 11:50:29 +00001626 if ((writer == NULL) || (data == NULL) || (start < 0) || (len < 0))
Daniel Veillard1d211e22003-10-20 22:32:39 +00001627 return -1;
1628
Daniel Veillard1d211e22003-10-20 22:32:39 +00001629 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001630 lk = xmlListFront(writer->nodes);
1631 if (lk != 0) {
1632 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1633 if (p != 0) {
1634 count = xmlTextWriterHandleStateDependencies(writer, p);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001635 if (count < 0)
1636 return -1;
1637 sum += count;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001638 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001639 }
1640
Daniel Veillardab69f362004-02-17 11:40:32 +00001641 if (writer->indent)
1642 writer->doindent = 0;
1643
Daniel Veillard1d211e22003-10-20 22:32:39 +00001644 count =
1645 xmlOutputBufferWriteBinHex(writer->out, len,
1646 (unsigned char *) data + start);
1647 if (count < 0)
1648 return -1;
1649 sum += count;
1650
1651 return sum;
1652}
1653
1654/**
1655 * xmlTextWriterStartAttribute:
1656 * @writer: the xmlTextWriterPtr
1657 * @name: element name
1658 *
1659 * Start an xml attribute.
1660 *
1661 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1662 */
1663int
1664xmlTextWriterStartAttribute(xmlTextWriterPtr writer, const xmlChar * name)
1665{
1666 int count;
1667 int sum;
1668 xmlLinkPtr lk;
1669 xmlTextWriterStackEntry *p;
1670
1671 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1672 return -1;
1673
1674 sum = 0;
1675 lk = xmlListFront(writer->nodes);
1676 if (lk == 0)
1677 return -1;
1678
1679 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1680 if (p == 0)
1681 return -1;
1682
1683 switch (p->state) {
1684 case XML_TEXTWRITER_ATTRIBUTE:
1685 count = xmlTextWriterEndAttribute(writer);
1686 if (count < 0)
1687 return -1;
1688 sum += count;
1689 /* fallthrough */
1690 case XML_TEXTWRITER_NAME:
1691 count = xmlOutputBufferWriteString(writer->out, " ");
1692 if (count < 0)
1693 return -1;
1694 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00001695 count =
1696 xmlOutputBufferWriteString(writer->out,
1697 (const char *) name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001698 if (count < 0)
1699 return -1;
1700 sum += count;
1701 count = xmlOutputBufferWriteString(writer->out, "=");
1702 if (count < 0)
1703 return -1;
1704 sum += count;
1705 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
1706 if (count < 0)
1707 return -1;
1708 sum += count;
1709 p->state = XML_TEXTWRITER_ATTRIBUTE;
1710 break;
1711 default:
1712 return -1;
1713 }
1714
1715 return sum;
1716}
1717
1718/**
1719 * xmlTextWriterStartAttributeNS:
1720 * @writer: the xmlTextWriterPtr
1721 * @prefix: namespace prefix or NULL
1722 * @name: element local name
1723 * @namespaceURI: namespace URI or NULL
1724 *
1725 * Start an xml attribute with namespace support.
1726 *
1727 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1728 */
1729int
1730xmlTextWriterStartAttributeNS(xmlTextWriterPtr writer,
1731 const xmlChar * prefix, const xmlChar * name,
1732 const xmlChar * namespaceURI)
1733{
1734 int count;
1735 int sum;
1736 xmlChar *buf;
1737 xmlTextWriterNsStackEntry *p;
1738
1739 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1740 return -1;
1741
1742 buf = 0;
1743 if (prefix != 0) {
1744 buf = xmlStrdup(prefix);
1745 buf = xmlStrcat(buf, BAD_CAST ":");
1746 }
1747 buf = xmlStrcat(buf, name);
1748
1749 sum = 0;
1750 count = xmlTextWriterStartAttribute(writer, buf);
1751 xmlFree(buf);
1752 if (count < 0)
1753 return -1;
1754 sum += count;
1755
1756 if (namespaceURI != 0) {
1757 buf = xmlStrdup(BAD_CAST "xmlns");
1758 if (prefix != 0) {
1759 buf = xmlStrcat(buf, BAD_CAST ":");
1760 buf = xmlStrcat(buf, prefix);
1761 }
1762
1763 p = (xmlTextWriterNsStackEntry *)
1764 xmlMalloc(sizeof(xmlTextWriterNsStackEntry));
1765 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00001766 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00001767 "xmlTextWriterStartAttributeNS : out of memory!\n");
1768 return -1;
1769 }
1770
1771 p->prefix = buf;
1772 p->uri = xmlStrdup(namespaceURI);
1773 if (p->uri == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00001774 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00001775 "xmlTextWriterStartAttributeNS : out of memory!\n");
1776 xmlFree(p);
1777 return -1;
1778 }
1779 p->elem = xmlListFront(writer->nodes);
1780
1781 xmlListPushFront(writer->nsstack, p);
1782 }
1783
1784 return sum;
1785}
1786
1787/**
1788 * xmlTextWriterEndAttribute:
1789 * @writer: the xmlTextWriterPtr
1790 *
1791 * End the current xml element.
1792 *
1793 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1794 */
1795int
1796xmlTextWriterEndAttribute(xmlTextWriterPtr writer)
1797{
1798 int count;
1799 int sum;
1800 xmlLinkPtr lk;
1801 xmlTextWriterStackEntry *p;
1802 xmlTextWriterNsStackEntry *np;
1803
1804 if (writer == NULL)
1805 return -1;
1806
1807 lk = xmlListFront(writer->nodes);
1808 if (lk == 0) {
1809 xmlListDelete(writer->nsstack);
Daniel Veillarde43cc572004-11-03 11:50:29 +00001810 writer->nsstack = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001811 return -1;
1812 }
1813
1814 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1815 if (p == 0) {
1816 xmlListDelete(writer->nsstack);
Daniel Veillarde43cc572004-11-03 11:50:29 +00001817 writer->nsstack = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001818 return -1;
1819 }
1820
1821 sum = 0;
1822 switch (p->state) {
1823 case XML_TEXTWRITER_ATTRIBUTE:
1824 p->state = XML_TEXTWRITER_NAME;
1825
1826 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
1827 if (count < 0) {
1828 xmlListDelete(writer->nsstack);
Daniel Veillarde43cc572004-11-03 11:50:29 +00001829 writer->nsstack = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001830 return -1;
1831 }
1832 sum += count;
1833
1834 while (!xmlListEmpty(writer->nsstack)) {
1835 lk = xmlListFront(writer->nsstack);
1836 np = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
1837 if (np != 0) {
1838 count =
1839 xmlTextWriterWriteAttribute(writer, np->prefix,
1840 np->uri);
1841 if (count < 0) {
1842 xmlListDelete(writer->nsstack);
Daniel Veillarde43cc572004-11-03 11:50:29 +00001843 writer->nsstack = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001844 return -1;
1845 }
1846 sum += count;
1847 }
1848
1849 xmlListPopFront(writer->nsstack);
1850 }
1851 break;
1852
1853 default:
1854 xmlListClear(writer->nsstack);
1855 return -1;
1856 }
1857
1858 return sum;
1859}
1860
1861/**
1862 * xmlTextWriterWriteFormatAttribute:
1863 * @writer: the xmlTextWriterPtr
1864 * @name: attribute name
1865 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001866 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001867 *
1868 * Write a formatted xml attribute.
1869 *
1870 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1871 */
1872int
1873xmlTextWriterWriteFormatAttribute(xmlTextWriterPtr writer,
1874 const xmlChar * name, const char *format,
1875 ...)
1876{
1877 int rc;
1878 va_list ap;
1879
1880 va_start(ap, format);
1881
1882 rc = xmlTextWriterWriteVFormatAttribute(writer, name, format, ap);
1883
1884 va_end(ap);
1885 return rc;
1886}
1887
1888/**
1889 * xmlTextWriterWriteVFormatAttribute:
1890 * @writer: the xmlTextWriterPtr
1891 * @name: attribute name
1892 * @format: format string (see printf)
1893 * @argptr: pointer to the first member of the variable argument list.
1894 *
1895 * Write a formatted xml attribute.
1896 *
1897 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1898 */
1899int
1900xmlTextWriterWriteVFormatAttribute(xmlTextWriterPtr writer,
1901 const xmlChar * name,
1902 const char *format, va_list argptr)
1903{
1904 int rc;
1905 xmlChar *buf;
1906
1907 if (writer == NULL)
1908 return -1;
1909
1910 buf = xmlTextWriterVSprintf(format, argptr);
1911 if (buf == 0)
1912 return 0;
1913
1914 rc = xmlTextWriterWriteAttribute(writer, name, buf);
1915
1916 xmlFree(buf);
1917 return rc;
1918}
1919
1920/**
1921 * xmlTextWriterWriteAttribute:
1922 * @writer: the xmlTextWriterPtr
1923 * @name: attribute name
1924 * @content: attribute content
1925 *
1926 * Write an xml attribute.
1927 *
1928 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1929 */
1930int
1931xmlTextWriterWriteAttribute(xmlTextWriterPtr writer, const xmlChar * name,
1932 const xmlChar * content)
1933{
1934 int count;
1935 int sum;
1936
1937 sum = 0;
1938 count = xmlTextWriterStartAttribute(writer, name);
1939 if (count < 0)
1940 return -1;
1941 sum += count;
1942 count = xmlTextWriterWriteString(writer, content);
1943 if (count < 0)
1944 return -1;
1945 sum += count;
1946 count = xmlTextWriterEndAttribute(writer);
1947 if (count < 0)
1948 return -1;
1949 sum += count;
1950
1951 return sum;
1952}
1953
1954/**
1955 * xmlTextWriterWriteFormatAttributeNS:
1956 * @writer: the xmlTextWriterPtr
1957 * @prefix: namespace prefix
1958 * @name: attribute local name
1959 * @namespaceURI: namespace URI
1960 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001961 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001962 *
1963 * Write a formatted xml attribute.with namespace support
1964 *
1965 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1966 */
1967int
1968xmlTextWriterWriteFormatAttributeNS(xmlTextWriterPtr writer,
1969 const xmlChar * prefix,
1970 const xmlChar * name,
1971 const xmlChar * namespaceURI,
1972 const char *format, ...)
1973{
1974 int rc;
1975 va_list ap;
1976
1977 va_start(ap, format);
1978
1979 rc = xmlTextWriterWriteVFormatAttributeNS(writer, prefix, name,
1980 namespaceURI, format, ap);
1981
1982 va_end(ap);
1983 return rc;
1984}
1985
1986/**
1987 * xmlTextWriterWriteVFormatAttributeNS:
1988 * @writer: the xmlTextWriterPtr
1989 * @prefix: namespace prefix
1990 * @name: attribute local name
1991 * @namespaceURI: namespace URI
1992 * @format: format string (see printf)
1993 * @argptr: pointer to the first member of the variable argument list.
1994 *
1995 * Write a formatted xml attribute.with namespace support
1996 *
1997 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1998 */
1999int
2000xmlTextWriterWriteVFormatAttributeNS(xmlTextWriterPtr writer,
2001 const xmlChar * prefix,
2002 const xmlChar * name,
2003 const xmlChar * namespaceURI,
2004 const char *format, va_list argptr)
2005{
2006 int rc;
2007 xmlChar *buf;
2008
2009 if (writer == NULL)
2010 return -1;
2011
2012 buf = xmlTextWriterVSprintf(format, argptr);
2013 if (buf == 0)
2014 return 0;
2015
2016 rc = xmlTextWriterWriteAttributeNS(writer, prefix, name, namespaceURI,
2017 buf);
2018
2019 xmlFree(buf);
2020 return rc;
2021}
2022
2023/**
2024 * xmlTextWriterWriteAttributeNS:
2025 * @writer: the xmlTextWriterPtr
2026 * @prefix: namespace prefix
2027 * @name: attribute local name
2028 * @namespaceURI: namespace URI
2029 * @content: attribute content
2030 *
2031 * Write an xml attribute.
2032 *
2033 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2034 */
2035int
2036xmlTextWriterWriteAttributeNS(xmlTextWriterPtr writer,
2037 const xmlChar * prefix, const xmlChar * name,
2038 const xmlChar * namespaceURI,
2039 const xmlChar * content)
2040{
2041 int count;
2042 int sum;
2043 xmlChar *buf;
2044
2045 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
2046 return -1;
2047
2048 buf = 0;
2049 if (prefix != NULL) {
2050 buf = xmlStrdup(prefix);
2051 buf = xmlStrcat(buf, BAD_CAST ":");
2052 }
2053 buf = xmlStrcat(buf, name);
2054
2055 sum = 0;
2056 count = xmlTextWriterWriteAttribute(writer, buf, content);
2057 xmlFree(buf);
2058 if (count < 0)
2059 return -1;
2060 sum += count;
2061
2062 if (namespaceURI != NULL) {
2063 buf = 0;
2064 buf = xmlStrdup(BAD_CAST "xmlns");
2065 if (prefix != NULL) {
2066 buf = xmlStrcat(buf, BAD_CAST ":");
2067 buf = xmlStrcat(buf, prefix);
2068 }
2069 count = xmlTextWriterWriteAttribute(writer, buf, namespaceURI);
2070 xmlFree(buf);
2071 if (count < 0)
2072 return -1;
2073 sum += count;
2074 }
2075 return sum;
2076}
2077
2078/**
2079 * xmlTextWriterWriteFormatElement:
2080 * @writer: the xmlTextWriterPtr
2081 * @name: element name
2082 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002083 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002084 *
2085 * Write a formatted xml element.
2086 *
2087 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2088 */
2089int
2090xmlTextWriterWriteFormatElement(xmlTextWriterPtr writer,
2091 const xmlChar * name, const char *format,
2092 ...)
2093{
2094 int rc;
2095 va_list ap;
2096
2097 va_start(ap, format);
2098
2099 rc = xmlTextWriterWriteVFormatElement(writer, name, format, ap);
2100
2101 va_end(ap);
2102 return rc;
2103}
2104
2105/**
2106 * xmlTextWriterWriteVFormatElement:
2107 * @writer: the xmlTextWriterPtr
2108 * @name: element name
2109 * @format: format string (see printf)
2110 * @argptr: pointer to the first member of the variable argument list.
2111 *
2112 * Write a formatted xml element.
2113 *
2114 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2115 */
2116int
2117xmlTextWriterWriteVFormatElement(xmlTextWriterPtr writer,
2118 const xmlChar * name, const char *format,
2119 va_list argptr)
2120{
2121 int rc;
2122 xmlChar *buf;
2123
2124 if (writer == NULL)
2125 return -1;
2126
2127 buf = xmlTextWriterVSprintf(format, argptr);
2128 if (buf == 0)
2129 return 0;
2130
2131 rc = xmlTextWriterWriteElement(writer, name, buf);
2132
2133 xmlFree(buf);
2134 return rc;
2135}
2136
2137/**
2138 * xmlTextWriterWriteElement:
2139 * @writer: the xmlTextWriterPtr
2140 * @name: element name
2141 * @content: element content
2142 *
2143 * Write an xml element.
2144 *
2145 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2146 */
2147int
2148xmlTextWriterWriteElement(xmlTextWriterPtr writer, const xmlChar * name,
2149 const xmlChar * content)
2150{
2151 int count;
2152 int sum;
2153
2154 sum = 0;
2155 count = xmlTextWriterStartElement(writer, name);
2156 if (count == -1)
2157 return -1;
2158 sum += count;
2159 count = xmlTextWriterWriteString(writer, content);
2160 if (count == -1)
2161 return -1;
2162 sum += count;
2163 count = xmlTextWriterEndElement(writer);
2164 if (count == -1)
2165 return -1;
2166 sum += count;
2167
2168 return sum;
2169}
2170
2171/**
2172 * xmlTextWriterWriteFormatElementNS:
2173 * @writer: the xmlTextWriterPtr
2174 * @prefix: namespace prefix
2175 * @name: element local name
2176 * @namespaceURI: namespace URI
2177 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002178 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002179 *
2180 * Write a formatted xml element with namespace support.
2181 *
2182 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2183 */
2184int
2185xmlTextWriterWriteFormatElementNS(xmlTextWriterPtr writer,
2186 const xmlChar * prefix,
2187 const xmlChar * name,
2188 const xmlChar * namespaceURI,
2189 const char *format, ...)
2190{
2191 int rc;
2192 va_list ap;
2193
2194 va_start(ap, format);
2195
2196 rc = xmlTextWriterWriteVFormatElementNS(writer, prefix, name,
2197 namespaceURI, format, ap);
2198
2199 va_end(ap);
2200 return rc;
2201}
2202
2203/**
2204 * xmlTextWriterWriteVFormatElementNS:
2205 * @writer: the xmlTextWriterPtr
2206 * @prefix: namespace prefix
2207 * @name: element local name
2208 * @namespaceURI: namespace URI
2209 * @format: format string (see printf)
2210 * @argptr: pointer to the first member of the variable argument list.
2211 *
2212 * Write a formatted xml element with namespace support.
2213 *
2214 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2215 */
2216int
2217xmlTextWriterWriteVFormatElementNS(xmlTextWriterPtr writer,
2218 const xmlChar * prefix,
2219 const xmlChar * name,
2220 const xmlChar * namespaceURI,
2221 const char *format, va_list argptr)
2222{
2223 int rc;
2224 xmlChar *buf;
2225
2226 if (writer == NULL)
2227 return -1;
2228
2229 buf = xmlTextWriterVSprintf(format, argptr);
2230 if (buf == 0)
2231 return 0;
2232
2233 rc = xmlTextWriterWriteElementNS(writer, prefix, name, namespaceURI,
2234 buf);
2235
2236 xmlFree(buf);
2237 return rc;
2238}
2239
2240/**
2241 * xmlTextWriterWriteElementNS:
2242 * @writer: the xmlTextWriterPtr
2243 * @prefix: namespace prefix
2244 * @name: element local name
2245 * @namespaceURI: namespace URI
2246 * @content: element content
2247 *
2248 * Write an xml element with namespace support.
2249 *
2250 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2251 */
2252int
2253xmlTextWriterWriteElementNS(xmlTextWriterPtr writer,
2254 const xmlChar * prefix, const xmlChar * name,
2255 const xmlChar * namespaceURI,
2256 const xmlChar * content)
2257{
2258 int count;
2259 int sum;
2260
2261 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
2262 return -1;
2263
2264 sum = 0;
2265 count =
2266 xmlTextWriterStartElementNS(writer, prefix, name, namespaceURI);
2267 if (count < 0)
2268 return -1;
2269 sum += count;
2270 count = xmlTextWriterWriteString(writer, content);
2271 if (count == -1)
2272 return -1;
2273 sum += count;
2274 count = xmlTextWriterEndElement(writer);
2275 if (count == -1)
2276 return -1;
2277 sum += count;
2278
2279 return sum;
2280}
2281
2282/**
2283 * xmlTextWriterStartPI:
2284 * @writer: the xmlTextWriterPtr
2285 * @target: PI target
2286 *
2287 * Start an xml PI.
2288 *
2289 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2290 */
2291int
2292xmlTextWriterStartPI(xmlTextWriterPtr writer, const xmlChar * target)
2293{
2294 int count;
2295 int sum;
2296 xmlLinkPtr lk;
2297 xmlTextWriterStackEntry *p;
2298
2299 if ((writer == NULL) || (target == NULL) || (*target == '\0'))
2300 return -1;
2301
2302 if (xmlStrcasecmp(target, (const xmlChar *) "xml") == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002303 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002304 "xmlTextWriterStartPI : target name [Xx][Mm][Ll] is reserved for xml standardization!\n");
2305 return -1;
2306 }
2307
2308 sum = 0;
2309 lk = xmlListFront(writer->nodes);
2310 if (lk != 0) {
2311 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2312 if (p != 0) {
2313 switch (p->state) {
2314 case XML_TEXTWRITER_ATTRIBUTE:
2315 count = xmlTextWriterEndAttribute(writer);
2316 if (count < 0)
2317 return -1;
2318 sum += count;
2319 /* fallthrough */
2320 case XML_TEXTWRITER_NAME:
2321 count = xmlOutputBufferWriteString(writer->out, ">");
2322 if (count < 0)
2323 return -1;
2324 sum += count;
2325 p->state = XML_TEXTWRITER_TEXT;
2326 break;
Daniel Veillardab69f362004-02-17 11:40:32 +00002327 case XML_TEXTWRITER_NONE:
2328 case XML_TEXTWRITER_TEXT:
2329 case XML_TEXTWRITER_DTD:
2330 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002331 case XML_TEXTWRITER_PI:
2332 case XML_TEXTWRITER_PI_TEXT:
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002333 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002334 "xmlTextWriterStartPI : nested PI!\n");
2335 return -1;
2336 default:
2337 return -1;
2338 }
2339 }
2340 }
2341
2342 p = (xmlTextWriterStackEntry *)
2343 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2344 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002345 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002346 "xmlTextWriterStartPI : out of memory!\n");
2347 return -1;
2348 }
2349
2350 p->name = xmlStrdup(target);
2351 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002352 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002353 "xmlTextWriterStartPI : out of memory!\n");
2354 xmlFree(p);
2355 return -1;
2356 }
2357 p->state = XML_TEXTWRITER_PI;
2358
2359 xmlListPushFront(writer->nodes, p);
2360
2361 count = xmlOutputBufferWriteString(writer->out, "<?");
2362 if (count < 0)
2363 return -1;
2364 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002365 count =
2366 xmlOutputBufferWriteString(writer->out, (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002367 if (count < 0)
2368 return -1;
2369 sum += count;
2370
2371 return sum;
2372}
2373
2374/**
2375 * xmlTextWriterEndPI:
2376 * @writer: the xmlTextWriterPtr
2377 *
2378 * End the current xml PI.
2379 *
2380 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2381 */
2382int
2383xmlTextWriterEndPI(xmlTextWriterPtr writer)
2384{
2385 int count;
2386 int sum;
2387 xmlLinkPtr lk;
2388 xmlTextWriterStackEntry *p;
2389
2390 if (writer == NULL)
2391 return -1;
2392
2393 lk = xmlListFront(writer->nodes);
2394 if (lk == 0)
2395 return 0;
2396
2397 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2398 if (p == 0)
2399 return 0;
2400
2401 sum = 0;
2402 switch (p->state) {
2403 case XML_TEXTWRITER_PI:
2404 case XML_TEXTWRITER_PI_TEXT:
2405 count = xmlOutputBufferWriteString(writer->out, "?>");
2406 if (count < 0)
2407 return -1;
2408 sum += count;
2409 break;
2410 default:
2411 return -1;
2412 }
2413
2414 xmlListPopFront(writer->nodes);
2415 return sum;
2416}
2417
2418/**
2419 * xmlTextWriterWriteFormatPI:
2420 * @writer: the xmlTextWriterPtr
2421 * @target: PI target
2422 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002423 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002424 *
2425 * Write a formatted PI.
2426 *
2427 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2428 */
2429int
2430xmlTextWriterWriteFormatPI(xmlTextWriterPtr writer, const xmlChar * target,
2431 const char *format, ...)
2432{
2433 int rc;
2434 va_list ap;
2435
2436 va_start(ap, format);
2437
2438 rc = xmlTextWriterWriteVFormatPI(writer, target, format, ap);
2439
2440 va_end(ap);
2441 return rc;
2442}
2443
2444/**
2445 * xmlTextWriterWriteVFormatPI:
2446 * @writer: the xmlTextWriterPtr
2447 * @target: PI target
2448 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002449 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00002450 *
2451 * Write a formatted xml PI.
2452 *
2453 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2454 */
2455int
2456xmlTextWriterWriteVFormatPI(xmlTextWriterPtr writer,
2457 const xmlChar * target, const char *format,
2458 va_list argptr)
2459{
2460 int rc;
2461 xmlChar *buf;
2462
2463 if (writer == NULL)
2464 return -1;
2465
2466 buf = xmlTextWriterVSprintf(format, argptr);
2467 if (buf == 0)
2468 return 0;
2469
2470 rc = xmlTextWriterWritePI(writer, target, buf);
2471
2472 xmlFree(buf);
2473 return rc;
2474}
2475
2476/**
2477 * xmlTextWriterWritePI:
2478 * @writer: the xmlTextWriterPtr
2479 * @target: PI target
2480 * @content: PI content
2481 *
2482 * Write an xml PI.
2483 *
2484 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2485 */
2486int
2487xmlTextWriterWritePI(xmlTextWriterPtr writer, const xmlChar * target,
2488 const xmlChar * content)
2489{
2490 int count;
2491 int sum;
2492
2493 sum = 0;
2494 count = xmlTextWriterStartPI(writer, target);
2495 if (count == -1)
2496 return -1;
2497 sum += count;
2498 if (content != 0) {
2499 count = xmlTextWriterWriteString(writer, content);
2500 if (count == -1)
2501 return -1;
2502 sum += count;
2503 }
2504 count = xmlTextWriterEndPI(writer);
2505 if (count == -1)
2506 return -1;
2507 sum += count;
2508
2509 return sum;
2510}
2511
2512/**
2513 * xmlTextWriterStartCDATA:
2514 * @writer: the xmlTextWriterPtr
2515 *
2516 * Start an xml CDATA section.
2517 *
2518 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2519 */
2520int
2521xmlTextWriterStartCDATA(xmlTextWriterPtr writer)
2522{
2523 int count;
2524 int sum;
2525 xmlLinkPtr lk;
2526 xmlTextWriterStackEntry *p;
2527
2528 if (writer == NULL)
2529 return -1;
2530
2531 sum = 0;
2532 lk = xmlListFront(writer->nodes);
2533 if (lk != 0) {
2534 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2535 if (p != 0) {
2536 switch (p->state) {
2537 case XML_TEXTWRITER_NONE:
2538 case XML_TEXTWRITER_PI:
2539 case XML_TEXTWRITER_PI_TEXT:
2540 break;
2541 case XML_TEXTWRITER_ATTRIBUTE:
2542 count = xmlTextWriterEndAttribute(writer);
2543 if (count < 0)
2544 return -1;
2545 sum += count;
2546 /* fallthrough */
2547 case XML_TEXTWRITER_NAME:
2548 count = xmlOutputBufferWriteString(writer->out, ">");
2549 if (count < 0)
2550 return -1;
2551 sum += count;
2552 p->state = XML_TEXTWRITER_TEXT;
2553 break;
2554 case XML_TEXTWRITER_CDATA:
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002555 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002556 "xmlTextWriterStartCDATA : CDATA not allowed in this context!\n");
2557 return -1;
2558 default:
2559 return -1;
2560 }
2561 }
2562 }
2563
2564 p = (xmlTextWriterStackEntry *)
2565 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2566 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002567 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002568 "xmlTextWriterStartCDATA : out of memory!\n");
2569 return -1;
2570 }
2571
2572 p->name = 0;
2573 p->state = XML_TEXTWRITER_CDATA;
2574
2575 xmlListPushFront(writer->nodes, p);
2576
2577 count = xmlOutputBufferWriteString(writer->out, "<![CDATA[");
2578 if (count < 0)
2579 return -1;
2580 sum += count;
2581
2582 return sum;
2583}
2584
2585/**
2586 * xmlTextWriterEndCDATA:
2587 * @writer: the xmlTextWriterPtr
2588 *
2589 * End an xml CDATA section.
2590 *
2591 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2592 */
2593int
2594xmlTextWriterEndCDATA(xmlTextWriterPtr writer)
2595{
2596 int count;
2597 int sum;
2598 xmlLinkPtr lk;
2599 xmlTextWriterStackEntry *p;
2600
2601 if (writer == NULL)
2602 return -1;
2603
2604 lk = xmlListFront(writer->nodes);
2605 if (lk == 0)
2606 return -1;
2607
2608 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2609 if (p == 0)
2610 return -1;
2611
2612 sum = 0;
2613 switch (p->state) {
2614 case XML_TEXTWRITER_CDATA:
2615 count = xmlOutputBufferWriteString(writer->out, "]]>");
2616 if (count < 0)
2617 return -1;
2618 sum += count;
2619 break;
2620 default:
2621 return -1;
2622 }
2623
2624 xmlListPopFront(writer->nodes);
2625 return sum;
2626}
2627
2628/**
2629 * xmlTextWriterWriteFormatCDATA:
2630 * @writer: the xmlTextWriterPtr
2631 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002632 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002633 *
2634 * Write a formatted xml CDATA.
2635 *
2636 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2637 */
2638int
2639xmlTextWriterWriteFormatCDATA(xmlTextWriterPtr writer, const char *format,
2640 ...)
2641{
2642 int rc;
2643 va_list ap;
2644
2645 va_start(ap, format);
2646
2647 rc = xmlTextWriterWriteVFormatCDATA(writer, format, ap);
2648
2649 va_end(ap);
2650 return rc;
2651}
2652
2653/**
2654 * xmlTextWriterWriteVFormatCDATA:
2655 * @writer: the xmlTextWriterPtr
2656 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002657 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00002658 *
2659 * Write a formatted xml CDATA.
2660 *
2661 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2662 */
2663int
2664xmlTextWriterWriteVFormatCDATA(xmlTextWriterPtr writer, const char *format,
2665 va_list argptr)
2666{
2667 int rc;
2668 xmlChar *buf;
2669
2670 if (writer == NULL)
2671 return -1;
2672
2673 buf = xmlTextWriterVSprintf(format, argptr);
2674 if (buf == 0)
2675 return 0;
2676
2677 rc = xmlTextWriterWriteCDATA(writer, buf);
2678
2679 xmlFree(buf);
2680 return rc;
2681}
2682
2683/**
2684 * xmlTextWriterWriteCDATA:
2685 * @writer: the xmlTextWriterPtr
2686 * @content: CDATA content
2687 *
2688 * Write an xml CDATA.
2689 *
2690 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2691 */
2692int
2693xmlTextWriterWriteCDATA(xmlTextWriterPtr writer, const xmlChar * content)
2694{
2695 int count;
2696 int sum;
2697
2698 sum = 0;
2699 count = xmlTextWriterStartCDATA(writer);
2700 if (count == -1)
2701 return -1;
2702 sum += count;
2703 if (content != 0) {
2704 count = xmlTextWriterWriteString(writer, content);
2705 if (count == -1)
2706 return -1;
2707 sum += count;
2708 }
2709 count = xmlTextWriterEndCDATA(writer);
2710 if (count == -1)
2711 return -1;
2712 sum += count;
2713
2714 return sum;
2715}
2716
2717/**
2718 * xmlTextWriterStartDTD:
2719 * @writer: the xmlTextWriterPtr
2720 * @name: the name of the DTD
2721 * @pubid: the public identifier, which is an alternative to the system identifier
2722 * @sysid: the system identifier, which is the URI of the DTD
2723 *
2724 * Start an xml DTD.
2725 *
2726 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2727 */
2728int
2729xmlTextWriterStartDTD(xmlTextWriterPtr writer,
2730 const xmlChar * name,
2731 const xmlChar * pubid, const xmlChar * sysid)
2732{
2733 int count;
2734 int sum;
2735 xmlLinkPtr lk;
2736 xmlTextWriterStackEntry *p;
2737
2738 if (writer == NULL || name == NULL || *name == '\0')
2739 return -1;
2740
2741 sum = 0;
2742 lk = xmlListFront(writer->nodes);
Daniel Veillardab69f362004-02-17 11:40:32 +00002743 if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002744 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002745 "xmlTextWriterStartDTD : DTD allowed only in prolog!\n");
2746 return -1;
2747 }
2748
2749 p = (xmlTextWriterStackEntry *)
2750 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2751 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002752 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002753 "xmlTextWriterStartDTD : out of memory!\n");
2754 return -1;
2755 }
2756
2757 p->name = xmlStrdup(name);
2758 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002759 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002760 "xmlTextWriterStartDTD : out of memory!\n");
2761 xmlFree(p);
2762 return -1;
2763 }
2764 p->state = XML_TEXTWRITER_DTD;
2765
2766 xmlListPushFront(writer->nodes, p);
2767
2768 count = xmlOutputBufferWriteString(writer->out, "<!DOCTYPE ");
2769 if (count < 0)
2770 return -1;
2771 sum += count;
2772 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
2773 if (count < 0)
2774 return -1;
2775 sum += count;
2776
2777 if (pubid != 0) {
2778 if (sysid == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002779 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002780 "xmlTextWriterStartDTD : system identifier needed!\n");
2781 return -1;
2782 }
2783
Daniel Veillard500a1de2004-03-22 15:22:58 +00002784 if (writer->indent)
2785 count = xmlOutputBufferWrite(writer->out, 1, "\n");
2786 else
2787 count = xmlOutputBufferWrite(writer->out, 1, " ");
2788 if (count < 0)
2789 return -1;
2790 sum += count;
2791
2792 count = xmlOutputBufferWriteString(writer->out, "PUBLIC ");
2793 if (count < 0)
2794 return -1;
2795 sum += count;
2796
2797 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002798 if (count < 0)
2799 return -1;
2800 sum += count;
2801
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002802 count =
2803 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002804 if (count < 0)
2805 return -1;
2806 sum += count;
2807
Daniel Veillard500a1de2004-03-22 15:22:58 +00002808 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002809 if (count < 0)
2810 return -1;
2811 sum += count;
2812 }
2813
2814 if (sysid != 0) {
2815 if (pubid == 0) {
Daniel Veillard500a1de2004-03-22 15:22:58 +00002816 if (writer->indent)
2817 count = xmlOutputBufferWrite(writer->out, 1, "\n");
2818 else
2819 count = xmlOutputBufferWrite(writer->out, 1, " ");
2820 if (count < 0)
2821 return -1;
2822 sum += count;
2823 count = xmlOutputBufferWriteString(writer->out, "SYSTEM ");
2824 if (count < 0)
2825 return -1;
2826 sum += count;
2827 } else if (writer->indent) {
2828 count = xmlOutputBufferWriteString(writer->out, "\n ");
Daniel Veillard1d211e22003-10-20 22:32:39 +00002829 if (count < 0)
2830 return -1;
2831 sum += count;
2832 }
2833
Daniel Veillard500a1de2004-03-22 15:22:58 +00002834 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002835 if (count < 0)
2836 return -1;
2837 sum += count;
2838
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002839 count =
2840 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002841 if (count < 0)
2842 return -1;
2843 sum += count;
2844
Daniel Veillard500a1de2004-03-22 15:22:58 +00002845 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002846 if (count < 0)
2847 return -1;
2848 sum += count;
2849 }
2850
2851 return sum;
2852}
2853
2854/**
2855 * xmlTextWriterEndDTD:
2856 * @writer: the xmlTextWriterPtr
2857 *
2858 * End an xml DTD.
2859 *
2860 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2861 */
2862int
2863xmlTextWriterEndDTD(xmlTextWriterPtr writer)
2864{
Daniel Veillard500a1de2004-03-22 15:22:58 +00002865 int loop;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002866 int count;
2867 int sum;
2868 xmlLinkPtr lk;
2869 xmlTextWriterStackEntry *p;
2870
2871 if (writer == NULL)
2872 return -1;
2873
2874 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00002875 loop = 1;
2876 while (loop) {
2877 lk = xmlListFront(writer->nodes);
2878 if (lk == NULL)
Daniel Veillard1d211e22003-10-20 22:32:39 +00002879 break;
Daniel Veillard500a1de2004-03-22 15:22:58 +00002880 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2881 if (p == 0)
2882 break;
2883 switch (p->state) {
2884 case XML_TEXTWRITER_DTD_TEXT:
2885 count = xmlOutputBufferWriteString(writer->out, "]");
2886 if (count < 0)
2887 return -1;
2888 sum += count;
2889 /* fallthrough */
2890 case XML_TEXTWRITER_DTD:
2891 count = xmlOutputBufferWriteString(writer->out, ">");
2892
2893 if (writer->indent) {
2894 if (count < 0)
2895 return -1;
2896 sum += count;
2897 count = xmlOutputBufferWriteString(writer->out, "\n");
2898 }
2899
2900 xmlListPopFront(writer->nodes);
2901 break;
2902 case XML_TEXTWRITER_DTD_ELEM:
2903 case XML_TEXTWRITER_DTD_ELEM_TEXT:
2904 count = xmlTextWriterEndDTDElement(writer);
2905 break;
2906 case XML_TEXTWRITER_DTD_ATTL:
2907 case XML_TEXTWRITER_DTD_ATTL_TEXT:
2908 count = xmlTextWriterEndDTDAttlist(writer);
2909 break;
2910 case XML_TEXTWRITER_DTD_ENTY:
2911 case XML_TEXTWRITER_DTD_PENT:
2912 case XML_TEXTWRITER_DTD_ENTY_TEXT:
2913 count = xmlTextWriterEndDTDEntity(writer);
2914 break;
2915 case XML_TEXTWRITER_COMMENT:
2916 count = xmlTextWriterEndComment(writer);
2917 break;
2918 default:
2919 loop = 0;
2920 continue;
2921 }
2922
2923 if (count < 0)
Daniel Veillard1d211e22003-10-20 22:32:39 +00002924 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00002925 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002926 }
2927
Daniel Veillard1d211e22003-10-20 22:32:39 +00002928 return sum;
2929}
2930
2931/**
2932 * xmlTextWriterWriteFormatDTD:
2933 * @writer: the xmlTextWriterPtr
2934 * @name: the name of the DTD
2935 * @pubid: the public identifier, which is an alternative to the system identifier
2936 * @sysid: the system identifier, which is the URI of the DTD
2937 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002938 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002939 *
2940 * Write a DTD with a formatted markup declarations part.
2941 *
2942 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2943 */
2944int
2945xmlTextWriterWriteFormatDTD(xmlTextWriterPtr writer,
2946 const xmlChar * name,
2947 const xmlChar * pubid,
2948 const xmlChar * sysid, const char *format, ...)
2949{
2950 int rc;
2951 va_list ap;
2952
2953 va_start(ap, format);
2954
2955 rc = xmlTextWriterWriteVFormatDTD(writer, name, pubid, sysid, format,
2956 ap);
2957
2958 va_end(ap);
2959 return rc;
2960}
2961
2962/**
2963 * xmlTextWriterWriteVFormatDTD:
2964 * @writer: the xmlTextWriterPtr
2965 * @name: the name of the DTD
2966 * @pubid: the public identifier, which is an alternative to the system identifier
2967 * @sysid: the system identifier, which is the URI of the DTD
2968 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002969 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00002970 *
2971 * Write a DTD with a formatted markup declarations part.
2972 *
2973 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2974 */
2975int
2976xmlTextWriterWriteVFormatDTD(xmlTextWriterPtr writer,
2977 const xmlChar * name,
2978 const xmlChar * pubid,
2979 const xmlChar * sysid,
2980 const char *format, va_list argptr)
2981{
2982 int rc;
2983 xmlChar *buf;
2984
2985 if (writer == NULL)
2986 return -1;
2987
2988 buf = xmlTextWriterVSprintf(format, argptr);
2989 if (buf == 0)
2990 return 0;
2991
2992 rc = xmlTextWriterWriteDTD(writer, name, pubid, sysid, buf);
2993
2994 xmlFree(buf);
2995 return rc;
2996}
2997
2998/**
2999 * xmlTextWriterWriteDTD:
3000 * @writer: the xmlTextWriterPtr
3001 * @name: the name of the DTD
3002 * @pubid: the public identifier, which is an alternative to the system identifier
3003 * @sysid: the system identifier, which is the URI of the DTD
William M. Brackb1d53162003-11-18 06:54:40 +00003004 * @subset: string content of the DTD
Daniel Veillard1d211e22003-10-20 22:32:39 +00003005 *
3006 * Write a DTD.
3007 *
3008 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3009 */
3010int
3011xmlTextWriterWriteDTD(xmlTextWriterPtr writer,
3012 const xmlChar * name,
3013 const xmlChar * pubid,
3014 const xmlChar * sysid, const xmlChar * subset)
3015{
3016 int count;
3017 int sum;
3018
3019 sum = 0;
3020 count = xmlTextWriterStartDTD(writer, name, pubid, sysid);
3021 if (count == -1)
3022 return -1;
3023 sum += count;
3024 if (subset != 0) {
3025 count = xmlTextWriterWriteString(writer, subset);
3026 if (count == -1)
3027 return -1;
3028 sum += count;
3029 }
3030 count = xmlTextWriterEndDTD(writer);
3031 if (count == -1)
3032 return -1;
3033 sum += count;
3034
3035 return sum;
3036}
3037
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003038/**
3039 * xmlTextWriterStartDTDElement:
3040 * @writer: the xmlTextWriterPtr
3041 * @name: the name of the DTD element
3042 *
3043 * Start an xml DTD element.
3044 *
3045 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3046 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003047int
3048xmlTextWriterStartDTDElement(xmlTextWriterPtr writer, const xmlChar * name)
3049{
3050 int count;
3051 int sum;
3052 xmlLinkPtr lk;
3053 xmlTextWriterStackEntry *p;
3054
3055 if (writer == NULL || name == NULL || *name == '\0')
3056 return -1;
3057
3058 sum = 0;
3059 lk = xmlListFront(writer->nodes);
3060 if (lk == 0) {
3061 return -1;
3062 }
3063
3064 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
Daniel Veillard500a1de2004-03-22 15:22:58 +00003065 if (p != 0) {
3066 switch (p->state) {
3067 case XML_TEXTWRITER_DTD:
3068 count = xmlOutputBufferWriteString(writer->out, " [");
3069 if (count < 0)
3070 return -1;
3071 sum += count;
3072 if (writer->indent) {
3073 count = xmlOutputBufferWriteString(writer->out, "\n");
3074 if (count < 0)
3075 return -1;
3076 sum += count;
3077 }
3078 p->state = XML_TEXTWRITER_DTD_TEXT;
3079 /* fallthrough */
3080 case XML_TEXTWRITER_DTD_TEXT:
3081 case XML_TEXTWRITER_NONE:
3082 break;
3083 default:
Daniel Veillard1d211e22003-10-20 22:32:39 +00003084 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00003085 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00003086 }
3087
3088 p = (xmlTextWriterStackEntry *)
3089 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3090 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003091 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003092 "xmlTextWriterStartDTDElement : out of memory!\n");
3093 return -1;
3094 }
3095
3096 p->name = xmlStrdup(name);
3097 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003098 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003099 "xmlTextWriterStartDTDElement : out of memory!\n");
3100 xmlFree(p);
3101 return -1;
3102 }
3103 p->state = XML_TEXTWRITER_DTD_ELEM;
3104
3105 xmlListPushFront(writer->nodes, p);
3106
Daniel Veillard500a1de2004-03-22 15:22:58 +00003107 if (writer->indent) {
3108 count = xmlTextWriterWriteIndent(writer);
3109 if (count < 0)
3110 return -1;
3111 sum += count;
3112 }
3113
Daniel Veillard1d211e22003-10-20 22:32:39 +00003114 count = xmlOutputBufferWriteString(writer->out, "<!ELEMENT ");
3115 if (count < 0)
3116 return -1;
3117 sum += count;
3118 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
3119 if (count < 0)
3120 return -1;
3121 sum += count;
3122
3123 return sum;
3124}
3125
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003126/**
Daniel Veillard500a1de2004-03-22 15:22:58 +00003127 * xmlTextWriterEndDTDElement:
3128 * @writer: the xmlTextWriterPtr
3129 *
3130 * End an xml DTD element.
3131 *
3132 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3133 */
3134int
3135xmlTextWriterEndDTDElement(xmlTextWriterPtr writer)
3136{
3137 int count;
3138 int sum;
3139 xmlLinkPtr lk;
3140 xmlTextWriterStackEntry *p;
3141
3142 if (writer == NULL)
3143 return -1;
3144
3145 sum = 0;
3146 lk = xmlListFront(writer->nodes);
3147 if (lk == 0)
3148 return -1;
3149
3150 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3151 if (p == 0)
3152 return -1;
3153
3154 switch (p->state) {
3155 case XML_TEXTWRITER_DTD_ELEM:
3156 case XML_TEXTWRITER_DTD_ELEM_TEXT:
3157 count = xmlOutputBufferWriteString(writer->out, ">");
3158 if (count < 0)
3159 return -1;
3160 sum += count;
3161 break;
3162 default:
3163 return -1;
3164 }
3165
3166 if (writer->indent) {
3167 count = xmlOutputBufferWriteString(writer->out, "\n");
3168 if (count < 0)
3169 return -1;
3170 sum += count;
3171 }
3172
3173 xmlListPopFront(writer->nodes);
3174 return sum;
3175}
3176
3177/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003178 * xmlTextWriterWriteFormatDTDElement:
3179 * @writer: the xmlTextWriterPtr
3180 * @name: the name of the DTD element
3181 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003182 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003183 *
3184 * Write a formatted DTD element.
3185 *
3186 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3187 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003188int
3189xmlTextWriterWriteFormatDTDElement(xmlTextWriterPtr writer,
3190 const xmlChar * name,
3191 const char *format, ...)
3192{
3193 int rc;
3194 va_list ap;
3195
3196 va_start(ap, format);
3197
3198 rc = xmlTextWriterWriteVFormatDTDElement(writer, name, format, ap);
3199
3200 va_end(ap);
3201 return rc;
3202}
3203
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003204/**
3205 * xmlTextWriterWriteVFormatDTDElement:
3206 * @writer: the xmlTextWriterPtr
3207 * @name: the name of the DTD element
3208 * @format: format string (see printf)
3209 * @argptr: pointer to the first member of the variable argument list.
3210 *
3211 * Write a formatted DTD element.
3212 *
3213 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3214 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003215int
3216xmlTextWriterWriteVFormatDTDElement(xmlTextWriterPtr writer,
3217 const xmlChar * name,
3218 const char *format, va_list argptr)
3219{
3220 int rc;
3221 xmlChar *buf;
3222
3223 if (writer == NULL)
3224 return -1;
3225
3226 buf = xmlTextWriterVSprintf(format, argptr);
3227 if (buf == 0)
3228 return 0;
3229
3230 rc = xmlTextWriterWriteDTDElement(writer, name, buf);
3231
3232 xmlFree(buf);
3233 return rc;
3234}
3235
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003236/**
3237 * xmlTextWriterWriteDTDElement:
3238 * @writer: the xmlTextWriterPtr
3239 * @name: the name of the DTD element
3240 * @content: content of the element
3241 *
3242 * Write a DTD element.
3243 *
3244 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3245 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003246int
3247xmlTextWriterWriteDTDElement(xmlTextWriterPtr writer,
3248 const xmlChar * name, const xmlChar * content)
3249{
3250 int count;
3251 int sum;
3252
3253 if (content == NULL)
3254 return -1;
3255
3256 sum = 0;
3257 count = xmlTextWriterStartDTDElement(writer, name);
3258 if (count == -1)
3259 return -1;
3260 sum += count;
3261
Daniel Veillard1d211e22003-10-20 22:32:39 +00003262 count = xmlTextWriterWriteString(writer, content);
3263 if (count == -1)
3264 return -1;
3265 sum += count;
3266
3267 count = xmlTextWriterEndDTDElement(writer);
3268 if (count == -1)
3269 return -1;
3270 sum += count;
3271
3272 return sum;
3273}
3274
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003275/**
3276 * xmlTextWriterStartDTDAttlist:
3277 * @writer: the xmlTextWriterPtr
3278 * @name: the name of the DTD ATTLIST
3279 *
3280 * Start an xml DTD ATTLIST.
3281 *
3282 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3283 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003284int
3285xmlTextWriterStartDTDAttlist(xmlTextWriterPtr writer, const xmlChar * name)
3286{
3287 int count;
3288 int sum;
3289 xmlLinkPtr lk;
3290 xmlTextWriterStackEntry *p;
3291
3292 if (writer == NULL || name == NULL || *name == '\0')
3293 return -1;
3294
3295 sum = 0;
3296 lk = xmlListFront(writer->nodes);
3297 if (lk == 0) {
3298 return -1;
3299 }
3300
3301 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
Daniel Veillard500a1de2004-03-22 15:22:58 +00003302 if (p != 0) {
3303 switch (p->state) {
3304 case XML_TEXTWRITER_DTD:
3305 count = xmlOutputBufferWriteString(writer->out, " [");
3306 if (count < 0)
3307 return -1;
3308 sum += count;
3309 if (writer->indent) {
3310 count = xmlOutputBufferWriteString(writer->out, "\n");
3311 if (count < 0)
3312 return -1;
3313 sum += count;
3314 }
3315 p->state = XML_TEXTWRITER_DTD_TEXT;
3316 /* fallthrough */
3317 case XML_TEXTWRITER_DTD_TEXT:
3318 case XML_TEXTWRITER_NONE:
3319 break;
3320 default:
Daniel Veillard1d211e22003-10-20 22:32:39 +00003321 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00003322 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00003323 }
3324
3325 p = (xmlTextWriterStackEntry *)
3326 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3327 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003328 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003329 "xmlTextWriterStartDTDAttlist : out of memory!\n");
3330 return -1;
3331 }
3332
3333 p->name = xmlStrdup(name);
3334 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003335 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003336 "xmlTextWriterStartDTDAttlist : out of memory!\n");
3337 xmlFree(p);
3338 return -1;
3339 }
3340 p->state = XML_TEXTWRITER_DTD_ATTL;
3341
3342 xmlListPushFront(writer->nodes, p);
3343
Daniel Veillard500a1de2004-03-22 15:22:58 +00003344 if (writer->indent) {
3345 count = xmlTextWriterWriteIndent(writer);
3346 if (count < 0)
3347 return -1;
3348 sum += count;
3349 }
3350
Daniel Veillard1d211e22003-10-20 22:32:39 +00003351 count = xmlOutputBufferWriteString(writer->out, "<!ATTLIST ");
3352 if (count < 0)
3353 return -1;
3354 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +00003355 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003356 if (count < 0)
3357 return -1;
3358 sum += count;
3359
3360 return sum;
3361}
3362
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003363/**
Daniel Veillard500a1de2004-03-22 15:22:58 +00003364 * xmlTextWriterEndDTDAttlist:
3365 * @writer: the xmlTextWriterPtr
3366 *
3367 * End an xml DTD attribute list.
3368 *
3369 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3370 */
3371int
3372xmlTextWriterEndDTDAttlist(xmlTextWriterPtr writer)
3373{
3374 int count;
3375 int sum;
3376 xmlLinkPtr lk;
3377 xmlTextWriterStackEntry *p;
3378
3379 if (writer == NULL)
3380 return -1;
3381
3382 sum = 0;
3383 lk = xmlListFront(writer->nodes);
3384 if (lk == 0)
3385 return -1;
3386
3387 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3388 if (p == 0)
3389 return -1;
3390
3391 switch (p->state) {
3392 case XML_TEXTWRITER_DTD_ATTL:
3393 case XML_TEXTWRITER_DTD_ATTL_TEXT:
3394 count = xmlOutputBufferWriteString(writer->out, ">");
3395 if (count < 0)
3396 return -1;
3397 sum += count;
3398 break;
3399 default:
3400 return -1;
3401 }
3402
3403 if (writer->indent) {
3404 count = xmlOutputBufferWriteString(writer->out, "\n");
3405 if (count < 0)
3406 return -1;
3407 sum += count;
3408 }
3409
3410 xmlListPopFront(writer->nodes);
3411 return sum;
3412}
3413
3414/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003415 * xmlTextWriterWriteFormatDTDAttlist:
3416 * @writer: the xmlTextWriterPtr
3417 * @name: the name of the DTD ATTLIST
3418 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003419 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003420 *
3421 * Write a formatted DTD ATTLIST.
3422 *
3423 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3424 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003425int
3426xmlTextWriterWriteFormatDTDAttlist(xmlTextWriterPtr writer,
3427 const xmlChar * name,
3428 const char *format, ...)
3429{
3430 int rc;
3431 va_list ap;
3432
3433 va_start(ap, format);
3434
3435 rc = xmlTextWriterWriteVFormatDTDAttlist(writer, name, format, ap);
3436
3437 va_end(ap);
3438 return rc;
3439}
3440
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003441/**
3442 * xmlTextWriterWriteVFormatDTDAttlist:
3443 * @writer: the xmlTextWriterPtr
3444 * @name: the name of the DTD ATTLIST
3445 * @format: format string (see printf)
3446 * @argptr: pointer to the first member of the variable argument list.
3447 *
3448 * Write a formatted DTD ATTLIST.
3449 *
3450 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3451 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003452int
3453xmlTextWriterWriteVFormatDTDAttlist(xmlTextWriterPtr writer,
3454 const xmlChar * name,
3455 const char *format, va_list argptr)
3456{
3457 int rc;
3458 xmlChar *buf;
3459
3460 if (writer == NULL)
3461 return -1;
3462
3463 buf = xmlTextWriterVSprintf(format, argptr);
3464 if (buf == 0)
3465 return 0;
3466
3467 rc = xmlTextWriterWriteDTDAttlist(writer, name, buf);
3468
3469 xmlFree(buf);
3470 return rc;
3471}
3472
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003473/**
3474 * xmlTextWriterWriteDTDAttlist:
3475 * @writer: the xmlTextWriterPtr
3476 * @name: the name of the DTD ATTLIST
3477 * @content: content of the ATTLIST
3478 *
3479 * Write a DTD ATTLIST.
3480 *
3481 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3482 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003483int
3484xmlTextWriterWriteDTDAttlist(xmlTextWriterPtr writer,
3485 const xmlChar * name, const xmlChar * content)
3486{
3487 int count;
3488 int sum;
3489
3490 if (content == NULL)
3491 return -1;
3492
3493 sum = 0;
3494 count = xmlTextWriterStartDTDAttlist(writer, name);
3495 if (count == -1)
3496 return -1;
3497 sum += count;
3498
Daniel Veillard1d211e22003-10-20 22:32:39 +00003499 count = xmlTextWriterWriteString(writer, content);
3500 if (count == -1)
3501 return -1;
3502 sum += count;
3503
3504 count = xmlTextWriterEndDTDAttlist(writer);
3505 if (count == -1)
3506 return -1;
3507 sum += count;
3508
3509 return sum;
3510}
3511
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003512/**
3513 * xmlTextWriterStartDTDEntity:
3514 * @writer: the xmlTextWriterPtr
3515 * @pe: TRUE if this is a parameter entity, FALSE if not
3516 * @name: the name of the DTD ATTLIST
3517 *
3518 * Start an xml DTD ATTLIST.
3519 *
3520 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3521 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003522int
3523xmlTextWriterStartDTDEntity(xmlTextWriterPtr writer,
3524 int pe, const xmlChar * name)
3525{
3526 int count;
3527 int sum;
3528 xmlLinkPtr lk;
3529 xmlTextWriterStackEntry *p;
3530
3531 if (writer == NULL || name == NULL || *name == '\0')
3532 return -1;
3533
3534 sum = 0;
3535 lk = xmlListFront(writer->nodes);
Daniel Veillard500a1de2004-03-22 15:22:58 +00003536 if (lk != 0) {
Daniel Veillard1d211e22003-10-20 22:32:39 +00003537
Daniel Veillard500a1de2004-03-22 15:22:58 +00003538 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3539 if (p != 0) {
3540 switch (p->state) {
3541 case XML_TEXTWRITER_DTD:
3542 count = xmlOutputBufferWriteString(writer->out, " [");
3543 if (count < 0)
3544 return -1;
3545 sum += count;
3546 if (writer->indent) {
3547 count =
3548 xmlOutputBufferWriteString(writer->out, "\n");
3549 if (count < 0)
3550 return -1;
3551 sum += count;
3552 }
3553 p->state = XML_TEXTWRITER_DTD_TEXT;
3554 /* fallthrough */
3555 case XML_TEXTWRITER_DTD_TEXT:
3556 case XML_TEXTWRITER_NONE:
3557 break;
3558 default:
3559 return -1;
3560 }
3561 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00003562 }
3563
3564 p = (xmlTextWriterStackEntry *)
3565 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3566 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003567 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003568 "xmlTextWriterStartDTDElement : out of memory!\n");
3569 return -1;
3570 }
3571
3572 p->name = xmlStrdup(name);
3573 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003574 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003575 "xmlTextWriterStartDTDElement : out of memory!\n");
3576 xmlFree(p);
3577 return -1;
3578 }
Daniel Veillard500a1de2004-03-22 15:22:58 +00003579
3580 if (pe != 0)
3581 p->state = XML_TEXTWRITER_DTD_PENT;
3582 else
3583 p->state = XML_TEXTWRITER_DTD_ENTY;
Daniel Veillard1d211e22003-10-20 22:32:39 +00003584
3585 xmlListPushFront(writer->nodes, p);
3586
Daniel Veillard500a1de2004-03-22 15:22:58 +00003587 if (writer->indent) {
3588 count = xmlTextWriterWriteIndent(writer);
3589 if (count < 0)
3590 return -1;
3591 sum += count;
3592 }
3593
Daniel Veillard1d211e22003-10-20 22:32:39 +00003594 count = xmlOutputBufferWriteString(writer->out, "<!ENTITY ");
3595 if (count < 0)
3596 return -1;
3597 sum += count;
3598
3599 if (pe != 0) {
Daniel Veillard500a1de2004-03-22 15:22:58 +00003600 count = xmlOutputBufferWriteString(writer->out, "% ");
Daniel Veillard1d211e22003-10-20 22:32:39 +00003601 if (count < 0)
3602 return -1;
3603 sum += count;
3604 }
3605
Daniel Veillardab69f362004-02-17 11:40:32 +00003606 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003607 if (count < 0)
3608 return -1;
3609 sum += count;
3610
3611 return sum;
3612}
3613
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003614/**
Daniel Veillard500a1de2004-03-22 15:22:58 +00003615 * xmlTextWriterEndDTDEntity:
3616 * @writer: the xmlTextWriterPtr
3617 *
3618 * End an xml DTD entity.
3619 *
3620 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3621 */
3622int
3623xmlTextWriterEndDTDEntity(xmlTextWriterPtr writer)
3624{
3625 int count;
3626 int sum;
3627 xmlLinkPtr lk;
3628 xmlTextWriterStackEntry *p;
3629
3630 if (writer == NULL)
3631 return -1;
3632
3633 sum = 0;
3634 lk = xmlListFront(writer->nodes);
3635 if (lk == 0)
3636 return -1;
3637
3638 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3639 if (p == 0)
3640 return -1;
3641
3642 switch (p->state) {
3643 case XML_TEXTWRITER_DTD_ENTY_TEXT:
3644 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3645 if (count < 0)
3646 return -1;
3647 sum += count;
3648 case XML_TEXTWRITER_DTD_ENTY:
3649 case XML_TEXTWRITER_DTD_PENT:
Daniel Veillard500a1de2004-03-22 15:22:58 +00003650 count = xmlOutputBufferWriteString(writer->out, ">");
3651 if (count < 0)
3652 return -1;
3653 sum += count;
3654 break;
3655 default:
3656 return -1;
3657 }
3658
3659 if (writer->indent) {
3660 count = xmlOutputBufferWriteString(writer->out, "\n");
3661 if (count < 0)
3662 return -1;
3663 sum += count;
3664 }
3665
3666 xmlListPopFront(writer->nodes);
3667 return sum;
3668}
3669
3670/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003671 * xmlTextWriterWriteFormatDTDInternalEntity:
3672 * @writer: the xmlTextWriterPtr
3673 * @pe: TRUE if this is a parameter entity, FALSE if not
3674 * @name: the name of the DTD entity
3675 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003676 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003677 *
3678 * Write a formatted DTD internal entity.
3679 *
3680 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3681 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003682int
3683xmlTextWriterWriteFormatDTDInternalEntity(xmlTextWriterPtr writer,
3684 int pe,
3685 const xmlChar * name,
3686 const char *format, ...)
3687{
3688 int rc;
3689 va_list ap;
3690
3691 va_start(ap, format);
3692
3693 rc = xmlTextWriterWriteVFormatDTDInternalEntity(writer, pe, name,
3694 format, ap);
3695
3696 va_end(ap);
3697 return rc;
3698}
3699
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003700/**
3701 * xmlTextWriterWriteVFormatDTDInternalEntity:
3702 * @writer: the xmlTextWriterPtr
3703 * @pe: TRUE if this is a parameter entity, FALSE if not
3704 * @name: the name of the DTD entity
3705 * @format: format string (see printf)
3706 * @argptr: pointer to the first member of the variable argument list.
3707 *
3708 * Write a formatted DTD internal entity.
3709 *
3710 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3711 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003712int
3713xmlTextWriterWriteVFormatDTDInternalEntity(xmlTextWriterPtr writer,
3714 int pe,
3715 const xmlChar * name,
3716 const char *format,
3717 va_list argptr)
3718{
3719 int rc;
3720 xmlChar *buf;
3721
3722 if (writer == NULL)
3723 return -1;
3724
3725 buf = xmlTextWriterVSprintf(format, argptr);
3726 if (buf == 0)
3727 return 0;
3728
3729 rc = xmlTextWriterWriteDTDInternalEntity(writer, pe, name, buf);
3730
3731 xmlFree(buf);
3732 return rc;
3733}
3734
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003735/**
3736 * xmlTextWriterWriteDTDEntity:
3737 * @writer: the xmlTextWriterPtr
3738 * @pe: TRUE if this is a parameter entity, FALSE if not
3739 * @name: the name of the DTD entity
3740 * @pubid: the public identifier, which is an alternative to the system identifier
3741 * @sysid: the system identifier, which is the URI of the DTD
3742 * @ndataid: the xml notation name.
3743 * @content: content of the entity
3744 *
3745 * Write a DTD entity.
3746 *
3747 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3748 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003749int
3750xmlTextWriterWriteDTDEntity(xmlTextWriterPtr writer,
3751 int pe,
3752 const xmlChar * name,
3753 const xmlChar * pubid,
3754 const xmlChar * sysid,
3755 const xmlChar * ndataid,
3756 const xmlChar * content)
3757{
Daniel Veillard500a1de2004-03-22 15:22:58 +00003758 if ((content == NULL) && (pubid == NULL) && (sysid == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00003759 return -1;
3760 if ((pe != 0) && (ndataid != NULL))
3761 return -1;
3762
Daniel Veillard500a1de2004-03-22 15:22:58 +00003763 if ((pubid == NULL) && (sysid == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00003764 return xmlTextWriterWriteDTDInternalEntity(writer, pe, name,
3765 content);
3766
3767 return xmlTextWriterWriteDTDExternalEntity(writer, pe, name, pubid,
3768 sysid, ndataid);
3769}
3770
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003771/**
3772 * xmlTextWriterWriteDTDInternalEntity:
3773 * @writer: the xmlTextWriterPtr
3774 * @pe: TRUE if this is a parameter entity, FALSE if not
3775 * @name: the name of the DTD entity
3776 * @content: content of the entity
3777 *
3778 * Write a DTD internal entity.
3779 *
3780 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3781 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003782int
3783xmlTextWriterWriteDTDInternalEntity(xmlTextWriterPtr writer,
3784 int pe,
3785 const xmlChar * name,
3786 const xmlChar * content)
3787{
3788 int count;
3789 int sum;
3790
3791 if ((name == NULL) || (*name == '\0') || (content == NULL))
3792 return -1;
3793
3794 sum = 0;
3795 count = xmlTextWriterStartDTDEntity(writer, pe, name);
3796 if (count == -1)
3797 return -1;
3798 sum += count;
3799
Daniel Veillard1d211e22003-10-20 22:32:39 +00003800 count = xmlTextWriterWriteString(writer, content);
3801 if (count == -1)
3802 return -1;
3803 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00003804
3805 count = xmlTextWriterEndDTDEntity(writer);
3806 if (count == -1)
3807 return -1;
3808 sum += count;
3809
3810 return sum;
3811}
3812
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003813/**
3814 * xmlTextWriterWriteDTDExternalEntity:
3815 * @writer: the xmlTextWriterPtr
3816 * @pe: TRUE if this is a parameter entity, FALSE if not
3817 * @name: the name of the DTD entity
3818 * @pubid: the public identifier, which is an alternative to the system identifier
3819 * @sysid: the system identifier, which is the URI of the DTD
3820 * @ndataid: the xml notation name.
3821 *
Daniel Veillard500a1de2004-03-22 15:22:58 +00003822 * Write a DTD external entity. The entity must have been started with xmlTextWriterStartDTDEntity
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003823 *
3824 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3825 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003826int
3827xmlTextWriterWriteDTDExternalEntity(xmlTextWriterPtr writer,
3828 int pe,
3829 const xmlChar * name,
3830 const xmlChar * pubid,
3831 const xmlChar * sysid,
3832 const xmlChar * ndataid)
3833{
3834 int count;
3835 int sum;
3836
Daniel Veillard500a1de2004-03-22 15:22:58 +00003837 if (((pubid == NULL) && (sysid == NULL)))
Daniel Veillard1d211e22003-10-20 22:32:39 +00003838 return -1;
3839 if ((pe != 0) && (ndataid != NULL))
3840 return -1;
3841
3842 sum = 0;
3843 count = xmlTextWriterStartDTDEntity(writer, pe, name);
3844 if (count == -1)
3845 return -1;
3846 sum += count;
3847
Daniel Veillard500a1de2004-03-22 15:22:58 +00003848 count =
3849 xmlTextWriterWriteDTDExternalEntityContents(writer, pubid, sysid,
3850 ndataid);
3851 if (count < 0)
3852 return -1;
3853 sum += count;
3854
3855 count = xmlTextWriterEndDTDEntity(writer);
3856 if (count == -1)
3857 return -1;
3858 sum += count;
3859
3860 return sum;
3861}
3862
3863/**
3864 * xmlTextWriterWriteDTDExternalEntityContents:
3865 * @writer: the xmlTextWriterPtr
3866 * @pubid: the public identifier, which is an alternative to the system identifier
3867 * @sysid: the system identifier, which is the URI of the DTD
3868 * @ndataid: the xml notation name.
3869 *
3870 * Write the contents of a DTD external entity.
3871 *
3872 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3873 */
3874int
3875xmlTextWriterWriteDTDExternalEntityContents(xmlTextWriterPtr writer,
3876 const xmlChar * pubid,
3877 const xmlChar * sysid,
3878 const xmlChar * ndataid)
3879{
3880 int count;
3881 int sum;
3882 xmlLinkPtr lk;
3883 xmlTextWriterStackEntry *p;
3884
3885 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003886 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003887 "xmlTextWriterWriteDTDExternalEntityContents: xmlTextWriterPtr invalid!\n");
3888 return -1;
3889 }
3890
3891 sum = 0;
3892 lk = xmlListFront(writer->nodes);
3893 if (lk == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003894 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003895 "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n");
3896 return -1;
3897 }
3898
3899 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3900 if (p == 0)
3901 return -1;
3902
3903 switch (p->state) {
3904 case XML_TEXTWRITER_DTD_ENTY:
3905 break;
3906 case XML_TEXTWRITER_DTD_PENT:
3907 if (ndataid != NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003908 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003909 "xmlTextWriterWriteDTDExternalEntityContents: notation not allowed with parameter entities!\n");
3910 return -1;
3911 }
3912 break;
3913 default:
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003914 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003915 "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n");
3916 return -1;
3917 }
3918
Daniel Veillard1d211e22003-10-20 22:32:39 +00003919 if (pubid != 0) {
3920 if (sysid == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003921 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003922 "xmlTextWriterWriteDTDExternalEntityContents: system identifier needed!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +00003923 return -1;
3924 }
3925
3926 count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
3927 if (count < 0)
3928 return -1;
3929 sum += count;
3930
3931 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3932 if (count < 0)
3933 return -1;
3934 sum += count;
3935
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003936 count =
3937 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003938 if (count < 0)
3939 return -1;
3940 sum += count;
3941
3942 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3943 if (count < 0)
3944 return -1;
3945 sum += count;
3946 }
3947
3948 if (sysid != 0) {
3949 if (pubid == 0) {
3950 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
3951 if (count < 0)
3952 return -1;
3953 sum += count;
3954 }
3955
3956 count = xmlOutputBufferWriteString(writer->out, " ");
3957 if (count < 0)
3958 return -1;
3959 sum += count;
3960
3961 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3962 if (count < 0)
3963 return -1;
3964 sum += count;
3965
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003966 count =
3967 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003968 if (count < 0)
3969 return -1;
3970 sum += count;
3971
3972 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3973 if (count < 0)
3974 return -1;
3975 sum += count;
3976 }
3977
3978 if (ndataid != NULL) {
3979 count = xmlOutputBufferWriteString(writer->out, " NDATA ");
3980 if (count < 0)
3981 return -1;
3982 sum += count;
3983
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003984 count =
3985 xmlOutputBufferWriteString(writer->out,
3986 (const char *) ndataid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003987 if (count < 0)
3988 return -1;
3989 sum += count;
3990 }
3991
Daniel Veillard1d211e22003-10-20 22:32:39 +00003992 return sum;
3993}
3994
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003995/**
3996 * xmlTextWriterWriteDTDNotation:
3997 * @writer: the xmlTextWriterPtr
3998 * @name: the name of the xml notation
3999 * @pubid: the public identifier, which is an alternative to the system identifier
4000 * @sysid: the system identifier, which is the URI of the DTD
4001 *
4002 * Write a DTD entity.
4003 *
4004 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
4005 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00004006int
4007xmlTextWriterWriteDTDNotation(xmlTextWriterPtr writer,
4008 const xmlChar * name,
4009 const xmlChar * pubid, const xmlChar * sysid)
4010{
4011 int count;
4012 int sum;
4013 xmlLinkPtr lk;
4014 xmlTextWriterStackEntry *p;
4015
4016 if (writer == NULL || name == NULL || *name == '\0')
4017 return -1;
4018
4019 sum = 0;
4020 lk = xmlListFront(writer->nodes);
4021 if (lk == 0) {
4022 return -1;
4023 }
4024
4025 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
Daniel Veillard500a1de2004-03-22 15:22:58 +00004026 if (p != 0) {
4027 switch (p->state) {
4028 case XML_TEXTWRITER_DTD:
4029 count = xmlOutputBufferWriteString(writer->out, " [");
4030 if (count < 0)
4031 return -1;
4032 sum += count;
4033 if (writer->indent) {
4034 count = xmlOutputBufferWriteString(writer->out, "\n");
4035 if (count < 0)
4036 return -1;
4037 sum += count;
4038 }
4039 p->state = XML_TEXTWRITER_DTD_TEXT;
4040 /* fallthrough */
4041 case XML_TEXTWRITER_DTD_TEXT:
4042 break;
4043 default:
4044 return -1;
4045 }
4046 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00004047
Daniel Veillard500a1de2004-03-22 15:22:58 +00004048 if (writer->indent) {
4049 count = xmlTextWriterWriteIndent(writer);
4050 if (count < 0)
Daniel Veillard1d211e22003-10-20 22:32:39 +00004051 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00004052 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00004053 }
4054
4055 count = xmlOutputBufferWriteString(writer->out, "<!NOTATION ");
4056 if (count < 0)
4057 return -1;
4058 sum += count;
4059 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
4060 if (count < 0)
4061 return -1;
4062 sum += count;
4063
4064 if (pubid != 0) {
4065 count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
4066 if (count < 0)
4067 return -1;
4068 sum += count;
4069 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4070 if (count < 0)
4071 return -1;
4072 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004073 count =
4074 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004075 if (count < 0)
4076 return -1;
4077 sum += count;
4078 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4079 if (count < 0)
4080 return -1;
4081 sum += count;
4082 }
4083
4084 if (sysid != 0) {
4085 if (pubid == 0) {
4086 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
4087 if (count < 0)
4088 return -1;
4089 sum += count;
4090 }
4091 count = xmlOutputBufferWriteString(writer->out, " ");
4092 if (count < 0)
4093 return -1;
4094 sum += count;
4095 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4096 if (count < 0)
4097 return -1;
4098 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004099 count =
4100 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004101 if (count < 0)
4102 return -1;
4103 sum += count;
4104 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4105 if (count < 0)
4106 return -1;
4107 sum += count;
4108 }
4109
4110 count = xmlOutputBufferWriteString(writer->out, ">");
4111 if (count < 0)
4112 return -1;
4113 sum += count;
4114
4115 return sum;
4116}
4117
4118/**
4119 * xmlTextWriterFlush:
4120 * @writer: the xmlTextWriterPtr
4121 *
4122 * Flush the output buffer.
4123 *
4124 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
4125 */
4126int
4127xmlTextWriterFlush(xmlTextWriterPtr writer)
4128{
4129 int count;
4130
4131 if (writer == NULL)
4132 return -1;
4133
4134 if (writer->out == NULL)
4135 count = 0;
4136 else
4137 count = xmlOutputBufferFlush(writer->out);
4138
4139 return count;
4140}
4141
4142/**
4143 * misc
4144 */
4145
4146/**
4147 * xmlFreeTextWriterStackEntry:
4148 * @lk: the xmlLinkPtr
4149 *
4150 * Free callback for the xmlList.
4151 */
4152static void
4153xmlFreeTextWriterStackEntry(xmlLinkPtr lk)
4154{
4155 xmlTextWriterStackEntry *p;
4156
4157 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
4158 if (p == 0)
4159 return;
4160
4161 if (p->name != 0)
4162 xmlFree(p->name);
4163 xmlFree(p);
4164}
4165
4166/**
4167 * xmlCmpTextWriterStackEntry:
4168 * @data0: the first data
4169 * @data1: the second data
4170 *
4171 * Compare callback for the xmlList.
4172 *
4173 * Returns -1, 0, 1
4174 */
4175static int
4176xmlCmpTextWriterStackEntry(const void *data0, const void *data1)
4177{
4178 xmlTextWriterStackEntry *p0;
4179 xmlTextWriterStackEntry *p1;
4180
4181 if (data0 == data1)
4182 return 0;
4183
4184 if (data0 == 0)
4185 return -1;
4186
4187 if (data1 == 0)
4188 return 1;
4189
4190 p0 = (xmlTextWriterStackEntry *) data0;
4191 p1 = (xmlTextWriterStackEntry *) data1;
4192
4193 return xmlStrcmp(p0->name, p1->name);
4194}
4195
4196/**
4197 * misc
4198 */
4199
4200/**
4201 * xmlFreeTextWriterNsStackEntry:
4202 * @lk: the xmlLinkPtr
4203 *
4204 * Free callback for the xmlList.
4205 */
4206static void
4207xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk)
4208{
4209 xmlTextWriterNsStackEntry *p;
4210
4211 p = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
4212 if (p == 0)
4213 return;
4214
4215 if (p->prefix != 0)
4216 xmlFree(p->prefix);
4217 if (p->uri != 0)
4218 xmlFree(p->uri);
4219
4220 xmlFree(p);
4221}
4222
4223/**
4224 * xmlCmpTextWriterNsStackEntry:
4225 * @data0: the first data
4226 * @data1: the second data
4227 *
4228 * Compare callback for the xmlList.
4229 *
4230 * Returns -1, 0, 1
4231 */
4232static int
4233xmlCmpTextWriterNsStackEntry(const void *data0, const void *data1)
4234{
4235 xmlTextWriterNsStackEntry *p0;
4236 xmlTextWriterNsStackEntry *p1;
4237 int rc;
4238
4239 if (data0 == data1)
4240 return 0;
4241
4242 if (data0 == 0)
4243 return -1;
4244
4245 if (data1 == 0)
4246 return 1;
4247
4248 p0 = (xmlTextWriterNsStackEntry *) data0;
4249 p1 = (xmlTextWriterNsStackEntry *) data1;
4250
4251 rc = xmlStrcmp(p0->prefix, p1->prefix);
4252
4253 if (rc == 0)
4254 rc = p0->elem == p1->elem;
4255
4256 return rc;
4257}
4258
4259/**
4260 * xmlTextWriterWriteMemCallback:
4261 * @context: the xmlBufferPtr
4262 * @str: the data to write
4263 * @len: the length of the data
4264 *
4265 * Write callback for the xmlOutputBuffer with target xmlBuffer
4266 *
4267 * Returns -1, 0, 1
4268 */
4269static int
4270xmlTextWriterWriteMemCallback(void *context, const xmlChar * str, int len)
4271{
4272 xmlBufferPtr buf = (xmlBufferPtr) context;
4273
4274 xmlBufferAdd(buf, str, len);
4275
4276 return len;
4277}
4278
4279/**
4280 * xmlTextWriterCloseMemCallback:
4281 * @context: the xmlBufferPtr
4282 *
4283 * Close callback for the xmlOutputBuffer with target xmlBuffer
4284 *
4285 * Returns -1, 0, 1
4286 */
4287static int
4288xmlTextWriterCloseMemCallback(void *context ATTRIBUTE_UNUSED)
4289{
4290 return 0;
4291}
4292
4293/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004294 * xmlTextWriterWriteDocCallback:
4295 * @context: the xmlBufferPtr
4296 * @str: the data to write
4297 * @len: the length of the data
4298 *
4299 * Write callback for the xmlOutputBuffer with target xmlBuffer
4300 *
4301 * Returns -1, 0, 1
4302 */
4303static int
4304xmlTextWriterWriteDocCallback(void *context, const xmlChar * str, int len)
4305{
4306 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context;
4307 int rc;
4308
Daniel Veillard1d913862003-11-21 00:28:39 +00004309 if ((rc = xmlParseChunk(ctxt, (const char *) str, len, 0)) != 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004310 xmlWriterErrMsgInt(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004311 "xmlTextWriterWriteDocCallback : XML error %d !\n",
4312 rc);
4313 return -1;
4314 }
4315
4316 return len;
4317}
4318
4319/**
4320 * xmlTextWriterCloseDocCallback:
4321 * @context: the xmlBufferPtr
4322 *
4323 * Close callback for the xmlOutputBuffer with target xmlBuffer
4324 *
4325 * Returns -1, 0, 1
4326 */
4327static int
4328xmlTextWriterCloseDocCallback(void *context)
4329{
4330 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context;
4331 int rc;
4332
4333 if ((rc = xmlParseChunk(ctxt, NULL, 0, 1)) != 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004334 xmlWriterErrMsgInt(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004335 "xmlTextWriterWriteDocCallback : XML error %d !\n",
4336 rc);
4337 return -1;
4338 }
4339
4340 return 0;
4341}
4342
4343/**
Daniel Veillard1d211e22003-10-20 22:32:39 +00004344 * xmlTextWriterVSprintf:
4345 * @format: see printf
4346 * @argptr: pointer to the first member of the variable argument list.
4347 *
4348 * Utility function for formatted output
4349 *
4350 * Returns a new xmlChar buffer with the data or NULL on error. This buffer must be freed.
4351 */
4352static xmlChar *
4353xmlTextWriterVSprintf(const char *format, va_list argptr)
4354{
4355 int size;
4356 int count;
4357 xmlChar *buf;
4358
4359 size = BUFSIZ;
4360 buf = (xmlChar *) xmlMalloc(size);
4361 if (buf == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004362 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00004363 "xmlTextWriterVSprintf : out of memory!\n");
4364 return NULL;
4365 }
4366
4367 while (((count = vsnprintf((char *) buf, size, format, argptr)) < 0)
4368 || (count == size - 1) || (count == size) || (count > size)) {
4369 xmlFree(buf);
4370 size += BUFSIZ;
4371 buf = (xmlChar *) xmlMalloc(size);
4372 if (buf == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004373 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00004374 "xmlTextWriterVSprintf : out of memory!\n");
4375 return NULL;
4376 }
4377 }
4378
4379 return buf;
4380}
4381
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004382/**
4383 * xmlTextWriterStartDocumentCallback:
4384 * @ctx: the user data (XML parser context)
4385 *
4386 * called at the start of document processing.
4387 */
4388static void
4389xmlTextWriterStartDocumentCallback(void *ctx)
4390{
4391 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
4392 xmlDocPtr doc;
4393
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004394 if (ctxt->html) {
4395#ifdef LIBXML_HTML_ENABLED
4396 if (ctxt->myDoc == NULL)
4397 ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
4398 if (ctxt->myDoc == NULL) {
4399 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
4400 ctxt->sax->error(ctxt->userData,
4401 "SAX.startDocument(): out of memory\n");
4402 ctxt->errNo = XML_ERR_NO_MEMORY;
4403 ctxt->instate = XML_PARSER_EOF;
4404 ctxt->disableSAX = 1;
4405 return;
4406 }
4407#else
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004408 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004409 "libxml2 built without HTML support\n");
4410 ctxt->errNo = XML_ERR_INTERNAL_ERROR;
4411 ctxt->instate = XML_PARSER_EOF;
4412 ctxt->disableSAX = 1;
4413 return;
4414#endif
4415 } else {
4416 doc = ctxt->myDoc;
4417 if (doc == NULL)
4418 doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
4419 if (doc != NULL) {
4420 if (doc->children == NULL) {
4421 if (ctxt->encoding != NULL)
4422 doc->encoding = xmlStrdup(ctxt->encoding);
4423 else
4424 doc->encoding = NULL;
4425 doc->standalone = ctxt->standalone;
4426 }
4427 } else {
4428 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
4429 ctxt->sax->error(ctxt->userData,
4430 "SAX.startDocument(): out of memory\n");
4431 ctxt->errNo = XML_ERR_NO_MEMORY;
4432 ctxt->instate = XML_PARSER_EOF;
4433 ctxt->disableSAX = 1;
4434 return;
4435 }
4436 }
4437 if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) &&
4438 (ctxt->input != NULL) && (ctxt->input->filename != NULL)) {
4439 ctxt->myDoc->URL =
4440 xmlCanonicPath((const xmlChar *) ctxt->input->filename);
4441 if (ctxt->myDoc->URL == NULL)
4442 ctxt->myDoc->URL =
4443 xmlStrdup((const xmlChar *) ctxt->input->filename);
4444 }
4445}
4446
Daniel Veillard2cca4462004-01-02 20:04:23 +00004447/**
4448 * xmlTextWriterSetIndent:
4449 * @writer: the xmlTextWriterPtr
4450 * @indent: do indentation?
4451 *
4452 * Set indentation output. indent = 0 do not indentation. indent > 0 do indentation.
4453 *
4454 * Returns -1 on error or 0 otherwise.
4455 */
4456int
Daniel Veillardab69f362004-02-17 11:40:32 +00004457xmlTextWriterSetIndent(xmlTextWriterPtr writer, int indent)
Daniel Veillard2cca4462004-01-02 20:04:23 +00004458{
Daniel Veillarde43cc572004-11-03 11:50:29 +00004459 if ((writer == NULL) || (indent < 0))
Daniel Veillardab69f362004-02-17 11:40:32 +00004460 return -1;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004461
Daniel Veillardab69f362004-02-17 11:40:32 +00004462 writer->indent = indent;
4463 writer->doindent = 1;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004464
Daniel Veillardab69f362004-02-17 11:40:32 +00004465 return 0;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004466}
4467
4468/**
4469 * xmlTextWriterSetIndentString:
4470 * @writer: the xmlTextWriterPtr
4471 * @str: the xmlChar string
4472 *
4473 * Set string indentation.
4474 *
4475 * Returns -1 on error or 0 otherwise.
4476 */
4477int
Daniel Veillardab69f362004-02-17 11:40:32 +00004478xmlTextWriterSetIndentString(xmlTextWriterPtr writer, const xmlChar * str)
Daniel Veillard2cca4462004-01-02 20:04:23 +00004479{
Daniel Veillarde43cc572004-11-03 11:50:29 +00004480 if ((writer == NULL) || (!str))
Daniel Veillardab69f362004-02-17 11:40:32 +00004481 return -1;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004482
Daniel Veillardab69f362004-02-17 11:40:32 +00004483 if (writer->ichar != NULL)
4484 xmlFree(writer->ichar);
4485 writer->ichar = xmlStrdup(str);
4486
4487 if (!writer->ichar)
4488 return -1;
4489 else
4490 return 0;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004491}
4492
4493/**
4494 * xmlTextWriterWriteIndent:
4495 * @writer: the xmlTextWriterPtr
4496 *
4497 * Write indent string.
4498 *
4499 * Returns -1 on error or the number of strings written.
Daniel Veillardab69f362004-02-17 11:40:32 +00004500 */
Daniel Veillard2cca4462004-01-02 20:04:23 +00004501static int
Daniel Veillardab69f362004-02-17 11:40:32 +00004502xmlTextWriterWriteIndent(xmlTextWriterPtr writer)
Daniel Veillard2cca4462004-01-02 20:04:23 +00004503{
Daniel Veillardab69f362004-02-17 11:40:32 +00004504 int lksize;
4505 int i;
4506 int ret;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004507
Daniel Veillardab69f362004-02-17 11:40:32 +00004508 lksize = xmlListSize(writer->nodes);
4509 if (lksize < 1)
4510 return (-1); /* list is empty */
4511 for (i = 0; i < (lksize - 1); i++) {
4512 ret = xmlOutputBufferWriteString(writer->out,
4513 (const char *) writer->ichar);
4514 if (ret == -1)
4515 return (-1);
4516 }
4517
4518 return (lksize - 1);
Daniel Veillard2cca4462004-01-02 20:04:23 +00004519}
4520
Daniel Veillard500a1de2004-03-22 15:22:58 +00004521/**
4522 * xmlTextWriterHandleStateDependencies:
4523 * @writer: the xmlTextWriterPtr
4524 * @p: the xmlTextWriterStackEntry
4525 *
4526 * Write state dependent strings.
4527 *
4528 * Returns -1 on error or the number of characters written.
4529 */
4530static int
4531xmlTextWriterHandleStateDependencies(xmlTextWriterPtr writer,
4532 xmlTextWriterStackEntry * p)
4533{
4534 int count;
4535 int sum;
4536 char extra[3];
4537
4538 if (writer == NULL)
4539 return -1;
4540
4541 if (p == NULL)
4542 return 0;
4543
4544 sum = 0;
4545 extra[0] = extra[1] = extra[2] = '\0';
4546 if (p != 0) {
4547 sum = 0;
4548 switch (p->state) {
4549 case XML_TEXTWRITER_NAME:
4550 extra[0] = '>';
4551 p->state = XML_TEXTWRITER_TEXT;
4552 break;
4553 case XML_TEXTWRITER_PI:
4554 extra[0] = ' ';
4555 p->state = XML_TEXTWRITER_PI_TEXT;
4556 break;
4557 case XML_TEXTWRITER_DTD:
4558 extra[0] = ' ';
4559 extra[1] = '[';
4560 p->state = XML_TEXTWRITER_DTD_TEXT;
4561 break;
4562 case XML_TEXTWRITER_DTD_ELEM:
4563 extra[0] = ' ';
4564 p->state = XML_TEXTWRITER_DTD_ELEM_TEXT;
4565 break;
4566 case XML_TEXTWRITER_DTD_ATTL:
4567 extra[0] = ' ';
4568 p->state = XML_TEXTWRITER_DTD_ATTL_TEXT;
4569 break;
4570 case XML_TEXTWRITER_DTD_ENTY:
4571 case XML_TEXTWRITER_DTD_PENT:
4572 extra[0] = ' ';
4573 extra[1] = writer->qchar;
4574 p->state = XML_TEXTWRITER_DTD_ENTY_TEXT;
4575 break;
4576 default:
4577 break;
4578 }
4579 }
4580
4581 if (*extra != '\0') {
4582 count = xmlOutputBufferWriteString(writer->out, extra);
4583 if (count < 0)
4584 return -1;
4585 sum += count;
4586 }
4587
4588 return sum;
4589}
4590
Daniel Veillard1d211e22003-10-20 22:32:39 +00004591#endif