blob: 4b2c3e111120698fae28c8e250f922dc14185b3d [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 Veillard1d211e22003-10-20 22:32:39 +000074};
75
76static void xmlFreeTextWriterStackEntry(xmlLinkPtr lk);
77static int xmlCmpTextWriterStackEntry(const void *data0,
78 const void *data1);
79static void xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk);
80static int xmlCmpTextWriterNsStackEntry(const void *data0,
81 const void *data1);
82static int xmlTextWriterWriteMemCallback(void *context,
83 const xmlChar * str, int len);
84static int xmlTextWriterCloseMemCallback(void *context);
Daniel Veillard5841f0e2003-11-20 11:59:09 +000085static int xmlTextWriterWriteDocCallback(void *context,
86 const xmlChar * str, int len);
87static int xmlTextWriterCloseDocCallback(void *context);
88
Daniel Veillard1d211e22003-10-20 22:32:39 +000089static xmlChar *xmlTextWriterVSprintf(const char *format, va_list argptr);
90static int xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len,
91 const unsigned char *data);
Daniel Veillard5841f0e2003-11-20 11:59:09 +000092static void xmlTextWriterStartDocumentCallback(void *ctx);
Daniel Veillardab69f362004-02-17 11:40:32 +000093static int xmlTextWriterWriteIndent(xmlTextWriterPtr writer);
Daniel Veillard500a1de2004-03-22 15:22:58 +000094static int
95 xmlTextWriterHandleStateDependencies(xmlTextWriterPtr writer,
96 xmlTextWriterStackEntry * p);
Daniel Veillard1d211e22003-10-20 22:32:39 +000097
98/**
Daniel Veillarddd6d3002004-11-03 14:20:29 +000099 * xmlWriterErrMsg:
100 * @ctxt: a writer context
101 * @error: the error number
102 * @msg: the error message
103 *
104 * Handle a writer error
105 */
106static void
107xmlWriterErrMsg(xmlTextWriterPtr ctxt, xmlParserErrors error,
108 const char *msg)
109{
110 if (ctxt != NULL) {
111 __xmlRaiseError(NULL, NULL, NULL, ctxt->ctxt,
112 NULL, XML_FROM_WRITER, error, XML_ERR_FATAL,
113 NULL, 0, NULL, NULL, NULL, 0, 0, msg);
114 } else {
115 __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_WRITER, error,
116 XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, 0, 0, msg);
117 }
118}
119
120/**
121 * xmlWriterErrMsgInt:
122 * @ctxt: a writer context
123 * @error: the error number
124 * @msg: the error message
125 * @val: an int
126 *
127 * Handle a writer error
128 */
129static void
130xmlWriterErrMsgInt(xmlTextWriterPtr ctxt, xmlParserErrors error,
131 const char *msg, int val)
132{
133 if (ctxt != NULL) {
134 __xmlRaiseError(NULL, NULL, NULL, ctxt->ctxt,
135 NULL, XML_FROM_WRITER, error, XML_ERR_FATAL,
136 NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
137 } else {
138 __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_WRITER, error,
139 XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
140 }
141}
142
143/**
Daniel Veillard1d211e22003-10-20 22:32:39 +0000144 * xmlNewTextWriter:
145 * @out: an xmlOutputBufferPtr
146 *
147 * Create a new xmlNewTextWriter structure using an xmlOutputBufferPtr
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000148 * NOTE: the @out parameter will be deallocated when the writer is closed
149 * (if the call succeed.)
Daniel Veillard1d211e22003-10-20 22:32:39 +0000150 *
151 * Returns the new xmlTextWriterPtr or NULL in case of error
152 */
153xmlTextWriterPtr
154xmlNewTextWriter(xmlOutputBufferPtr out)
155{
156 xmlTextWriterPtr ret;
157
158 ret = (xmlTextWriterPtr) xmlMalloc(sizeof(xmlTextWriter));
159 if (ret == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000160 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000161 "xmlNewTextWriter : out of memory!\n");
162 return NULL;
163 }
164 memset(ret, 0, (size_t) sizeof(xmlTextWriter));
165
166 ret->nodes = xmlListCreate((xmlListDeallocator)
167 xmlFreeTextWriterStackEntry,
168 (xmlListDataCompare)
169 xmlCmpTextWriterStackEntry);
170 if (ret->nodes == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000171 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000172 "xmlNewTextWriter : out of memory!\n");
173 xmlFree(ret);
174 return NULL;
175 }
176
177 ret->nsstack = xmlListCreate((xmlListDeallocator)
178 xmlFreeTextWriterNsStackEntry,
179 (xmlListDataCompare)
180 xmlCmpTextWriterNsStackEntry);
181 if (ret->nsstack == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000182 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000183 "xmlNewTextWriter : out of memory!\n");
Daniel Veillard500a1de2004-03-22 15:22:58 +0000184 xmlListDelete(ret->nodes);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000185 xmlFree(ret);
186 return NULL;
187 }
188
189 ret->out = out;
Daniel Veillardab69f362004-02-17 11:40:32 +0000190 ret->ichar = xmlStrdup(BAD_CAST " ");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000191 ret->qchar = '"';
192
Daniel Veillard500a1de2004-03-22 15:22:58 +0000193 if (!ret->ichar) {
194 xmlListDelete(ret->nodes);
195 xmlListDelete(ret->nsstack);
196 xmlFree(ret);
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000197 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000198 "xmlNewTextWriter : out of memory!\n");
Daniel Veillardab69f362004-02-17 11:40:32 +0000199 return NULL;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000200 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000201
Daniel Veillard1d211e22003-10-20 22:32:39 +0000202 return ret;
203}
204
205/**
206 * xmlNewTextWriterFilename:
207 * @uri: the URI of the resource for the output
208 * @compression: compress the output?
209 *
210 * Create a new xmlNewTextWriter structure with @uri as output
211 *
212 * Returns the new xmlTextWriterPtr or NULL in case of error
213 */
214xmlTextWriterPtr
215xmlNewTextWriterFilename(const char *uri, int compression)
216{
217 xmlTextWriterPtr ret;
218 xmlOutputBufferPtr out;
219
220 out = xmlOutputBufferCreateFilename(uri, NULL, compression);
221 if (out == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000222 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000223 "xmlNewTextWriterFilename : out of memory!\n");
224 return NULL;
225 }
226
227 ret = xmlNewTextWriter(out);
228 if (ret == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000229 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000230 "xmlNewTextWriterFilename : out of memory!\n");
231 xmlOutputBufferClose(out);
232 return NULL;
233 }
234
Daniel Veillard2cca4462004-01-02 20:04:23 +0000235 ret->indent = 0;
236 ret->doindent = 0;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000237 return ret;
238}
239
240/**
241 * xmlNewTextWriterMemory:
242 * @buf: xmlBufferPtr
243 * @compression: compress the output?
244 *
245 * Create a new xmlNewTextWriter structure with @buf as output
246 * TODO: handle compression
247 *
248 * Returns the new xmlTextWriterPtr or NULL in case of error
249 */
250xmlTextWriterPtr
251xmlNewTextWriterMemory(xmlBufferPtr buf, int compression ATTRIBUTE_UNUSED)
252{
253 xmlTextWriterPtr ret;
254 xmlOutputBufferPtr out;
255
256/*::todo handle compression */
257 out = xmlOutputBufferCreateIO((xmlOutputWriteCallback)
258 xmlTextWriterWriteMemCallback,
259 (xmlOutputCloseCallback)
260 xmlTextWriterCloseMemCallback,
261 (void *) buf, NULL);
262 if (out == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000263 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000264 "xmlNewTextWriterMemory : out of memory!\n");
265 return NULL;
266 }
267
268 ret = xmlNewTextWriter(out);
269 if (ret == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000270 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000271 "xmlNewTextWriterMemory : out of memory!\n");
272 xmlOutputBufferClose(out);
273 return NULL;
274 }
275
276 return ret;
277}
278
279/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000280 * xmlNewTextWriterPushParser:
281 * @ctxt: xmlParserCtxtPtr to hold the new XML document tree
282 * @compression: compress the output?
283 *
284 * Create a new xmlNewTextWriter structure with @ctxt as output
Daniel Veillardd5cc0f72004-11-06 19:24:28 +0000285 * NOTE: the @ctxt context will be freed with the resulting writer
286 * (if the call succeeds).
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000287 * TODO: handle compression
288 *
289 * Returns the new xmlTextWriterPtr or NULL in case of error
290 */
291xmlTextWriterPtr
Daniel Veillard1d913862003-11-21 00:28:39 +0000292xmlNewTextWriterPushParser(xmlParserCtxtPtr ctxt,
293 int compression ATTRIBUTE_UNUSED)
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000294{
295 xmlTextWriterPtr ret;
296 xmlOutputBufferPtr out;
297
Daniel Veillard500a1de2004-03-22 15:22:58 +0000298 if (ctxt == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000299 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000300 "xmlNewTextWriterPushParser : invalid context!\n");
301 return NULL;
302 }
303
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000304 out = xmlOutputBufferCreateIO((xmlOutputWriteCallback)
305 xmlTextWriterWriteDocCallback,
306 (xmlOutputCloseCallback)
307 xmlTextWriterCloseDocCallback,
308 (void *) ctxt, NULL);
309 if (out == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000310 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000311 "xmlNewTextWriterPushParser : error at xmlOutputBufferCreateIO!\n");
312 return NULL;
313 }
314
315 ret = xmlNewTextWriter(out);
316 if (ret == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000317 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000318 "xmlNewTextWriterPushParser : error at xmlNewTextWriter!\n");
319 xmlOutputBufferClose(out);
320 return NULL;
321 }
322
Daniel Veillard20c5e782004-01-21 09:57:31 +0000323 ret->ctxt = ctxt;
324
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000325 return ret;
326}
327
328/**
329 * xmlNewTextWriterDoc:
330 * @doc: address of a xmlDocPtr to hold the new XML document tree
331 * @compression: compress the output?
332 *
333 * Create a new xmlNewTextWriter structure with @*doc as output
334 *
335 * Returns the new xmlTextWriterPtr or NULL in case of error
336 */
337xmlTextWriterPtr
338xmlNewTextWriterDoc(xmlDocPtr * doc, int compression)
339{
340 xmlTextWriterPtr ret;
341 xmlSAXHandler saxHandler;
342 xmlParserCtxtPtr ctxt;
343
344 memset(&saxHandler, '\0', sizeof(saxHandler));
345 xmlSAX2InitDefaultSAXHandler(&saxHandler, 1);
346 saxHandler.startDocument = xmlTextWriterStartDocumentCallback;
347 saxHandler.startElement = xmlSAX2StartElement;
348 saxHandler.endElement = xmlSAX2EndElement;
349
350 ctxt = xmlCreatePushParserCtxt(&saxHandler, NULL, NULL, 0, NULL);
351 if (ctxt == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000352 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000353 "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\n");
354 return NULL;
355 }
Daniel Veillard03a53c32004-10-26 16:06:51 +0000356 /*
357 * For some reason this seems to completely break if node names
358 * are interned.
359 */
360 ctxt->dictNames = 0;
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000361
Daniel Veillard1d913862003-11-21 00:28:39 +0000362 ctxt->myDoc = xmlNewDoc(BAD_CAST XML_DEFAULT_VERSION);
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000363 if (ctxt->myDoc == NULL) {
364 xmlFreeParserCtxt(ctxt);
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000365 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000366 "xmlNewTextWriterDoc : error at xmlNewDoc!\n");
367 return NULL;
368 }
369
370 ret = xmlNewTextWriterPushParser(ctxt, compression);
371 if (ret == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000372 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000373 "xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n");
374 return NULL;
375 }
376
Daniel Veillard500a1de2004-03-22 15:22:58 +0000377 xmlSetDocCompressMode(ctxt->myDoc, compression);
378
379 if (doc != NULL)
380 *doc = ctxt->myDoc;
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000381
382 return ret;
383}
384
385/**
386 * xmlNewTextWriterTree:
387 * @doc: xmlDocPtr
388 * @node: xmlNodePtr or NULL for doc->children
389 * @compression: compress the output?
390 *
391 * Create a new xmlNewTextWriter structure with @doc as output
392 * starting at @node
393 *
394 * Returns the new xmlTextWriterPtr or NULL in case of error
395 */
396xmlTextWriterPtr
397xmlNewTextWriterTree(xmlDocPtr doc, xmlNodePtr node, int compression)
398{
399 xmlTextWriterPtr ret;
400 xmlSAXHandler saxHandler;
401 xmlParserCtxtPtr ctxt;
402
403 if (doc == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000404 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000405 "xmlNewTextWriterTree : invalid document tree!\n");
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000406 return NULL;
407 }
408
409 memset(&saxHandler, '\0', sizeof(saxHandler));
410 xmlSAX2InitDefaultSAXHandler(&saxHandler, 1);
411 saxHandler.startDocument = xmlTextWriterStartDocumentCallback;
412 saxHandler.startElement = xmlSAX2StartElement;
413 saxHandler.endElement = xmlSAX2EndElement;
414
415 ctxt = xmlCreatePushParserCtxt(&saxHandler, NULL, NULL, 0, NULL);
416 if (ctxt == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000417 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000418 "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\n");
419 return NULL;
420 }
Daniel Veillard03a53c32004-10-26 16:06:51 +0000421 /*
422 * For some reason this seems to completely break if node names
423 * are interned.
424 */
425 ctxt->dictNames = 0;
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000426
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000427 ret = xmlNewTextWriterPushParser(ctxt, compression);
428 if (ret == NULL) {
Daniel Veillard500a1de2004-03-22 15:22:58 +0000429 xmlFreeParserCtxt(ctxt);
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000430 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000431 "xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n");
432 return NULL;
433 }
434
Daniel Veillard500a1de2004-03-22 15:22:58 +0000435 ctxt->myDoc = doc;
436 ctxt->node = node;
437
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000438 xmlSetDocCompressMode(doc, compression);
439
440 return ret;
441}
442
443/**
Daniel Veillard1d211e22003-10-20 22:32:39 +0000444 * xmlFreeTextWriter:
445 * @writer: the xmlTextWriterPtr
446 *
447 * Deallocate all the resources associated to the writer
448 */
449void
450xmlFreeTextWriter(xmlTextWriterPtr writer)
451{
452 if (writer == NULL)
453 return;
454
455 if (writer->out != NULL)
456 xmlOutputBufferClose(writer->out);
457
458 if (writer->nodes != NULL)
459 xmlListDelete(writer->nodes);
460
461 if (writer->nsstack != NULL)
462 xmlListDelete(writer->nsstack);
463
Daniel Veillard20c5e782004-01-21 09:57:31 +0000464 if (writer->ctxt != NULL)
465 xmlFreeParserCtxt(writer->ctxt);
466
Daniel Veillard4773df22004-01-23 13:15:13 +0000467 if (writer->ichar != NULL)
468 xmlFree(writer->ichar);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000469 xmlFree(writer);
470}
471
472/**
473 * xmlTextWriterStartDocument:
474 * @writer: the xmlTextWriterPtr
475 * @version: the xml version ("1.0") or NULL for default ("1.0")
476 * @encoding: the encoding or NULL for default
477 * @standalone: "yes" or "no" or NULL for default
478 *
479 * Start a new xml document
480 *
481 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
482 */
483int
484xmlTextWriterStartDocument(xmlTextWriterPtr writer, const char *version,
485 const char *encoding, const char *standalone)
486{
487 int count;
488 int sum;
489 xmlLinkPtr lk;
490 xmlCharEncodingHandlerPtr encoder;
491
Daniel Veillard500a1de2004-03-22 15:22:58 +0000492 if ((writer == NULL) || (writer->out == NULL)) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000493 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000494 "xmlTextWriterStartDocument : invalid writer!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000495 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000496 }
Daniel Veillard1d211e22003-10-20 22:32:39 +0000497
498 lk = xmlListFront(writer->nodes);
499 if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000500 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000501 "xmlTextWriterStartDocument : not allowed in this context!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000502 return -1;
503 }
504
505 encoder = NULL;
506 if (encoding != NULL) {
507 encoder = xmlFindCharEncodingHandler(encoding);
508 if (encoder == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000509 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000510 "xmlTextWriterStartDocument : out of memory!\n");
511 return -1;
512 }
513 }
514
515 writer->out->encoder = encoder;
516 if (encoder != NULL) {
517 writer->out->conv = xmlBufferCreateSize(4000);
518 xmlCharEncOutFunc(encoder, writer->out->conv, NULL);
519 } else
520 writer->out->conv = NULL;
521
522 sum = 0;
523 count = xmlOutputBufferWriteString(writer->out, "<?xml version=");
524 if (count < 0)
525 return -1;
526 sum += count;
527 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
528 if (count < 0)
529 return -1;
530 sum += count;
531 if (version != 0)
532 count = xmlOutputBufferWriteString(writer->out, version);
533 else
534 count = xmlOutputBufferWriteString(writer->out, "1.0");
535 if (count < 0)
536 return -1;
537 sum += count;
538 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
539 if (count < 0)
540 return -1;
541 sum += count;
542 if (writer->out->encoder != 0) {
543 count = xmlOutputBufferWriteString(writer->out, " encoding=");
544 if (count < 0)
545 return -1;
546 sum += count;
547 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
548 if (count < 0)
549 return -1;
550 sum += count;
551 count =
552 xmlOutputBufferWriteString(writer->out,
553 writer->out->encoder->name);
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 }
562
563 if (standalone != 0) {
564 count = xmlOutputBufferWriteString(writer->out, " standalone=");
565 if (count < 0)
566 return -1;
567 sum += count;
568 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
569 if (count < 0)
570 return -1;
571 sum += count;
572 count = xmlOutputBufferWriteString(writer->out, standalone);
573 if (count < 0)
574 return -1;
575 sum += count;
576 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
577 if (count < 0)
578 return -1;
579 sum += count;
580 }
581
582 count = xmlOutputBufferWriteString(writer->out, "?>\n");
583 if (count < 0)
584 return -1;
585 sum += count;
586
587 return sum;
588}
589
590/**
591 * xmlTextWriterEndDocument:
592 * @writer: the xmlTextWriterPtr
593 *
594 * End an xml document. All open elements are closed
595 *
596 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
597 */
598int
599xmlTextWriterEndDocument(xmlTextWriterPtr writer)
600{
601 int count;
602 int sum;
603 xmlLinkPtr lk;
604 xmlTextWriterStackEntry *p;
605
Daniel Veillard500a1de2004-03-22 15:22:58 +0000606 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000607 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000608 "xmlTextWriterEndDocument : invalid writer!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000609 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000610 }
Daniel Veillard1d211e22003-10-20 22:32:39 +0000611
612 sum = 0;
613 while ((lk = xmlListFront(writer->nodes)) != NULL) {
614 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
615 if (p == 0)
616 break;
617 switch (p->state) {
618 case XML_TEXTWRITER_NAME:
619 case XML_TEXTWRITER_ATTRIBUTE:
620 case XML_TEXTWRITER_TEXT:
621 count = xmlTextWriterEndElement(writer);
622 if (count < 0)
623 return -1;
624 sum += count;
625 break;
626 case XML_TEXTWRITER_PI:
627 case XML_TEXTWRITER_PI_TEXT:
628 count = xmlTextWriterEndPI(writer);
629 if (count < 0)
630 return -1;
631 sum += count;
632 break;
633 case XML_TEXTWRITER_CDATA:
634 count = xmlTextWriterEndCDATA(writer);
635 if (count < 0)
636 return -1;
637 sum += count;
638 break;
639 case XML_TEXTWRITER_DTD:
Daniel Veillard500a1de2004-03-22 15:22:58 +0000640 case XML_TEXTWRITER_DTD_TEXT:
641 case XML_TEXTWRITER_DTD_ELEM:
642 case XML_TEXTWRITER_DTD_ELEM_TEXT:
643 case XML_TEXTWRITER_DTD_ATTL:
644 case XML_TEXTWRITER_DTD_ATTL_TEXT:
645 case XML_TEXTWRITER_DTD_ENTY:
646 case XML_TEXTWRITER_DTD_ENTY_TEXT:
647 case XML_TEXTWRITER_DTD_PENT:
Daniel Veillard1d211e22003-10-20 22:32:39 +0000648 count = xmlTextWriterEndDTD(writer);
649 if (count < 0)
650 return -1;
651 sum += count;
652 break;
Daniel Veillardab69f362004-02-17 11:40:32 +0000653 case XML_TEXTWRITER_COMMENT:
654 count = xmlTextWriterEndComment(writer);
655 if (count < 0)
656 return -1;
657 sum += count;
658 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000659 default:
Daniel Veillardab69f362004-02-17 11:40:32 +0000660 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000661 }
662 }
663
Daniel Veillard2cca4462004-01-02 20:04:23 +0000664 if (!writer->indent) {
Daniel Veillardab69f362004-02-17 11:40:32 +0000665 count = xmlOutputBufferWriteString(writer->out, "\n");
666 if (count < 0)
667 return -1;
668 sum += count;
669 }
670 return sum;
671}
672
Daniel Veillardab69f362004-02-17 11:40:32 +0000673/**
674 * xmlTextWriterStartComment:
675 * @writer: the xmlTextWriterPtr
676 *
677 * Start an xml comment.
678 *
679 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
680 */
681int
682xmlTextWriterStartComment(xmlTextWriterPtr writer)
683{
684 int count;
685 int sum;
686 xmlLinkPtr lk;
687 xmlTextWriterStackEntry *p;
688
Daniel Veillard500a1de2004-03-22 15:22:58 +0000689 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000690 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000691 "xmlTextWriterStartComment : invalid writer!\n");
Daniel Veillardab69f362004-02-17 11:40:32 +0000692 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000693 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000694
695 sum = 0;
696 lk = xmlListFront(writer->nodes);
697 if (lk != 0) {
698 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
699 if (p != 0) {
700 switch (p->state) {
701 case XML_TEXTWRITER_TEXT:
702 case XML_TEXTWRITER_NONE:
703 break;
704 case XML_TEXTWRITER_NAME:
705 count = xmlOutputBufferWriteString(writer->out, ">");
706 if (count < 0)
707 return -1;
708 sum += count;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000709 if (writer->indent) {
710 count =
711 xmlOutputBufferWriteString(writer->out, "\n");
712 if (count < 0)
713 return -1;
714 sum += count;
715 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000716 p->state = XML_TEXTWRITER_TEXT;
717 break;
718 default:
719 return -1;
720 }
721 }
722 }
723
724 p = (xmlTextWriterStackEntry *)
725 xmlMalloc(sizeof(xmlTextWriterStackEntry));
726 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000727 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillardab69f362004-02-17 11:40:32 +0000728 "xmlTextWriterStartElement : out of memory!\n");
729 return -1;
730 }
731
732 p->name = 0;
733 p->state = XML_TEXTWRITER_COMMENT;
734
735 xmlListPushFront(writer->nodes, p);
736
737 if (writer->indent) {
Daniel Veillardab69f362004-02-17 11:40:32 +0000738 count = xmlTextWriterWriteIndent(writer);
739 if (count < 0)
740 return -1;
741 sum += count;
742 }
743
744 count = xmlOutputBufferWriteString(writer->out, "<!--");
745 if (count < 0)
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000746 return -1;
747 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +0000748
749 return sum;
750}
751
752/**
753 * xmlTextWriterEndComment:
754 * @writer: the xmlTextWriterPtr
755 *
756 * End the current xml coment.
757 *
758 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
759 */
760int
761xmlTextWriterEndComment(xmlTextWriterPtr writer)
762{
763 int count;
764 int sum;
765 xmlLinkPtr lk;
766 xmlTextWriterStackEntry *p;
767
Daniel Veillard500a1de2004-03-22 15:22:58 +0000768 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000769 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000770 "xmlTextWriterEndComment : invalid writer!\n");
Daniel Veillardab69f362004-02-17 11:40:32 +0000771 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000772 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000773
774 lk = xmlListFront(writer->nodes);
Daniel Veillard500a1de2004-03-22 15:22:58 +0000775 if (lk == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000776 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000777 "xmlTextWriterEndComment : not allowed in this context!\n");
Daniel Veillardab69f362004-02-17 11:40:32 +0000778 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000779 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000780
781 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
782 if (p == 0)
783 return -1;
784
785 sum = 0;
786 switch (p->state) {
787 case XML_TEXTWRITER_COMMENT:
788 count = xmlOutputBufferWriteString(writer->out, "-->");
789 if (count < 0)
790 return -1;
791 sum += count;
792 break;
793 default:
794 return -1;
Daniel Veillard2cca4462004-01-02 20:04:23 +0000795 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000796
797 if (writer->indent) {
798 count = xmlOutputBufferWriteString(writer->out, "\n");
799 if (count < 0)
800 return -1;
801 sum += count;
802 }
803
804 xmlListPopFront(writer->nodes);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000805 return sum;
806}
807
808/**
809 * xmlTextWriterWriteFormatComment:
810 * @writer: the xmlTextWriterPtr
811 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +0000812 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +0000813 *
814 * Write an xml comment.
815 *
816 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
817 */
818int
819xmlTextWriterWriteFormatComment(xmlTextWriterPtr writer,
820 const char *format, ...)
821{
822 int rc;
823 va_list ap;
824
825 va_start(ap, format);
826
827 rc = xmlTextWriterWriteVFormatComment(writer, format, ap);
828
829 va_end(ap);
830 return rc;
831}
832
833/**
834 * xmlTextWriterWriteVFormatComment:
835 * @writer: the xmlTextWriterPtr
836 * @format: format string (see printf)
837 * @argptr: pointer to the first member of the variable argument list.
838 *
839 * Write an xml comment.
840 *
841 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
842 */
843int
844xmlTextWriterWriteVFormatComment(xmlTextWriterPtr writer,
845 const char *format, va_list argptr)
846{
847 int rc;
848 xmlChar *buf;
849
Daniel Veillard500a1de2004-03-22 15:22:58 +0000850 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000851 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000852 "xmlTextWriterWriteVFormatComment : invalid writer!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000853 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000854 }
Daniel Veillard1d211e22003-10-20 22:32:39 +0000855
856 buf = xmlTextWriterVSprintf(format, argptr);
857 if (buf == 0)
858 return 0;
859
860 rc = xmlTextWriterWriteComment(writer, buf);
861
862 xmlFree(buf);
863 return rc;
864}
865
866/**
867 * xmlTextWriterWriteComment:
868 * @writer: the xmlTextWriterPtr
869 * @content: comment string
870 *
871 * Write an xml comment.
872 *
873 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
874 */
875int
876xmlTextWriterWriteComment(xmlTextWriterPtr writer, const xmlChar * content)
877{
878 int count;
879 int sum;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000880
881 sum = 0;
Daniel Veillardab69f362004-02-17 11:40:32 +0000882 count = xmlTextWriterStartComment(writer);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000883 if (count < 0)
884 return -1;
885 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +0000886 count = xmlTextWriterWriteString(writer, content);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000887 if (count < 0)
888 return -1;
889 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +0000890 count = xmlTextWriterEndComment(writer);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000891 if (count < 0)
892 return -1;
893 sum += count;
894
895 return sum;
896}
897
898/**
899 * xmlTextWriterStartElement:
900 * @writer: the xmlTextWriterPtr
901 * @name: element name
902 *
903 * Start an xml element.
904 *
905 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
906 */
907int
908xmlTextWriterStartElement(xmlTextWriterPtr writer, const xmlChar * name)
909{
910 int count;
911 int sum;
912 xmlLinkPtr lk;
913 xmlTextWriterStackEntry *p;
914
915 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
916 return -1;
917
918 sum = 0;
919 lk = xmlListFront(writer->nodes);
920 if (lk != 0) {
921 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
922 if (p != 0) {
923 switch (p->state) {
924 case XML_TEXTWRITER_PI:
925 case XML_TEXTWRITER_PI_TEXT:
926 return -1;
927 case XML_TEXTWRITER_NONE:
928 break;
929 case XML_TEXTWRITER_NAME:
930 count = xmlOutputBufferWriteString(writer->out, ">");
931 if (count < 0)
932 return -1;
933 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +0000934 if (writer->indent)
935 count =
936 xmlOutputBufferWriteString(writer->out, "\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000937 p->state = XML_TEXTWRITER_TEXT;
938 break;
Daniel Veillardab69f362004-02-17 11:40:32 +0000939 default:
940 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000941 }
942 }
943 }
944
945 p = (xmlTextWriterStackEntry *)
946 xmlMalloc(sizeof(xmlTextWriterStackEntry));
947 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000948 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000949 "xmlTextWriterStartElement : out of memory!\n");
950 return -1;
951 }
952
953 p->name = xmlStrdup(name);
954 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000955 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000956 "xmlTextWriterStartElement : out of memory!\n");
957 xmlFree(p);
958 return -1;
959 }
960 p->state = XML_TEXTWRITER_NAME;
961
962 xmlListPushFront(writer->nodes, p);
963
Daniel Veillardab69f362004-02-17 11:40:32 +0000964 if (writer->indent) {
965 count = xmlTextWriterWriteIndent(writer);
966 sum += count;
Daniel Veillard2cca4462004-01-02 20:04:23 +0000967 }
968
Daniel Veillard1d211e22003-10-20 22:32:39 +0000969 count = xmlOutputBufferWriteString(writer->out, "<");
970 if (count < 0)
971 return -1;
972 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000973 count =
974 xmlOutputBufferWriteString(writer->out, (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000975 if (count < 0)
976 return -1;
977 sum += count;
978
979 return sum;
980}
981
982/**
983 * xmlTextWriterStartElementNS:
984 * @writer: the xmlTextWriterPtr
985 * @prefix: namespace prefix or NULL
986 * @name: element local name
987 * @namespaceURI: namespace URI or NULL
988 *
989 * Start an xml element with namespace support.
990 *
991 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
992 */
993int
994xmlTextWriterStartElementNS(xmlTextWriterPtr writer,
995 const xmlChar * prefix, const xmlChar * name,
996 const xmlChar * namespaceURI)
997{
998 int count;
999 int sum;
1000 xmlChar *buf;
1001
1002 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1003 return -1;
1004
1005 buf = 0;
1006 if (prefix != 0) {
1007 buf = xmlStrdup(prefix);
1008 buf = xmlStrcat(buf, BAD_CAST ":");
1009 }
1010 buf = xmlStrcat(buf, name);
1011
1012 sum = 0;
1013 count = xmlTextWriterStartElement(writer, buf);
1014 xmlFree(buf);
1015 if (count < 0)
1016 return -1;
1017 sum += count;
1018
1019 if (namespaceURI != 0) {
1020 buf = xmlStrdup(BAD_CAST "xmlns");
1021 if (prefix != 0) {
1022 buf = xmlStrcat(buf, BAD_CAST ":");
1023 buf = xmlStrcat(buf, prefix);
1024 }
1025
1026 count = xmlTextWriterWriteAttribute(writer, buf, namespaceURI);
1027 xmlFree(buf);
1028 if (count < 0)
1029 return -1;
1030 sum += count;
1031 }
1032
1033 return sum;
1034}
1035
1036/**
1037 * xmlTextWriterEndElement:
1038 * @writer: the xmlTextWriterPtr
1039 *
1040 * End the current xml element.
1041 *
1042 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1043 */
1044int
1045xmlTextWriterEndElement(xmlTextWriterPtr writer)
1046{
1047 int count;
1048 int sum;
1049 xmlLinkPtr lk;
1050 xmlTextWriterStackEntry *p;
1051
1052 if (writer == NULL)
1053 return -1;
1054
1055 lk = xmlListFront(writer->nodes);
1056 if (lk == 0)
1057 return -1;
1058
1059 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1060 if (p == 0)
1061 return -1;
1062
1063 sum = 0;
1064 switch (p->state) {
1065 case XML_TEXTWRITER_ATTRIBUTE:
1066 count = xmlTextWriterEndAttribute(writer);
1067 if (count < 0)
1068 return -1;
1069 sum += count;
1070 /* fallthrough */
1071 case XML_TEXTWRITER_NAME:
Daniel Veillardab69f362004-02-17 11:40:32 +00001072 if (writer->indent) /* next element needs indent */
1073 writer->doindent = 1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001074 count = xmlOutputBufferWriteString(writer->out, "/>");
1075 if (count < 0)
1076 return -1;
1077 sum += count;
1078 break;
1079 case XML_TEXTWRITER_TEXT:
Daniel Veillardab69f362004-02-17 11:40:32 +00001080 if ((writer->indent) && (writer->doindent)) {
1081 count = xmlTextWriterWriteIndent(writer);
1082 sum += count;
1083 writer->doindent = 1;
1084 } else
1085 writer->doindent = 1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001086 count = xmlOutputBufferWriteString(writer->out, "</");
1087 if (count < 0)
1088 return -1;
1089 sum += count;
1090 count = xmlOutputBufferWriteString(writer->out,
Daniel Veillardab69f362004-02-17 11:40:32 +00001091 (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001092 if (count < 0)
1093 return -1;
1094 sum += count;
1095 count = xmlOutputBufferWriteString(writer->out, ">");
1096 if (count < 0)
1097 return -1;
1098 sum += count;
1099 break;
1100 default:
1101 return -1;
1102 }
1103
Daniel Veillard2cca4462004-01-02 20:04:23 +00001104 if (writer->indent) {
Daniel Veillardab69f362004-02-17 11:40:32 +00001105 count = xmlOutputBufferWriteString(writer->out, "\n");
1106 sum += count;
Daniel Veillard2cca4462004-01-02 20:04:23 +00001107 }
1108
Daniel Veillard1d211e22003-10-20 22:32:39 +00001109 xmlListPopFront(writer->nodes);
1110 return sum;
1111}
1112
1113/**
1114 * xmlTextWriterFullEndElement:
1115 * @writer: the xmlTextWriterPtr
1116 *
1117 * End the current xml element. Writes an end tag even if the element is empty
1118 *
1119 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1120 */
1121int
1122xmlTextWriterFullEndElement(xmlTextWriterPtr writer)
1123{
1124 int count;
1125 int sum;
1126 xmlLinkPtr lk;
1127 xmlTextWriterStackEntry *p;
1128
1129 if (writer == NULL)
1130 return -1;
1131
1132 lk = xmlListFront(writer->nodes);
1133 if (lk == 0)
1134 return -1;
1135
1136 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1137 if (p == 0)
1138 return -1;
1139
1140 sum = 0;
1141 switch (p->state) {
1142 case XML_TEXTWRITER_ATTRIBUTE:
1143 count = xmlTextWriterEndAttribute(writer);
1144 if (count < 0)
1145 return -1;
1146 sum += count;
1147 /* fallthrough */
1148 case XML_TEXTWRITER_NAME:
1149 count = xmlOutputBufferWriteString(writer->out, ">");
1150 if (count < 0)
1151 return -1;
1152 sum += count;
1153 /* fallthrough */
1154 case XML_TEXTWRITER_TEXT:
1155 count = xmlOutputBufferWriteString(writer->out, "</");
1156 if (count < 0)
1157 return -1;
1158 sum += count;
1159 count = xmlOutputBufferWriteString(writer->out,
Daniel Veillardab69f362004-02-17 11:40:32 +00001160 (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001161 if (count < 0)
1162 return -1;
1163 sum += count;
1164 count = xmlOutputBufferWriteString(writer->out, ">");
1165 if (count < 0)
1166 return -1;
1167 sum += count;
1168 break;
1169 default:
1170 return -1;
1171 }
1172
1173 xmlListPopFront(writer->nodes);
1174 return sum;
1175}
1176
1177/**
1178 * xmlTextWriterWriteFormatRaw:
1179 * @writer: the xmlTextWriterPtr
1180 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001181 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001182 *
1183 * Write a formatted raw xml text.
1184 *
1185 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1186 */
1187int
1188xmlTextWriterWriteFormatRaw(xmlTextWriterPtr writer, const char *format,
1189 ...)
1190{
1191 int rc;
1192 va_list ap;
1193
1194 va_start(ap, format);
1195
1196 rc = xmlTextWriterWriteVFormatRaw(writer, format, ap);
1197
1198 va_end(ap);
1199 return rc;
1200}
1201
1202/**
1203 * xmlTextWriterWriteVFormatRaw:
1204 * @writer: the xmlTextWriterPtr
1205 * @format: format string (see printf)
1206 * @argptr: pointer to the first member of the variable argument list.
1207 *
1208 * Write a formatted raw xml text.
1209 *
1210 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1211 */
1212int
1213xmlTextWriterWriteVFormatRaw(xmlTextWriterPtr writer, const char *format,
1214 va_list argptr)
1215{
1216 int rc;
1217 xmlChar *buf;
1218
1219 if (writer == NULL)
1220 return -1;
1221
1222 buf = xmlTextWriterVSprintf(format, argptr);
1223 if (buf == 0)
1224 return 0;
1225
1226 rc = xmlTextWriterWriteRaw(writer, buf);
1227
1228 xmlFree(buf);
1229 return rc;
1230}
1231
1232/**
Daniel Veillard1e906612003-12-05 14:57:46 +00001233 * xmlTextWriterWriteRawLen:
Daniel Veillard1d211e22003-10-20 22:32:39 +00001234 * @writer: the xmlTextWriterPtr
1235 * @content: text string
1236 * @len: length of the text string
1237 *
1238 * Write an xml text.
1239 * TODO: what about entities and special chars??
1240 *
1241 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1242 */
1243int
1244xmlTextWriterWriteRawLen(xmlTextWriterPtr writer, const xmlChar * content,
1245 int len)
1246{
1247 int count;
1248 int sum;
1249 xmlLinkPtr lk;
1250 xmlTextWriterStackEntry *p;
1251
Daniel Veillard500a1de2004-03-22 15:22:58 +00001252 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00001253 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00001254 "xmlTextWriterWriteRawLen : invalid writer!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +00001255 return -1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001256 }
1257
Daniel Veillarde43cc572004-11-03 11:50:29 +00001258 if ((content == NULL) || (len < 0)) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00001259 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00001260 "xmlTextWriterWriteRawLen : invalid content!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +00001261 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001262 }
1263
1264 sum = 0;
1265 lk = xmlListFront(writer->nodes);
1266 if (lk != 0) {
1267 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1268 count = xmlTextWriterHandleStateDependencies(writer, p);
1269 if (count < 0)
1270 return -1;
1271 sum += count;
1272 }
1273
1274 if (writer->indent)
1275 writer->doindent = 0;
1276
1277 if (content != NULL) {
1278 count =
1279 xmlOutputBufferWrite(writer->out, len, (const char *) content);
1280 if (count < 0)
1281 return -1;
1282 sum += count;
1283 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001284
1285 return sum;
1286}
1287
1288/**
1289 * xmlTextWriterWriteRaw:
1290 * @writer: the xmlTextWriterPtr
1291 * @content: text string
1292 *
1293 * Write a raw xml text.
1294 *
1295 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1296 */
1297int
1298xmlTextWriterWriteRaw(xmlTextWriterPtr writer, const xmlChar * content)
1299{
1300 return xmlTextWriterWriteRawLen(writer, content, xmlStrlen(content));
1301}
1302
1303/**
1304 * xmlTextWriterWriteFormatString:
1305 * @writer: the xmlTextWriterPtr
1306 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001307 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001308 *
1309 * Write a formatted xml text.
1310 *
1311 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1312 */
1313int
1314xmlTextWriterWriteFormatString(xmlTextWriterPtr writer, const char *format,
1315 ...)
1316{
1317 int rc;
1318 va_list ap;
1319
Daniel Veillarde43cc572004-11-03 11:50:29 +00001320 if ((writer == NULL) || (format == NULL))
1321 return -1;
1322
Daniel Veillard1d211e22003-10-20 22:32:39 +00001323 va_start(ap, format);
1324
1325 rc = xmlTextWriterWriteVFormatString(writer, format, ap);
1326
1327 va_end(ap);
1328 return rc;
1329}
1330
1331/**
1332 * xmlTextWriterWriteVFormatString:
1333 * @writer: the xmlTextWriterPtr
1334 * @format: format string (see printf)
1335 * @argptr: pointer to the first member of the variable argument list.
1336 *
1337 * Write a formatted xml text.
1338 *
1339 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1340 */
1341int
1342xmlTextWriterWriteVFormatString(xmlTextWriterPtr writer,
1343 const char *format, va_list argptr)
1344{
1345 int rc;
1346 xmlChar *buf;
1347
Daniel Veillarde43cc572004-11-03 11:50:29 +00001348 if ((writer == NULL) || (format == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00001349 return -1;
1350
1351 buf = xmlTextWriterVSprintf(format, argptr);
1352 if (buf == 0)
1353 return 0;
1354
1355 rc = xmlTextWriterWriteString(writer, buf);
1356
1357 xmlFree(buf);
1358 return rc;
1359}
1360
1361/**
1362 * xmlTextWriterWriteString:
1363 * @writer: the xmlTextWriterPtr
1364 * @content: text string
1365 *
1366 * Write an xml text.
1367 *
1368 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1369 */
1370int
1371xmlTextWriterWriteString(xmlTextWriterPtr writer, const xmlChar * content)
1372{
Daniel Veillard500a1de2004-03-22 15:22:58 +00001373 int count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001374 int sum;
1375 xmlLinkPtr lk;
1376 xmlTextWriterStackEntry *p;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001377 xmlChar *buf;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001378
Daniel Veillarde43cc572004-11-03 11:50:29 +00001379 if ((writer == NULL) || (content == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00001380 return -1;
1381
Daniel Veillard1d211e22003-10-20 22:32:39 +00001382 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001383 buf = (xmlChar *) content;
1384 lk = xmlListFront(writer->nodes);
1385 if (lk != 0) {
1386 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1387 if (p != 0) {
1388 switch (p->state) {
1389 case XML_TEXTWRITER_NAME:
1390 case XML_TEXTWRITER_TEXT:
Daniel Veillard62040be2004-05-17 03:17:26 +00001391#if 0
1392 buf = NULL;
1393 xmlOutputBufferWriteEscape(writer->out, content, NULL);
1394#endif
Daniel Veillard500a1de2004-03-22 15:22:58 +00001395 buf = xmlEncodeSpecialChars(NULL, content);
1396 break;
1397 case XML_TEXTWRITER_ATTRIBUTE:
1398 buf = NULL;
1399 xmlAttrSerializeTxtContent(writer->out->buffer, NULL,
1400 NULL, content);
1401 break;
William M. Brack87640d52004-04-17 14:58:15 +00001402 default:
1403 break;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001404 }
1405 }
1406 }
1407
1408 if (buf != NULL) {
1409 count = xmlTextWriterWriteRaw(writer, buf);
1410 if (count < 0)
Daniel Veillard1d211e22003-10-20 22:32:39 +00001411 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001412 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001413
Daniel Veillard500a1de2004-03-22 15:22:58 +00001414 if (buf != content) /* buf was allocated by us, so free it */
1415 xmlFree(buf);
William M. Bracka9c612c2004-02-01 10:04:05 +00001416 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001417
1418 return sum;
1419}
1420
1421/**
1422 * xmlOutputBufferWriteBase64:
1423 * @out: the xmlOutputBufferPtr
1424 * @data: binary data
1425 * @len: the number of bytes to encode
1426 *
1427 * Write base64 encoded data to an xmlOutputBuffer.
1428 * Adapted from John Walker's base64.c (http://www.fourmilab.ch/).
1429 *
1430 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1431 */
1432static int
1433xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len,
1434 const unsigned char *data)
1435{
1436 static unsigned char dtable[64] =
William M. Brack47a31882004-09-11 16:09:09 +00001437 {'A','B','C','D','E','F','G','H','I','J','K','L','M',
1438 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
1439 'a','b','c','d','e','f','g','h','i','j','k','l','m',
1440 'n','o','p','q','r','s','t','u','v','w','x','y','z',
1441 '0','1','2','3','4','5','6','7','8','9','+','/'};
1442
Daniel Veillard1d211e22003-10-20 22:32:39 +00001443 int i;
1444 int linelen;
1445 int count;
1446 int sum;
1447
Daniel Veillarde43cc572004-11-03 11:50:29 +00001448 if ((out == NULL) || (len < 0) || (data == NULL))
1449 return(-1);
1450
Daniel Veillard1d211e22003-10-20 22:32:39 +00001451 linelen = 0;
1452 sum = 0;
1453
1454 i = 0;
1455 while (1) {
1456 unsigned char igroup[3];
1457 unsigned char ogroup[4];
1458 int c;
1459 int n;
1460
1461 igroup[0] = igroup[1] = igroup[2] = 0;
1462 for (n = 0; n < 3 && i < len; n++, i++) {
1463 c = data[i];
1464 igroup[n] = (unsigned char) c;
1465 }
1466
1467 if (n > 0) {
1468 ogroup[0] = dtable[igroup[0] >> 2];
1469 ogroup[1] = dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)];
1470 ogroup[2] =
1471 dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)];
1472 ogroup[3] = dtable[igroup[2] & 0x3F];
1473
1474 if (n < 3) {
1475 ogroup[3] = '=';
1476 if (n < 2) {
1477 ogroup[2] = '=';
1478 }
1479 }
1480
1481 if (linelen >= B64LINELEN) {
1482 count = xmlOutputBufferWrite(out, 2, B64CRLF);
1483 if (count == -1)
1484 return -1;
1485 sum += count;
1486 linelen = 0;
1487 }
1488 count = xmlOutputBufferWrite(out, 4, (const char *) ogroup);
1489 if (count == -1)
1490 return -1;
1491 sum += count;
1492
1493 linelen += 4;
1494 }
Daniel Veillard929714b2003-10-22 12:34:36 +00001495
1496 if (i >= len)
1497 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001498 }
1499
Daniel Veillard1d211e22003-10-20 22:32:39 +00001500 return sum;
1501}
1502
1503/**
1504 * xmlTextWriterWriteBase64:
1505 * @writer: the xmlTextWriterPtr
1506 * @data: binary data
1507 * @start: the position within the data of the first byte to encode
1508 * @len: the number of bytes to encode
1509 *
1510 * Write an base64 encoded xml text.
1511 *
1512 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1513 */
1514int
Daniel Veillardab69f362004-02-17 11:40:32 +00001515xmlTextWriterWriteBase64(xmlTextWriterPtr writer, const char *data,
Daniel Veillard1d211e22003-10-20 22:32:39 +00001516 int start, int len)
1517{
1518 int count;
1519 int sum;
1520 xmlLinkPtr lk;
1521 xmlTextWriterStackEntry *p;
1522
Daniel Veillarde43cc572004-11-03 11:50:29 +00001523 if ((writer == NULL) || (data == NULL) || (start < 0) || (len < 0))
Daniel Veillard1d211e22003-10-20 22:32:39 +00001524 return -1;
1525
Daniel Veillard1d211e22003-10-20 22:32:39 +00001526 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001527 lk = xmlListFront(writer->nodes);
1528 if (lk != 0) {
1529 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1530 if (p != 0) {
1531 count = xmlTextWriterHandleStateDependencies(writer, p);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001532 if (count < 0)
1533 return -1;
1534 sum += count;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001535 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001536 }
1537
Daniel Veillardab69f362004-02-17 11:40:32 +00001538 if (writer->indent)
1539 writer->doindent = 0;
1540
Daniel Veillard1d211e22003-10-20 22:32:39 +00001541 count =
1542 xmlOutputBufferWriteBase64(writer->out, len,
1543 (unsigned char *) data + start);
1544 if (count < 0)
1545 return -1;
1546 sum += count;
1547
1548 return sum;
1549}
1550
1551/**
1552 * xmlOutputBufferWriteBinHex:
1553 * @out: the xmlOutputBufferPtr
1554 * @data: binary data
1555 * @len: the number of bytes to encode
1556 *
1557 * Write hqx encoded data to an xmlOutputBuffer.
1558 * ::todo
1559 *
William M. Brack47a31882004-09-11 16:09:09 +00001560 * Returns the bytes written (may be 0 because of buffering)
1561 * or -1 in case of error
Daniel Veillard1d211e22003-10-20 22:32:39 +00001562 */
1563static int
Daniel Veillardab69f362004-02-17 11:40:32 +00001564xmlOutputBufferWriteBinHex(xmlOutputBufferPtr out,
1565 int len, const unsigned char *data)
Daniel Veillard1d211e22003-10-20 22:32:39 +00001566{
Daniel Veillardab69f362004-02-17 11:40:32 +00001567 int count;
1568 int sum;
William M. Brack47a31882004-09-11 16:09:09 +00001569 static char hex[16] =
1570 {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
Daniel Veillardab69f362004-02-17 11:40:32 +00001571 int i;
1572
Daniel Veillarde43cc572004-11-03 11:50:29 +00001573 if ((out == NULL) || (data == NULL) || (len < 0)) {
Daniel Veillardab69f362004-02-17 11:40:32 +00001574 return -1;
1575 }
1576
1577 sum = 0;
1578 for (i = 0; i < len; i++) {
1579 count =
1580 xmlOutputBufferWrite(out, 1,
1581 (const char *) &hex[data[i] >> 4]);
1582 if (count == -1)
1583 return -1;
1584 sum += count;
1585 count =
1586 xmlOutputBufferWrite(out, 1,
1587 (const char *) &hex[data[i] & 0xF]);
1588 if (count == -1)
1589 return -1;
1590 sum += count;
1591 }
1592
1593 return sum;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001594}
1595
1596/**
1597 * xmlTextWriterWriteBinHex:
1598 * @writer: the xmlTextWriterPtr
1599 * @data: binary data
1600 * @start: the position within the data of the first byte to encode
1601 * @len: the number of bytes to encode
1602 *
1603 * Write a BinHex encoded xml text.
1604 *
1605 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1606 */
1607int
Daniel Veillardab69f362004-02-17 11:40:32 +00001608xmlTextWriterWriteBinHex(xmlTextWriterPtr writer, const char *data,
Daniel Veillard1d211e22003-10-20 22:32:39 +00001609 int start, int len)
1610{
1611 int count;
1612 int sum;
1613 xmlLinkPtr lk;
1614 xmlTextWriterStackEntry *p;
1615
Daniel Veillarde43cc572004-11-03 11:50:29 +00001616 if ((writer == NULL) || (data == NULL) || (start < 0) || (len < 0))
Daniel Veillard1d211e22003-10-20 22:32:39 +00001617 return -1;
1618
Daniel Veillard1d211e22003-10-20 22:32:39 +00001619 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001620 lk = xmlListFront(writer->nodes);
1621 if (lk != 0) {
1622 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1623 if (p != 0) {
1624 count = xmlTextWriterHandleStateDependencies(writer, p);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001625 if (count < 0)
1626 return -1;
1627 sum += count;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001628 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001629 }
1630
Daniel Veillardab69f362004-02-17 11:40:32 +00001631 if (writer->indent)
1632 writer->doindent = 0;
1633
Daniel Veillard1d211e22003-10-20 22:32:39 +00001634 count =
1635 xmlOutputBufferWriteBinHex(writer->out, len,
1636 (unsigned char *) data + start);
1637 if (count < 0)
1638 return -1;
1639 sum += count;
1640
1641 return sum;
1642}
1643
1644/**
1645 * xmlTextWriterStartAttribute:
1646 * @writer: the xmlTextWriterPtr
1647 * @name: element name
1648 *
1649 * Start an xml attribute.
1650 *
1651 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1652 */
1653int
1654xmlTextWriterStartAttribute(xmlTextWriterPtr writer, const xmlChar * name)
1655{
1656 int count;
1657 int sum;
1658 xmlLinkPtr lk;
1659 xmlTextWriterStackEntry *p;
1660
1661 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1662 return -1;
1663
1664 sum = 0;
1665 lk = xmlListFront(writer->nodes);
1666 if (lk == 0)
1667 return -1;
1668
1669 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1670 if (p == 0)
1671 return -1;
1672
1673 switch (p->state) {
1674 case XML_TEXTWRITER_ATTRIBUTE:
1675 count = xmlTextWriterEndAttribute(writer);
1676 if (count < 0)
1677 return -1;
1678 sum += count;
1679 /* fallthrough */
1680 case XML_TEXTWRITER_NAME:
1681 count = xmlOutputBufferWriteString(writer->out, " ");
1682 if (count < 0)
1683 return -1;
1684 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00001685 count =
1686 xmlOutputBufferWriteString(writer->out,
1687 (const char *) name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001688 if (count < 0)
1689 return -1;
1690 sum += count;
1691 count = xmlOutputBufferWriteString(writer->out, "=");
1692 if (count < 0)
1693 return -1;
1694 sum += count;
1695 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
1696 if (count < 0)
1697 return -1;
1698 sum += count;
1699 p->state = XML_TEXTWRITER_ATTRIBUTE;
1700 break;
1701 default:
1702 return -1;
1703 }
1704
1705 return sum;
1706}
1707
1708/**
1709 * xmlTextWriterStartAttributeNS:
1710 * @writer: the xmlTextWriterPtr
1711 * @prefix: namespace prefix or NULL
1712 * @name: element local name
1713 * @namespaceURI: namespace URI or NULL
1714 *
1715 * Start an xml attribute with namespace support.
1716 *
1717 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1718 */
1719int
1720xmlTextWriterStartAttributeNS(xmlTextWriterPtr writer,
1721 const xmlChar * prefix, const xmlChar * name,
1722 const xmlChar * namespaceURI)
1723{
1724 int count;
1725 int sum;
1726 xmlChar *buf;
1727 xmlTextWriterNsStackEntry *p;
1728
1729 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1730 return -1;
1731
1732 buf = 0;
1733 if (prefix != 0) {
1734 buf = xmlStrdup(prefix);
1735 buf = xmlStrcat(buf, BAD_CAST ":");
1736 }
1737 buf = xmlStrcat(buf, name);
1738
1739 sum = 0;
1740 count = xmlTextWriterStartAttribute(writer, buf);
1741 xmlFree(buf);
1742 if (count < 0)
1743 return -1;
1744 sum += count;
1745
1746 if (namespaceURI != 0) {
1747 buf = xmlStrdup(BAD_CAST "xmlns");
1748 if (prefix != 0) {
1749 buf = xmlStrcat(buf, BAD_CAST ":");
1750 buf = xmlStrcat(buf, prefix);
1751 }
1752
1753 p = (xmlTextWriterNsStackEntry *)
1754 xmlMalloc(sizeof(xmlTextWriterNsStackEntry));
1755 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00001756 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00001757 "xmlTextWriterStartAttributeNS : out of memory!\n");
1758 return -1;
1759 }
1760
1761 p->prefix = buf;
1762 p->uri = xmlStrdup(namespaceURI);
1763 if (p->uri == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00001764 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00001765 "xmlTextWriterStartAttributeNS : out of memory!\n");
1766 xmlFree(p);
1767 return -1;
1768 }
1769 p->elem = xmlListFront(writer->nodes);
1770
1771 xmlListPushFront(writer->nsstack, p);
1772 }
1773
1774 return sum;
1775}
1776
1777/**
1778 * xmlTextWriterEndAttribute:
1779 * @writer: the xmlTextWriterPtr
1780 *
1781 * End the current xml element.
1782 *
1783 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1784 */
1785int
1786xmlTextWriterEndAttribute(xmlTextWriterPtr writer)
1787{
1788 int count;
1789 int sum;
1790 xmlLinkPtr lk;
1791 xmlTextWriterStackEntry *p;
1792 xmlTextWriterNsStackEntry *np;
1793
1794 if (writer == NULL)
1795 return -1;
1796
1797 lk = xmlListFront(writer->nodes);
1798 if (lk == 0) {
1799 xmlListDelete(writer->nsstack);
Daniel Veillarde43cc572004-11-03 11:50:29 +00001800 writer->nsstack = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001801 return -1;
1802 }
1803
1804 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1805 if (p == 0) {
1806 xmlListDelete(writer->nsstack);
Daniel Veillarde43cc572004-11-03 11:50:29 +00001807 writer->nsstack = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001808 return -1;
1809 }
1810
1811 sum = 0;
1812 switch (p->state) {
1813 case XML_TEXTWRITER_ATTRIBUTE:
1814 p->state = XML_TEXTWRITER_NAME;
1815
1816 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
1817 if (count < 0) {
1818 xmlListDelete(writer->nsstack);
Daniel Veillarde43cc572004-11-03 11:50:29 +00001819 writer->nsstack = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001820 return -1;
1821 }
1822 sum += count;
1823
1824 while (!xmlListEmpty(writer->nsstack)) {
1825 lk = xmlListFront(writer->nsstack);
1826 np = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
1827 if (np != 0) {
1828 count =
1829 xmlTextWriterWriteAttribute(writer, np->prefix,
1830 np->uri);
1831 if (count < 0) {
1832 xmlListDelete(writer->nsstack);
Daniel Veillarde43cc572004-11-03 11:50:29 +00001833 writer->nsstack = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001834 return -1;
1835 }
1836 sum += count;
1837 }
1838
1839 xmlListPopFront(writer->nsstack);
1840 }
1841 break;
1842
1843 default:
1844 xmlListClear(writer->nsstack);
1845 return -1;
1846 }
1847
1848 return sum;
1849}
1850
1851/**
1852 * xmlTextWriterWriteFormatAttribute:
1853 * @writer: the xmlTextWriterPtr
1854 * @name: attribute name
1855 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001856 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001857 *
1858 * Write a formatted xml attribute.
1859 *
1860 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1861 */
1862int
1863xmlTextWriterWriteFormatAttribute(xmlTextWriterPtr writer,
1864 const xmlChar * name, const char *format,
1865 ...)
1866{
1867 int rc;
1868 va_list ap;
1869
1870 va_start(ap, format);
1871
1872 rc = xmlTextWriterWriteVFormatAttribute(writer, name, format, ap);
1873
1874 va_end(ap);
1875 return rc;
1876}
1877
1878/**
1879 * xmlTextWriterWriteVFormatAttribute:
1880 * @writer: the xmlTextWriterPtr
1881 * @name: attribute name
1882 * @format: format string (see printf)
1883 * @argptr: pointer to the first member of the variable argument list.
1884 *
1885 * Write a formatted xml attribute.
1886 *
1887 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1888 */
1889int
1890xmlTextWriterWriteVFormatAttribute(xmlTextWriterPtr writer,
1891 const xmlChar * name,
1892 const char *format, va_list argptr)
1893{
1894 int rc;
1895 xmlChar *buf;
1896
1897 if (writer == NULL)
1898 return -1;
1899
1900 buf = xmlTextWriterVSprintf(format, argptr);
1901 if (buf == 0)
1902 return 0;
1903
1904 rc = xmlTextWriterWriteAttribute(writer, name, buf);
1905
1906 xmlFree(buf);
1907 return rc;
1908}
1909
1910/**
1911 * xmlTextWriterWriteAttribute:
1912 * @writer: the xmlTextWriterPtr
1913 * @name: attribute name
1914 * @content: attribute content
1915 *
1916 * Write an xml attribute.
1917 *
1918 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1919 */
1920int
1921xmlTextWriterWriteAttribute(xmlTextWriterPtr writer, const xmlChar * name,
1922 const xmlChar * content)
1923{
1924 int count;
1925 int sum;
1926
1927 sum = 0;
1928 count = xmlTextWriterStartAttribute(writer, name);
1929 if (count < 0)
1930 return -1;
1931 sum += count;
1932 count = xmlTextWriterWriteString(writer, content);
1933 if (count < 0)
1934 return -1;
1935 sum += count;
1936 count = xmlTextWriterEndAttribute(writer);
1937 if (count < 0)
1938 return -1;
1939 sum += count;
1940
1941 return sum;
1942}
1943
1944/**
1945 * xmlTextWriterWriteFormatAttributeNS:
1946 * @writer: the xmlTextWriterPtr
1947 * @prefix: namespace prefix
1948 * @name: attribute local name
1949 * @namespaceURI: namespace URI
1950 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001951 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001952 *
1953 * Write a formatted xml attribute.with namespace support
1954 *
1955 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1956 */
1957int
1958xmlTextWriterWriteFormatAttributeNS(xmlTextWriterPtr writer,
1959 const xmlChar * prefix,
1960 const xmlChar * name,
1961 const xmlChar * namespaceURI,
1962 const char *format, ...)
1963{
1964 int rc;
1965 va_list ap;
1966
1967 va_start(ap, format);
1968
1969 rc = xmlTextWriterWriteVFormatAttributeNS(writer, prefix, name,
1970 namespaceURI, format, ap);
1971
1972 va_end(ap);
1973 return rc;
1974}
1975
1976/**
1977 * xmlTextWriterWriteVFormatAttributeNS:
1978 * @writer: the xmlTextWriterPtr
1979 * @prefix: namespace prefix
1980 * @name: attribute local name
1981 * @namespaceURI: namespace URI
1982 * @format: format string (see printf)
1983 * @argptr: pointer to the first member of the variable argument list.
1984 *
1985 * Write a formatted xml attribute.with namespace support
1986 *
1987 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1988 */
1989int
1990xmlTextWriterWriteVFormatAttributeNS(xmlTextWriterPtr writer,
1991 const xmlChar * prefix,
1992 const xmlChar * name,
1993 const xmlChar * namespaceURI,
1994 const char *format, va_list argptr)
1995{
1996 int rc;
1997 xmlChar *buf;
1998
1999 if (writer == NULL)
2000 return -1;
2001
2002 buf = xmlTextWriterVSprintf(format, argptr);
2003 if (buf == 0)
2004 return 0;
2005
2006 rc = xmlTextWriterWriteAttributeNS(writer, prefix, name, namespaceURI,
2007 buf);
2008
2009 xmlFree(buf);
2010 return rc;
2011}
2012
2013/**
2014 * xmlTextWriterWriteAttributeNS:
2015 * @writer: the xmlTextWriterPtr
2016 * @prefix: namespace prefix
2017 * @name: attribute local name
2018 * @namespaceURI: namespace URI
2019 * @content: attribute content
2020 *
2021 * Write an xml attribute.
2022 *
2023 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2024 */
2025int
2026xmlTextWriterWriteAttributeNS(xmlTextWriterPtr writer,
2027 const xmlChar * prefix, const xmlChar * name,
2028 const xmlChar * namespaceURI,
2029 const xmlChar * content)
2030{
2031 int count;
2032 int sum;
2033 xmlChar *buf;
2034
2035 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
2036 return -1;
2037
2038 buf = 0;
2039 if (prefix != NULL) {
2040 buf = xmlStrdup(prefix);
2041 buf = xmlStrcat(buf, BAD_CAST ":");
2042 }
2043 buf = xmlStrcat(buf, name);
2044
2045 sum = 0;
2046 count = xmlTextWriterWriteAttribute(writer, buf, content);
2047 xmlFree(buf);
2048 if (count < 0)
2049 return -1;
2050 sum += count;
2051
2052 if (namespaceURI != NULL) {
2053 buf = 0;
2054 buf = xmlStrdup(BAD_CAST "xmlns");
2055 if (prefix != NULL) {
2056 buf = xmlStrcat(buf, BAD_CAST ":");
2057 buf = xmlStrcat(buf, prefix);
2058 }
2059 count = xmlTextWriterWriteAttribute(writer, buf, namespaceURI);
2060 xmlFree(buf);
2061 if (count < 0)
2062 return -1;
2063 sum += count;
2064 }
2065 return sum;
2066}
2067
2068/**
2069 * xmlTextWriterWriteFormatElement:
2070 * @writer: the xmlTextWriterPtr
2071 * @name: element name
2072 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002073 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002074 *
2075 * Write a formatted xml element.
2076 *
2077 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2078 */
2079int
2080xmlTextWriterWriteFormatElement(xmlTextWriterPtr writer,
2081 const xmlChar * name, const char *format,
2082 ...)
2083{
2084 int rc;
2085 va_list ap;
2086
2087 va_start(ap, format);
2088
2089 rc = xmlTextWriterWriteVFormatElement(writer, name, format, ap);
2090
2091 va_end(ap);
2092 return rc;
2093}
2094
2095/**
2096 * xmlTextWriterWriteVFormatElement:
2097 * @writer: the xmlTextWriterPtr
2098 * @name: element name
2099 * @format: format string (see printf)
2100 * @argptr: pointer to the first member of the variable argument list.
2101 *
2102 * Write a formatted xml element.
2103 *
2104 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2105 */
2106int
2107xmlTextWriterWriteVFormatElement(xmlTextWriterPtr writer,
2108 const xmlChar * name, const char *format,
2109 va_list argptr)
2110{
2111 int rc;
2112 xmlChar *buf;
2113
2114 if (writer == NULL)
2115 return -1;
2116
2117 buf = xmlTextWriterVSprintf(format, argptr);
2118 if (buf == 0)
2119 return 0;
2120
2121 rc = xmlTextWriterWriteElement(writer, name, buf);
2122
2123 xmlFree(buf);
2124 return rc;
2125}
2126
2127/**
2128 * xmlTextWriterWriteElement:
2129 * @writer: the xmlTextWriterPtr
2130 * @name: element name
2131 * @content: element content
2132 *
2133 * Write an xml element.
2134 *
2135 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2136 */
2137int
2138xmlTextWriterWriteElement(xmlTextWriterPtr writer, const xmlChar * name,
2139 const xmlChar * content)
2140{
2141 int count;
2142 int sum;
2143
2144 sum = 0;
2145 count = xmlTextWriterStartElement(writer, name);
2146 if (count == -1)
2147 return -1;
2148 sum += count;
2149 count = xmlTextWriterWriteString(writer, content);
2150 if (count == -1)
2151 return -1;
2152 sum += count;
2153 count = xmlTextWriterEndElement(writer);
2154 if (count == -1)
2155 return -1;
2156 sum += count;
2157
2158 return sum;
2159}
2160
2161/**
2162 * xmlTextWriterWriteFormatElementNS:
2163 * @writer: the xmlTextWriterPtr
2164 * @prefix: namespace prefix
2165 * @name: element local name
2166 * @namespaceURI: namespace URI
2167 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002168 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002169 *
2170 * Write a formatted xml element with namespace support.
2171 *
2172 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2173 */
2174int
2175xmlTextWriterWriteFormatElementNS(xmlTextWriterPtr writer,
2176 const xmlChar * prefix,
2177 const xmlChar * name,
2178 const xmlChar * namespaceURI,
2179 const char *format, ...)
2180{
2181 int rc;
2182 va_list ap;
2183
2184 va_start(ap, format);
2185
2186 rc = xmlTextWriterWriteVFormatElementNS(writer, prefix, name,
2187 namespaceURI, format, ap);
2188
2189 va_end(ap);
2190 return rc;
2191}
2192
2193/**
2194 * xmlTextWriterWriteVFormatElementNS:
2195 * @writer: the xmlTextWriterPtr
2196 * @prefix: namespace prefix
2197 * @name: element local name
2198 * @namespaceURI: namespace URI
2199 * @format: format string (see printf)
2200 * @argptr: pointer to the first member of the variable argument list.
2201 *
2202 * Write a formatted xml element with namespace support.
2203 *
2204 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2205 */
2206int
2207xmlTextWriterWriteVFormatElementNS(xmlTextWriterPtr writer,
2208 const xmlChar * prefix,
2209 const xmlChar * name,
2210 const xmlChar * namespaceURI,
2211 const char *format, va_list argptr)
2212{
2213 int rc;
2214 xmlChar *buf;
2215
2216 if (writer == NULL)
2217 return -1;
2218
2219 buf = xmlTextWriterVSprintf(format, argptr);
2220 if (buf == 0)
2221 return 0;
2222
2223 rc = xmlTextWriterWriteElementNS(writer, prefix, name, namespaceURI,
2224 buf);
2225
2226 xmlFree(buf);
2227 return rc;
2228}
2229
2230/**
2231 * xmlTextWriterWriteElementNS:
2232 * @writer: the xmlTextWriterPtr
2233 * @prefix: namespace prefix
2234 * @name: element local name
2235 * @namespaceURI: namespace URI
2236 * @content: element content
2237 *
2238 * Write an xml element with namespace support.
2239 *
2240 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2241 */
2242int
2243xmlTextWriterWriteElementNS(xmlTextWriterPtr writer,
2244 const xmlChar * prefix, const xmlChar * name,
2245 const xmlChar * namespaceURI,
2246 const xmlChar * content)
2247{
2248 int count;
2249 int sum;
2250
2251 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
2252 return -1;
2253
2254 sum = 0;
2255 count =
2256 xmlTextWriterStartElementNS(writer, prefix, name, namespaceURI);
2257 if (count < 0)
2258 return -1;
2259 sum += count;
2260 count = xmlTextWriterWriteString(writer, content);
2261 if (count == -1)
2262 return -1;
2263 sum += count;
2264 count = xmlTextWriterEndElement(writer);
2265 if (count == -1)
2266 return -1;
2267 sum += count;
2268
2269 return sum;
2270}
2271
2272/**
2273 * xmlTextWriterStartPI:
2274 * @writer: the xmlTextWriterPtr
2275 * @target: PI target
2276 *
2277 * Start an xml PI.
2278 *
2279 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2280 */
2281int
2282xmlTextWriterStartPI(xmlTextWriterPtr writer, const xmlChar * target)
2283{
2284 int count;
2285 int sum;
2286 xmlLinkPtr lk;
2287 xmlTextWriterStackEntry *p;
2288
2289 if ((writer == NULL) || (target == NULL) || (*target == '\0'))
2290 return -1;
2291
2292 if (xmlStrcasecmp(target, (const xmlChar *) "xml") == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002293 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002294 "xmlTextWriterStartPI : target name [Xx][Mm][Ll] is reserved for xml standardization!\n");
2295 return -1;
2296 }
2297
2298 sum = 0;
2299 lk = xmlListFront(writer->nodes);
2300 if (lk != 0) {
2301 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2302 if (p != 0) {
2303 switch (p->state) {
2304 case XML_TEXTWRITER_ATTRIBUTE:
2305 count = xmlTextWriterEndAttribute(writer);
2306 if (count < 0)
2307 return -1;
2308 sum += count;
2309 /* fallthrough */
2310 case XML_TEXTWRITER_NAME:
2311 count = xmlOutputBufferWriteString(writer->out, ">");
2312 if (count < 0)
2313 return -1;
2314 sum += count;
2315 p->state = XML_TEXTWRITER_TEXT;
2316 break;
Daniel Veillardab69f362004-02-17 11:40:32 +00002317 case XML_TEXTWRITER_NONE:
2318 case XML_TEXTWRITER_TEXT:
2319 case XML_TEXTWRITER_DTD:
2320 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002321 case XML_TEXTWRITER_PI:
2322 case XML_TEXTWRITER_PI_TEXT:
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002323 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002324 "xmlTextWriterStartPI : nested PI!\n");
2325 return -1;
2326 default:
2327 return -1;
2328 }
2329 }
2330 }
2331
2332 p = (xmlTextWriterStackEntry *)
2333 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2334 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002335 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002336 "xmlTextWriterStartPI : out of memory!\n");
2337 return -1;
2338 }
2339
2340 p->name = xmlStrdup(target);
2341 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002342 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002343 "xmlTextWriterStartPI : out of memory!\n");
2344 xmlFree(p);
2345 return -1;
2346 }
2347 p->state = XML_TEXTWRITER_PI;
2348
2349 xmlListPushFront(writer->nodes, p);
2350
2351 count = xmlOutputBufferWriteString(writer->out, "<?");
2352 if (count < 0)
2353 return -1;
2354 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002355 count =
2356 xmlOutputBufferWriteString(writer->out, (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002357 if (count < 0)
2358 return -1;
2359 sum += count;
2360
2361 return sum;
2362}
2363
2364/**
2365 * xmlTextWriterEndPI:
2366 * @writer: the xmlTextWriterPtr
2367 *
2368 * End the current xml PI.
2369 *
2370 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2371 */
2372int
2373xmlTextWriterEndPI(xmlTextWriterPtr writer)
2374{
2375 int count;
2376 int sum;
2377 xmlLinkPtr lk;
2378 xmlTextWriterStackEntry *p;
2379
2380 if (writer == NULL)
2381 return -1;
2382
2383 lk = xmlListFront(writer->nodes);
2384 if (lk == 0)
2385 return 0;
2386
2387 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2388 if (p == 0)
2389 return 0;
2390
2391 sum = 0;
2392 switch (p->state) {
2393 case XML_TEXTWRITER_PI:
2394 case XML_TEXTWRITER_PI_TEXT:
2395 count = xmlOutputBufferWriteString(writer->out, "?>");
2396 if (count < 0)
2397 return -1;
2398 sum += count;
2399 break;
2400 default:
2401 return -1;
2402 }
2403
2404 xmlListPopFront(writer->nodes);
2405 return sum;
2406}
2407
2408/**
2409 * xmlTextWriterWriteFormatPI:
2410 * @writer: the xmlTextWriterPtr
2411 * @target: PI target
2412 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002413 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002414 *
2415 * Write a formatted PI.
2416 *
2417 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2418 */
2419int
2420xmlTextWriterWriteFormatPI(xmlTextWriterPtr writer, const xmlChar * target,
2421 const char *format, ...)
2422{
2423 int rc;
2424 va_list ap;
2425
2426 va_start(ap, format);
2427
2428 rc = xmlTextWriterWriteVFormatPI(writer, target, format, ap);
2429
2430 va_end(ap);
2431 return rc;
2432}
2433
2434/**
2435 * xmlTextWriterWriteVFormatPI:
2436 * @writer: the xmlTextWriterPtr
2437 * @target: PI target
2438 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002439 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00002440 *
2441 * Write a formatted xml PI.
2442 *
2443 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2444 */
2445int
2446xmlTextWriterWriteVFormatPI(xmlTextWriterPtr writer,
2447 const xmlChar * target, const char *format,
2448 va_list argptr)
2449{
2450 int rc;
2451 xmlChar *buf;
2452
2453 if (writer == NULL)
2454 return -1;
2455
2456 buf = xmlTextWriterVSprintf(format, argptr);
2457 if (buf == 0)
2458 return 0;
2459
2460 rc = xmlTextWriterWritePI(writer, target, buf);
2461
2462 xmlFree(buf);
2463 return rc;
2464}
2465
2466/**
2467 * xmlTextWriterWritePI:
2468 * @writer: the xmlTextWriterPtr
2469 * @target: PI target
2470 * @content: PI content
2471 *
2472 * Write an xml PI.
2473 *
2474 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2475 */
2476int
2477xmlTextWriterWritePI(xmlTextWriterPtr writer, const xmlChar * target,
2478 const xmlChar * content)
2479{
2480 int count;
2481 int sum;
2482
2483 sum = 0;
2484 count = xmlTextWriterStartPI(writer, target);
2485 if (count == -1)
2486 return -1;
2487 sum += count;
2488 if (content != 0) {
2489 count = xmlTextWriterWriteString(writer, content);
2490 if (count == -1)
2491 return -1;
2492 sum += count;
2493 }
2494 count = xmlTextWriterEndPI(writer);
2495 if (count == -1)
2496 return -1;
2497 sum += count;
2498
2499 return sum;
2500}
2501
2502/**
2503 * xmlTextWriterStartCDATA:
2504 * @writer: the xmlTextWriterPtr
2505 *
2506 * Start an xml CDATA section.
2507 *
2508 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2509 */
2510int
2511xmlTextWriterStartCDATA(xmlTextWriterPtr writer)
2512{
2513 int count;
2514 int sum;
2515 xmlLinkPtr lk;
2516 xmlTextWriterStackEntry *p;
2517
2518 if (writer == NULL)
2519 return -1;
2520
2521 sum = 0;
2522 lk = xmlListFront(writer->nodes);
2523 if (lk != 0) {
2524 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2525 if (p != 0) {
2526 switch (p->state) {
2527 case XML_TEXTWRITER_NONE:
2528 case XML_TEXTWRITER_PI:
2529 case XML_TEXTWRITER_PI_TEXT:
2530 break;
2531 case XML_TEXTWRITER_ATTRIBUTE:
2532 count = xmlTextWriterEndAttribute(writer);
2533 if (count < 0)
2534 return -1;
2535 sum += count;
2536 /* fallthrough */
2537 case XML_TEXTWRITER_NAME:
2538 count = xmlOutputBufferWriteString(writer->out, ">");
2539 if (count < 0)
2540 return -1;
2541 sum += count;
2542 p->state = XML_TEXTWRITER_TEXT;
2543 break;
2544 case XML_TEXTWRITER_CDATA:
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002545 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002546 "xmlTextWriterStartCDATA : CDATA not allowed in this context!\n");
2547 return -1;
2548 default:
2549 return -1;
2550 }
2551 }
2552 }
2553
2554 p = (xmlTextWriterStackEntry *)
2555 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2556 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002557 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002558 "xmlTextWriterStartCDATA : out of memory!\n");
2559 return -1;
2560 }
2561
2562 p->name = 0;
2563 p->state = XML_TEXTWRITER_CDATA;
2564
2565 xmlListPushFront(writer->nodes, p);
2566
2567 count = xmlOutputBufferWriteString(writer->out, "<![CDATA[");
2568 if (count < 0)
2569 return -1;
2570 sum += count;
2571
2572 return sum;
2573}
2574
2575/**
2576 * xmlTextWriterEndCDATA:
2577 * @writer: the xmlTextWriterPtr
2578 *
2579 * End an xml CDATA section.
2580 *
2581 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2582 */
2583int
2584xmlTextWriterEndCDATA(xmlTextWriterPtr writer)
2585{
2586 int count;
2587 int sum;
2588 xmlLinkPtr lk;
2589 xmlTextWriterStackEntry *p;
2590
2591 if (writer == NULL)
2592 return -1;
2593
2594 lk = xmlListFront(writer->nodes);
2595 if (lk == 0)
2596 return -1;
2597
2598 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2599 if (p == 0)
2600 return -1;
2601
2602 sum = 0;
2603 switch (p->state) {
2604 case XML_TEXTWRITER_CDATA:
2605 count = xmlOutputBufferWriteString(writer->out, "]]>");
2606 if (count < 0)
2607 return -1;
2608 sum += count;
2609 break;
2610 default:
2611 return -1;
2612 }
2613
2614 xmlListPopFront(writer->nodes);
2615 return sum;
2616}
2617
2618/**
2619 * xmlTextWriterWriteFormatCDATA:
2620 * @writer: the xmlTextWriterPtr
2621 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002622 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002623 *
2624 * Write a formatted xml CDATA.
2625 *
2626 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2627 */
2628int
2629xmlTextWriterWriteFormatCDATA(xmlTextWriterPtr writer, const char *format,
2630 ...)
2631{
2632 int rc;
2633 va_list ap;
2634
2635 va_start(ap, format);
2636
2637 rc = xmlTextWriterWriteVFormatCDATA(writer, format, ap);
2638
2639 va_end(ap);
2640 return rc;
2641}
2642
2643/**
2644 * xmlTextWriterWriteVFormatCDATA:
2645 * @writer: the xmlTextWriterPtr
2646 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002647 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00002648 *
2649 * Write a formatted xml CDATA.
2650 *
2651 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2652 */
2653int
2654xmlTextWriterWriteVFormatCDATA(xmlTextWriterPtr writer, const char *format,
2655 va_list argptr)
2656{
2657 int rc;
2658 xmlChar *buf;
2659
2660 if (writer == NULL)
2661 return -1;
2662
2663 buf = xmlTextWriterVSprintf(format, argptr);
2664 if (buf == 0)
2665 return 0;
2666
2667 rc = xmlTextWriterWriteCDATA(writer, buf);
2668
2669 xmlFree(buf);
2670 return rc;
2671}
2672
2673/**
2674 * xmlTextWriterWriteCDATA:
2675 * @writer: the xmlTextWriterPtr
2676 * @content: CDATA content
2677 *
2678 * Write an xml CDATA.
2679 *
2680 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2681 */
2682int
2683xmlTextWriterWriteCDATA(xmlTextWriterPtr writer, const xmlChar * content)
2684{
2685 int count;
2686 int sum;
2687
2688 sum = 0;
2689 count = xmlTextWriterStartCDATA(writer);
2690 if (count == -1)
2691 return -1;
2692 sum += count;
2693 if (content != 0) {
2694 count = xmlTextWriterWriteString(writer, content);
2695 if (count == -1)
2696 return -1;
2697 sum += count;
2698 }
2699 count = xmlTextWriterEndCDATA(writer);
2700 if (count == -1)
2701 return -1;
2702 sum += count;
2703
2704 return sum;
2705}
2706
2707/**
2708 * xmlTextWriterStartDTD:
2709 * @writer: the xmlTextWriterPtr
2710 * @name: the name of the DTD
2711 * @pubid: the public identifier, which is an alternative to the system identifier
2712 * @sysid: the system identifier, which is the URI of the DTD
2713 *
2714 * Start an xml DTD.
2715 *
2716 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2717 */
2718int
2719xmlTextWriterStartDTD(xmlTextWriterPtr writer,
2720 const xmlChar * name,
2721 const xmlChar * pubid, const xmlChar * sysid)
2722{
2723 int count;
2724 int sum;
2725 xmlLinkPtr lk;
2726 xmlTextWriterStackEntry *p;
2727
2728 if (writer == NULL || name == NULL || *name == '\0')
2729 return -1;
2730
2731 sum = 0;
2732 lk = xmlListFront(writer->nodes);
Daniel Veillardab69f362004-02-17 11:40:32 +00002733 if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002734 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002735 "xmlTextWriterStartDTD : DTD allowed only in prolog!\n");
2736 return -1;
2737 }
2738
2739 p = (xmlTextWriterStackEntry *)
2740 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2741 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002742 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002743 "xmlTextWriterStartDTD : out of memory!\n");
2744 return -1;
2745 }
2746
2747 p->name = xmlStrdup(name);
2748 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002749 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002750 "xmlTextWriterStartDTD : out of memory!\n");
2751 xmlFree(p);
2752 return -1;
2753 }
2754 p->state = XML_TEXTWRITER_DTD;
2755
2756 xmlListPushFront(writer->nodes, p);
2757
2758 count = xmlOutputBufferWriteString(writer->out, "<!DOCTYPE ");
2759 if (count < 0)
2760 return -1;
2761 sum += count;
2762 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
2763 if (count < 0)
2764 return -1;
2765 sum += count;
2766
2767 if (pubid != 0) {
2768 if (sysid == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002769 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002770 "xmlTextWriterStartDTD : system identifier needed!\n");
2771 return -1;
2772 }
2773
Daniel Veillard500a1de2004-03-22 15:22:58 +00002774 if (writer->indent)
2775 count = xmlOutputBufferWrite(writer->out, 1, "\n");
2776 else
2777 count = xmlOutputBufferWrite(writer->out, 1, " ");
2778 if (count < 0)
2779 return -1;
2780 sum += count;
2781
2782 count = xmlOutputBufferWriteString(writer->out, "PUBLIC ");
2783 if (count < 0)
2784 return -1;
2785 sum += count;
2786
2787 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002788 if (count < 0)
2789 return -1;
2790 sum += count;
2791
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002792 count =
2793 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002794 if (count < 0)
2795 return -1;
2796 sum += count;
2797
Daniel Veillard500a1de2004-03-22 15:22:58 +00002798 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002799 if (count < 0)
2800 return -1;
2801 sum += count;
2802 }
2803
2804 if (sysid != 0) {
2805 if (pubid == 0) {
Daniel Veillard500a1de2004-03-22 15:22:58 +00002806 if (writer->indent)
2807 count = xmlOutputBufferWrite(writer->out, 1, "\n");
2808 else
2809 count = xmlOutputBufferWrite(writer->out, 1, " ");
2810 if (count < 0)
2811 return -1;
2812 sum += count;
2813 count = xmlOutputBufferWriteString(writer->out, "SYSTEM ");
2814 if (count < 0)
2815 return -1;
2816 sum += count;
2817 } else if (writer->indent) {
2818 count = xmlOutputBufferWriteString(writer->out, "\n ");
Daniel Veillard1d211e22003-10-20 22:32:39 +00002819 if (count < 0)
2820 return -1;
2821 sum += count;
2822 }
2823
Daniel Veillard500a1de2004-03-22 15:22:58 +00002824 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002825 if (count < 0)
2826 return -1;
2827 sum += count;
2828
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002829 count =
2830 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002831 if (count < 0)
2832 return -1;
2833 sum += count;
2834
Daniel Veillard500a1de2004-03-22 15:22:58 +00002835 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002836 if (count < 0)
2837 return -1;
2838 sum += count;
2839 }
2840
2841 return sum;
2842}
2843
2844/**
2845 * xmlTextWriterEndDTD:
2846 * @writer: the xmlTextWriterPtr
2847 *
2848 * End an xml DTD.
2849 *
2850 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2851 */
2852int
2853xmlTextWriterEndDTD(xmlTextWriterPtr writer)
2854{
Daniel Veillard500a1de2004-03-22 15:22:58 +00002855 int loop;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002856 int count;
2857 int sum;
2858 xmlLinkPtr lk;
2859 xmlTextWriterStackEntry *p;
2860
2861 if (writer == NULL)
2862 return -1;
2863
2864 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00002865 loop = 1;
2866 while (loop) {
2867 lk = xmlListFront(writer->nodes);
2868 if (lk == NULL)
Daniel Veillard1d211e22003-10-20 22:32:39 +00002869 break;
Daniel Veillard500a1de2004-03-22 15:22:58 +00002870 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2871 if (p == 0)
2872 break;
2873 switch (p->state) {
2874 case XML_TEXTWRITER_DTD_TEXT:
2875 count = xmlOutputBufferWriteString(writer->out, "]");
2876 if (count < 0)
2877 return -1;
2878 sum += count;
2879 /* fallthrough */
2880 case XML_TEXTWRITER_DTD:
2881 count = xmlOutputBufferWriteString(writer->out, ">");
2882
2883 if (writer->indent) {
2884 if (count < 0)
2885 return -1;
2886 sum += count;
2887 count = xmlOutputBufferWriteString(writer->out, "\n");
2888 }
2889
2890 xmlListPopFront(writer->nodes);
2891 break;
2892 case XML_TEXTWRITER_DTD_ELEM:
2893 case XML_TEXTWRITER_DTD_ELEM_TEXT:
2894 count = xmlTextWriterEndDTDElement(writer);
2895 break;
2896 case XML_TEXTWRITER_DTD_ATTL:
2897 case XML_TEXTWRITER_DTD_ATTL_TEXT:
2898 count = xmlTextWriterEndDTDAttlist(writer);
2899 break;
2900 case XML_TEXTWRITER_DTD_ENTY:
2901 case XML_TEXTWRITER_DTD_PENT:
2902 case XML_TEXTWRITER_DTD_ENTY_TEXT:
2903 count = xmlTextWriterEndDTDEntity(writer);
2904 break;
2905 case XML_TEXTWRITER_COMMENT:
2906 count = xmlTextWriterEndComment(writer);
2907 break;
2908 default:
2909 loop = 0;
2910 continue;
2911 }
2912
2913 if (count < 0)
Daniel Veillard1d211e22003-10-20 22:32:39 +00002914 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00002915 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002916 }
2917
Daniel Veillard1d211e22003-10-20 22:32:39 +00002918 return sum;
2919}
2920
2921/**
2922 * xmlTextWriterWriteFormatDTD:
2923 * @writer: the xmlTextWriterPtr
2924 * @name: the name of the DTD
2925 * @pubid: the public identifier, which is an alternative to the system identifier
2926 * @sysid: the system identifier, which is the URI of the DTD
2927 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002928 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002929 *
2930 * Write a DTD with a formatted markup declarations part.
2931 *
2932 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2933 */
2934int
2935xmlTextWriterWriteFormatDTD(xmlTextWriterPtr writer,
2936 const xmlChar * name,
2937 const xmlChar * pubid,
2938 const xmlChar * sysid, const char *format, ...)
2939{
2940 int rc;
2941 va_list ap;
2942
2943 va_start(ap, format);
2944
2945 rc = xmlTextWriterWriteVFormatDTD(writer, name, pubid, sysid, format,
2946 ap);
2947
2948 va_end(ap);
2949 return rc;
2950}
2951
2952/**
2953 * xmlTextWriterWriteVFormatDTD:
2954 * @writer: the xmlTextWriterPtr
2955 * @name: the name of the DTD
2956 * @pubid: the public identifier, which is an alternative to the system identifier
2957 * @sysid: the system identifier, which is the URI of the DTD
2958 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002959 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00002960 *
2961 * Write a DTD with a formatted markup declarations part.
2962 *
2963 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2964 */
2965int
2966xmlTextWriterWriteVFormatDTD(xmlTextWriterPtr writer,
2967 const xmlChar * name,
2968 const xmlChar * pubid,
2969 const xmlChar * sysid,
2970 const char *format, va_list argptr)
2971{
2972 int rc;
2973 xmlChar *buf;
2974
2975 if (writer == NULL)
2976 return -1;
2977
2978 buf = xmlTextWriterVSprintf(format, argptr);
2979 if (buf == 0)
2980 return 0;
2981
2982 rc = xmlTextWriterWriteDTD(writer, name, pubid, sysid, buf);
2983
2984 xmlFree(buf);
2985 return rc;
2986}
2987
2988/**
2989 * xmlTextWriterWriteDTD:
2990 * @writer: the xmlTextWriterPtr
2991 * @name: the name of the DTD
2992 * @pubid: the public identifier, which is an alternative to the system identifier
2993 * @sysid: the system identifier, which is the URI of the DTD
William M. Brackb1d53162003-11-18 06:54:40 +00002994 * @subset: string content of the DTD
Daniel Veillard1d211e22003-10-20 22:32:39 +00002995 *
2996 * Write a DTD.
2997 *
2998 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2999 */
3000int
3001xmlTextWriterWriteDTD(xmlTextWriterPtr writer,
3002 const xmlChar * name,
3003 const xmlChar * pubid,
3004 const xmlChar * sysid, const xmlChar * subset)
3005{
3006 int count;
3007 int sum;
3008
3009 sum = 0;
3010 count = xmlTextWriterStartDTD(writer, name, pubid, sysid);
3011 if (count == -1)
3012 return -1;
3013 sum += count;
3014 if (subset != 0) {
3015 count = xmlTextWriterWriteString(writer, subset);
3016 if (count == -1)
3017 return -1;
3018 sum += count;
3019 }
3020 count = xmlTextWriterEndDTD(writer);
3021 if (count == -1)
3022 return -1;
3023 sum += count;
3024
3025 return sum;
3026}
3027
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003028/**
3029 * xmlTextWriterStartDTDElement:
3030 * @writer: the xmlTextWriterPtr
3031 * @name: the name of the DTD element
3032 *
3033 * Start an xml DTD element.
3034 *
3035 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3036 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003037int
3038xmlTextWriterStartDTDElement(xmlTextWriterPtr writer, const xmlChar * name)
3039{
3040 int count;
3041 int sum;
3042 xmlLinkPtr lk;
3043 xmlTextWriterStackEntry *p;
3044
3045 if (writer == NULL || name == NULL || *name == '\0')
3046 return -1;
3047
3048 sum = 0;
3049 lk = xmlListFront(writer->nodes);
3050 if (lk == 0) {
3051 return -1;
3052 }
3053
3054 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
Daniel Veillard500a1de2004-03-22 15:22:58 +00003055 if (p != 0) {
3056 switch (p->state) {
3057 case XML_TEXTWRITER_DTD:
3058 count = xmlOutputBufferWriteString(writer->out, " [");
3059 if (count < 0)
3060 return -1;
3061 sum += count;
3062 if (writer->indent) {
3063 count = xmlOutputBufferWriteString(writer->out, "\n");
3064 if (count < 0)
3065 return -1;
3066 sum += count;
3067 }
3068 p->state = XML_TEXTWRITER_DTD_TEXT;
3069 /* fallthrough */
3070 case XML_TEXTWRITER_DTD_TEXT:
3071 case XML_TEXTWRITER_NONE:
3072 break;
3073 default:
Daniel Veillard1d211e22003-10-20 22:32:39 +00003074 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00003075 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00003076 }
3077
3078 p = (xmlTextWriterStackEntry *)
3079 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3080 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003081 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003082 "xmlTextWriterStartDTDElement : out of memory!\n");
3083 return -1;
3084 }
3085
3086 p->name = xmlStrdup(name);
3087 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003088 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003089 "xmlTextWriterStartDTDElement : out of memory!\n");
3090 xmlFree(p);
3091 return -1;
3092 }
3093 p->state = XML_TEXTWRITER_DTD_ELEM;
3094
3095 xmlListPushFront(writer->nodes, p);
3096
Daniel Veillard500a1de2004-03-22 15:22:58 +00003097 if (writer->indent) {
3098 count = xmlTextWriterWriteIndent(writer);
3099 if (count < 0)
3100 return -1;
3101 sum += count;
3102 }
3103
Daniel Veillard1d211e22003-10-20 22:32:39 +00003104 count = xmlOutputBufferWriteString(writer->out, "<!ELEMENT ");
3105 if (count < 0)
3106 return -1;
3107 sum += count;
3108 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
3109 if (count < 0)
3110 return -1;
3111 sum += count;
3112
3113 return sum;
3114}
3115
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003116/**
Daniel Veillard500a1de2004-03-22 15:22:58 +00003117 * xmlTextWriterEndDTDElement:
3118 * @writer: the xmlTextWriterPtr
3119 *
3120 * End an xml DTD element.
3121 *
3122 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3123 */
3124int
3125xmlTextWriterEndDTDElement(xmlTextWriterPtr writer)
3126{
3127 int count;
3128 int sum;
3129 xmlLinkPtr lk;
3130 xmlTextWriterStackEntry *p;
3131
3132 if (writer == NULL)
3133 return -1;
3134
3135 sum = 0;
3136 lk = xmlListFront(writer->nodes);
3137 if (lk == 0)
3138 return -1;
3139
3140 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3141 if (p == 0)
3142 return -1;
3143
3144 switch (p->state) {
3145 case XML_TEXTWRITER_DTD_ELEM:
3146 case XML_TEXTWRITER_DTD_ELEM_TEXT:
3147 count = xmlOutputBufferWriteString(writer->out, ">");
3148 if (count < 0)
3149 return -1;
3150 sum += count;
3151 break;
3152 default:
3153 return -1;
3154 }
3155
3156 if (writer->indent) {
3157 count = xmlOutputBufferWriteString(writer->out, "\n");
3158 if (count < 0)
3159 return -1;
3160 sum += count;
3161 }
3162
3163 xmlListPopFront(writer->nodes);
3164 return sum;
3165}
3166
3167/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003168 * xmlTextWriterWriteFormatDTDElement:
3169 * @writer: the xmlTextWriterPtr
3170 * @name: the name of the DTD element
3171 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003172 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003173 *
3174 * Write a formatted DTD element.
3175 *
3176 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3177 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003178int
3179xmlTextWriterWriteFormatDTDElement(xmlTextWriterPtr writer,
3180 const xmlChar * name,
3181 const char *format, ...)
3182{
3183 int rc;
3184 va_list ap;
3185
3186 va_start(ap, format);
3187
3188 rc = xmlTextWriterWriteVFormatDTDElement(writer, name, format, ap);
3189
3190 va_end(ap);
3191 return rc;
3192}
3193
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003194/**
3195 * xmlTextWriterWriteVFormatDTDElement:
3196 * @writer: the xmlTextWriterPtr
3197 * @name: the name of the DTD element
3198 * @format: format string (see printf)
3199 * @argptr: pointer to the first member of the variable argument list.
3200 *
3201 * Write a formatted DTD element.
3202 *
3203 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3204 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003205int
3206xmlTextWriterWriteVFormatDTDElement(xmlTextWriterPtr writer,
3207 const xmlChar * name,
3208 const char *format, va_list argptr)
3209{
3210 int rc;
3211 xmlChar *buf;
3212
3213 if (writer == NULL)
3214 return -1;
3215
3216 buf = xmlTextWriterVSprintf(format, argptr);
3217 if (buf == 0)
3218 return 0;
3219
3220 rc = xmlTextWriterWriteDTDElement(writer, name, buf);
3221
3222 xmlFree(buf);
3223 return rc;
3224}
3225
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003226/**
3227 * xmlTextWriterWriteDTDElement:
3228 * @writer: the xmlTextWriterPtr
3229 * @name: the name of the DTD element
3230 * @content: content of the element
3231 *
3232 * Write a DTD element.
3233 *
3234 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3235 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003236int
3237xmlTextWriterWriteDTDElement(xmlTextWriterPtr writer,
3238 const xmlChar * name, const xmlChar * content)
3239{
3240 int count;
3241 int sum;
3242
3243 if (content == NULL)
3244 return -1;
3245
3246 sum = 0;
3247 count = xmlTextWriterStartDTDElement(writer, name);
3248 if (count == -1)
3249 return -1;
3250 sum += count;
3251
Daniel Veillard1d211e22003-10-20 22:32:39 +00003252 count = xmlTextWriterWriteString(writer, content);
3253 if (count == -1)
3254 return -1;
3255 sum += count;
3256
3257 count = xmlTextWriterEndDTDElement(writer);
3258 if (count == -1)
3259 return -1;
3260 sum += count;
3261
3262 return sum;
3263}
3264
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003265/**
3266 * xmlTextWriterStartDTDAttlist:
3267 * @writer: the xmlTextWriterPtr
3268 * @name: the name of the DTD ATTLIST
3269 *
3270 * Start an xml DTD ATTLIST.
3271 *
3272 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3273 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003274int
3275xmlTextWriterStartDTDAttlist(xmlTextWriterPtr writer, const xmlChar * name)
3276{
3277 int count;
3278 int sum;
3279 xmlLinkPtr lk;
3280 xmlTextWriterStackEntry *p;
3281
3282 if (writer == NULL || name == NULL || *name == '\0')
3283 return -1;
3284
3285 sum = 0;
3286 lk = xmlListFront(writer->nodes);
3287 if (lk == 0) {
3288 return -1;
3289 }
3290
3291 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
Daniel Veillard500a1de2004-03-22 15:22:58 +00003292 if (p != 0) {
3293 switch (p->state) {
3294 case XML_TEXTWRITER_DTD:
3295 count = xmlOutputBufferWriteString(writer->out, " [");
3296 if (count < 0)
3297 return -1;
3298 sum += count;
3299 if (writer->indent) {
3300 count = xmlOutputBufferWriteString(writer->out, "\n");
3301 if (count < 0)
3302 return -1;
3303 sum += count;
3304 }
3305 p->state = XML_TEXTWRITER_DTD_TEXT;
3306 /* fallthrough */
3307 case XML_TEXTWRITER_DTD_TEXT:
3308 case XML_TEXTWRITER_NONE:
3309 break;
3310 default:
Daniel Veillard1d211e22003-10-20 22:32:39 +00003311 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00003312 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00003313 }
3314
3315 p = (xmlTextWriterStackEntry *)
3316 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3317 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003318 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003319 "xmlTextWriterStartDTDAttlist : out of memory!\n");
3320 return -1;
3321 }
3322
3323 p->name = xmlStrdup(name);
3324 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003325 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003326 "xmlTextWriterStartDTDAttlist : out of memory!\n");
3327 xmlFree(p);
3328 return -1;
3329 }
3330 p->state = XML_TEXTWRITER_DTD_ATTL;
3331
3332 xmlListPushFront(writer->nodes, p);
3333
Daniel Veillard500a1de2004-03-22 15:22:58 +00003334 if (writer->indent) {
3335 count = xmlTextWriterWriteIndent(writer);
3336 if (count < 0)
3337 return -1;
3338 sum += count;
3339 }
3340
Daniel Veillard1d211e22003-10-20 22:32:39 +00003341 count = xmlOutputBufferWriteString(writer->out, "<!ATTLIST ");
3342 if (count < 0)
3343 return -1;
3344 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +00003345 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003346 if (count < 0)
3347 return -1;
3348 sum += count;
3349
3350 return sum;
3351}
3352
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003353/**
Daniel Veillard500a1de2004-03-22 15:22:58 +00003354 * xmlTextWriterEndDTDAttlist:
3355 * @writer: the xmlTextWriterPtr
3356 *
3357 * End an xml DTD attribute list.
3358 *
3359 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3360 */
3361int
3362xmlTextWriterEndDTDAttlist(xmlTextWriterPtr writer)
3363{
3364 int count;
3365 int sum;
3366 xmlLinkPtr lk;
3367 xmlTextWriterStackEntry *p;
3368
3369 if (writer == NULL)
3370 return -1;
3371
3372 sum = 0;
3373 lk = xmlListFront(writer->nodes);
3374 if (lk == 0)
3375 return -1;
3376
3377 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3378 if (p == 0)
3379 return -1;
3380
3381 switch (p->state) {
3382 case XML_TEXTWRITER_DTD_ATTL:
3383 case XML_TEXTWRITER_DTD_ATTL_TEXT:
3384 count = xmlOutputBufferWriteString(writer->out, ">");
3385 if (count < 0)
3386 return -1;
3387 sum += count;
3388 break;
3389 default:
3390 return -1;
3391 }
3392
3393 if (writer->indent) {
3394 count = xmlOutputBufferWriteString(writer->out, "\n");
3395 if (count < 0)
3396 return -1;
3397 sum += count;
3398 }
3399
3400 xmlListPopFront(writer->nodes);
3401 return sum;
3402}
3403
3404/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003405 * xmlTextWriterWriteFormatDTDAttlist:
3406 * @writer: the xmlTextWriterPtr
3407 * @name: the name of the DTD ATTLIST
3408 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003409 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003410 *
3411 * Write a formatted DTD ATTLIST.
3412 *
3413 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3414 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003415int
3416xmlTextWriterWriteFormatDTDAttlist(xmlTextWriterPtr writer,
3417 const xmlChar * name,
3418 const char *format, ...)
3419{
3420 int rc;
3421 va_list ap;
3422
3423 va_start(ap, format);
3424
3425 rc = xmlTextWriterWriteVFormatDTDAttlist(writer, name, format, ap);
3426
3427 va_end(ap);
3428 return rc;
3429}
3430
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003431/**
3432 * xmlTextWriterWriteVFormatDTDAttlist:
3433 * @writer: the xmlTextWriterPtr
3434 * @name: the name of the DTD ATTLIST
3435 * @format: format string (see printf)
3436 * @argptr: pointer to the first member of the variable argument list.
3437 *
3438 * Write a formatted DTD ATTLIST.
3439 *
3440 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3441 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003442int
3443xmlTextWriterWriteVFormatDTDAttlist(xmlTextWriterPtr writer,
3444 const xmlChar * name,
3445 const char *format, va_list argptr)
3446{
3447 int rc;
3448 xmlChar *buf;
3449
3450 if (writer == NULL)
3451 return -1;
3452
3453 buf = xmlTextWriterVSprintf(format, argptr);
3454 if (buf == 0)
3455 return 0;
3456
3457 rc = xmlTextWriterWriteDTDAttlist(writer, name, buf);
3458
3459 xmlFree(buf);
3460 return rc;
3461}
3462
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003463/**
3464 * xmlTextWriterWriteDTDAttlist:
3465 * @writer: the xmlTextWriterPtr
3466 * @name: the name of the DTD ATTLIST
3467 * @content: content of the ATTLIST
3468 *
3469 * Write a DTD ATTLIST.
3470 *
3471 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3472 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003473int
3474xmlTextWriterWriteDTDAttlist(xmlTextWriterPtr writer,
3475 const xmlChar * name, const xmlChar * content)
3476{
3477 int count;
3478 int sum;
3479
3480 if (content == NULL)
3481 return -1;
3482
3483 sum = 0;
3484 count = xmlTextWriterStartDTDAttlist(writer, name);
3485 if (count == -1)
3486 return -1;
3487 sum += count;
3488
Daniel Veillard1d211e22003-10-20 22:32:39 +00003489 count = xmlTextWriterWriteString(writer, content);
3490 if (count == -1)
3491 return -1;
3492 sum += count;
3493
3494 count = xmlTextWriterEndDTDAttlist(writer);
3495 if (count == -1)
3496 return -1;
3497 sum += count;
3498
3499 return sum;
3500}
3501
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003502/**
3503 * xmlTextWriterStartDTDEntity:
3504 * @writer: the xmlTextWriterPtr
3505 * @pe: TRUE if this is a parameter entity, FALSE if not
3506 * @name: the name of the DTD ATTLIST
3507 *
3508 * Start an xml DTD ATTLIST.
3509 *
3510 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3511 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003512int
3513xmlTextWriterStartDTDEntity(xmlTextWriterPtr writer,
3514 int pe, const xmlChar * name)
3515{
3516 int count;
3517 int sum;
3518 xmlLinkPtr lk;
3519 xmlTextWriterStackEntry *p;
3520
3521 if (writer == NULL || name == NULL || *name == '\0')
3522 return -1;
3523
3524 sum = 0;
3525 lk = xmlListFront(writer->nodes);
Daniel Veillard500a1de2004-03-22 15:22:58 +00003526 if (lk != 0) {
Daniel Veillard1d211e22003-10-20 22:32:39 +00003527
Daniel Veillard500a1de2004-03-22 15:22:58 +00003528 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3529 if (p != 0) {
3530 switch (p->state) {
3531 case XML_TEXTWRITER_DTD:
3532 count = xmlOutputBufferWriteString(writer->out, " [");
3533 if (count < 0)
3534 return -1;
3535 sum += count;
3536 if (writer->indent) {
3537 count =
3538 xmlOutputBufferWriteString(writer->out, "\n");
3539 if (count < 0)
3540 return -1;
3541 sum += count;
3542 }
3543 p->state = XML_TEXTWRITER_DTD_TEXT;
3544 /* fallthrough */
3545 case XML_TEXTWRITER_DTD_TEXT:
3546 case XML_TEXTWRITER_NONE:
3547 break;
3548 default:
3549 return -1;
3550 }
3551 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00003552 }
3553
3554 p = (xmlTextWriterStackEntry *)
3555 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3556 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003557 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003558 "xmlTextWriterStartDTDElement : out of memory!\n");
3559 return -1;
3560 }
3561
3562 p->name = xmlStrdup(name);
3563 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003564 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003565 "xmlTextWriterStartDTDElement : out of memory!\n");
3566 xmlFree(p);
3567 return -1;
3568 }
Daniel Veillard500a1de2004-03-22 15:22:58 +00003569
3570 if (pe != 0)
3571 p->state = XML_TEXTWRITER_DTD_PENT;
3572 else
3573 p->state = XML_TEXTWRITER_DTD_ENTY;
Daniel Veillard1d211e22003-10-20 22:32:39 +00003574
3575 xmlListPushFront(writer->nodes, p);
3576
Daniel Veillard500a1de2004-03-22 15:22:58 +00003577 if (writer->indent) {
3578 count = xmlTextWriterWriteIndent(writer);
3579 if (count < 0)
3580 return -1;
3581 sum += count;
3582 }
3583
Daniel Veillard1d211e22003-10-20 22:32:39 +00003584 count = xmlOutputBufferWriteString(writer->out, "<!ENTITY ");
3585 if (count < 0)
3586 return -1;
3587 sum += count;
3588
3589 if (pe != 0) {
Daniel Veillard500a1de2004-03-22 15:22:58 +00003590 count = xmlOutputBufferWriteString(writer->out, "% ");
Daniel Veillard1d211e22003-10-20 22:32:39 +00003591 if (count < 0)
3592 return -1;
3593 sum += count;
3594 }
3595
Daniel Veillardab69f362004-02-17 11:40:32 +00003596 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003597 if (count < 0)
3598 return -1;
3599 sum += count;
3600
3601 return sum;
3602}
3603
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003604/**
Daniel Veillard500a1de2004-03-22 15:22:58 +00003605 * xmlTextWriterEndDTDEntity:
3606 * @writer: the xmlTextWriterPtr
3607 *
3608 * End an xml DTD entity.
3609 *
3610 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3611 */
3612int
3613xmlTextWriterEndDTDEntity(xmlTextWriterPtr writer)
3614{
3615 int count;
3616 int sum;
3617 xmlLinkPtr lk;
3618 xmlTextWriterStackEntry *p;
3619
3620 if (writer == NULL)
3621 return -1;
3622
3623 sum = 0;
3624 lk = xmlListFront(writer->nodes);
3625 if (lk == 0)
3626 return -1;
3627
3628 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3629 if (p == 0)
3630 return -1;
3631
3632 switch (p->state) {
3633 case XML_TEXTWRITER_DTD_ENTY_TEXT:
3634 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3635 if (count < 0)
3636 return -1;
3637 sum += count;
3638 case XML_TEXTWRITER_DTD_ENTY:
3639 case XML_TEXTWRITER_DTD_PENT:
Daniel Veillard500a1de2004-03-22 15:22:58 +00003640 count = xmlOutputBufferWriteString(writer->out, ">");
3641 if (count < 0)
3642 return -1;
3643 sum += count;
3644 break;
3645 default:
3646 return -1;
3647 }
3648
3649 if (writer->indent) {
3650 count = xmlOutputBufferWriteString(writer->out, "\n");
3651 if (count < 0)
3652 return -1;
3653 sum += count;
3654 }
3655
3656 xmlListPopFront(writer->nodes);
3657 return sum;
3658}
3659
3660/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003661 * xmlTextWriterWriteFormatDTDInternalEntity:
3662 * @writer: the xmlTextWriterPtr
3663 * @pe: TRUE if this is a parameter entity, FALSE if not
3664 * @name: the name of the DTD entity
3665 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003666 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003667 *
3668 * Write a formatted DTD internal entity.
3669 *
3670 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3671 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003672int
3673xmlTextWriterWriteFormatDTDInternalEntity(xmlTextWriterPtr writer,
3674 int pe,
3675 const xmlChar * name,
3676 const char *format, ...)
3677{
3678 int rc;
3679 va_list ap;
3680
3681 va_start(ap, format);
3682
3683 rc = xmlTextWriterWriteVFormatDTDInternalEntity(writer, pe, name,
3684 format, ap);
3685
3686 va_end(ap);
3687 return rc;
3688}
3689
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003690/**
3691 * xmlTextWriterWriteVFormatDTDInternalEntity:
3692 * @writer: the xmlTextWriterPtr
3693 * @pe: TRUE if this is a parameter entity, FALSE if not
3694 * @name: the name of the DTD entity
3695 * @format: format string (see printf)
3696 * @argptr: pointer to the first member of the variable argument list.
3697 *
3698 * Write a formatted DTD internal entity.
3699 *
3700 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3701 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003702int
3703xmlTextWriterWriteVFormatDTDInternalEntity(xmlTextWriterPtr writer,
3704 int pe,
3705 const xmlChar * name,
3706 const char *format,
3707 va_list argptr)
3708{
3709 int rc;
3710 xmlChar *buf;
3711
3712 if (writer == NULL)
3713 return -1;
3714
3715 buf = xmlTextWriterVSprintf(format, argptr);
3716 if (buf == 0)
3717 return 0;
3718
3719 rc = xmlTextWriterWriteDTDInternalEntity(writer, pe, name, buf);
3720
3721 xmlFree(buf);
3722 return rc;
3723}
3724
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003725/**
3726 * xmlTextWriterWriteDTDEntity:
3727 * @writer: the xmlTextWriterPtr
3728 * @pe: TRUE if this is a parameter entity, FALSE if not
3729 * @name: the name of the DTD entity
3730 * @pubid: the public identifier, which is an alternative to the system identifier
3731 * @sysid: the system identifier, which is the URI of the DTD
3732 * @ndataid: the xml notation name.
3733 * @content: content of the entity
3734 *
3735 * Write a DTD entity.
3736 *
3737 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3738 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003739int
3740xmlTextWriterWriteDTDEntity(xmlTextWriterPtr writer,
3741 int pe,
3742 const xmlChar * name,
3743 const xmlChar * pubid,
3744 const xmlChar * sysid,
3745 const xmlChar * ndataid,
3746 const xmlChar * content)
3747{
Daniel Veillard500a1de2004-03-22 15:22:58 +00003748 if ((content == NULL) && (pubid == NULL) && (sysid == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00003749 return -1;
3750 if ((pe != 0) && (ndataid != NULL))
3751 return -1;
3752
Daniel Veillard500a1de2004-03-22 15:22:58 +00003753 if ((pubid == NULL) && (sysid == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00003754 return xmlTextWriterWriteDTDInternalEntity(writer, pe, name,
3755 content);
3756
3757 return xmlTextWriterWriteDTDExternalEntity(writer, pe, name, pubid,
3758 sysid, ndataid);
3759}
3760
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003761/**
3762 * xmlTextWriterWriteDTDInternalEntity:
3763 * @writer: the xmlTextWriterPtr
3764 * @pe: TRUE if this is a parameter entity, FALSE if not
3765 * @name: the name of the DTD entity
3766 * @content: content of the entity
3767 *
3768 * Write a DTD internal entity.
3769 *
3770 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3771 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003772int
3773xmlTextWriterWriteDTDInternalEntity(xmlTextWriterPtr writer,
3774 int pe,
3775 const xmlChar * name,
3776 const xmlChar * content)
3777{
3778 int count;
3779 int sum;
3780
3781 if ((name == NULL) || (*name == '\0') || (content == NULL))
3782 return -1;
3783
3784 sum = 0;
3785 count = xmlTextWriterStartDTDEntity(writer, pe, name);
3786 if (count == -1)
3787 return -1;
3788 sum += count;
3789
Daniel Veillard1d211e22003-10-20 22:32:39 +00003790 count = xmlTextWriterWriteString(writer, content);
3791 if (count == -1)
3792 return -1;
3793 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00003794
3795 count = xmlTextWriterEndDTDEntity(writer);
3796 if (count == -1)
3797 return -1;
3798 sum += count;
3799
3800 return sum;
3801}
3802
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003803/**
3804 * xmlTextWriterWriteDTDExternalEntity:
3805 * @writer: the xmlTextWriterPtr
3806 * @pe: TRUE if this is a parameter entity, FALSE if not
3807 * @name: the name of the DTD entity
3808 * @pubid: the public identifier, which is an alternative to the system identifier
3809 * @sysid: the system identifier, which is the URI of the DTD
3810 * @ndataid: the xml notation name.
3811 *
Daniel Veillard500a1de2004-03-22 15:22:58 +00003812 * Write a DTD external entity. The entity must have been started with xmlTextWriterStartDTDEntity
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003813 *
3814 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3815 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003816int
3817xmlTextWriterWriteDTDExternalEntity(xmlTextWriterPtr writer,
3818 int pe,
3819 const xmlChar * name,
3820 const xmlChar * pubid,
3821 const xmlChar * sysid,
3822 const xmlChar * ndataid)
3823{
3824 int count;
3825 int sum;
3826
Daniel Veillard500a1de2004-03-22 15:22:58 +00003827 if (((pubid == NULL) && (sysid == NULL)))
Daniel Veillard1d211e22003-10-20 22:32:39 +00003828 return -1;
3829 if ((pe != 0) && (ndataid != NULL))
3830 return -1;
3831
3832 sum = 0;
3833 count = xmlTextWriterStartDTDEntity(writer, pe, name);
3834 if (count == -1)
3835 return -1;
3836 sum += count;
3837
Daniel Veillard500a1de2004-03-22 15:22:58 +00003838 count =
3839 xmlTextWriterWriteDTDExternalEntityContents(writer, pubid, sysid,
3840 ndataid);
3841 if (count < 0)
3842 return -1;
3843 sum += count;
3844
3845 count = xmlTextWriterEndDTDEntity(writer);
3846 if (count == -1)
3847 return -1;
3848 sum += count;
3849
3850 return sum;
3851}
3852
3853/**
3854 * xmlTextWriterWriteDTDExternalEntityContents:
3855 * @writer: the xmlTextWriterPtr
3856 * @pubid: the public identifier, which is an alternative to the system identifier
3857 * @sysid: the system identifier, which is the URI of the DTD
3858 * @ndataid: the xml notation name.
3859 *
3860 * Write the contents of a DTD external entity.
3861 *
3862 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3863 */
3864int
3865xmlTextWriterWriteDTDExternalEntityContents(xmlTextWriterPtr writer,
3866 const xmlChar * pubid,
3867 const xmlChar * sysid,
3868 const xmlChar * ndataid)
3869{
3870 int count;
3871 int sum;
3872 xmlLinkPtr lk;
3873 xmlTextWriterStackEntry *p;
3874
3875 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003876 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003877 "xmlTextWriterWriteDTDExternalEntityContents: xmlTextWriterPtr invalid!\n");
3878 return -1;
3879 }
3880
3881 sum = 0;
3882 lk = xmlListFront(writer->nodes);
3883 if (lk == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003884 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003885 "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n");
3886 return -1;
3887 }
3888
3889 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3890 if (p == 0)
3891 return -1;
3892
3893 switch (p->state) {
3894 case XML_TEXTWRITER_DTD_ENTY:
3895 break;
3896 case XML_TEXTWRITER_DTD_PENT:
3897 if (ndataid != NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003898 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003899 "xmlTextWriterWriteDTDExternalEntityContents: notation not allowed with parameter entities!\n");
3900 return -1;
3901 }
3902 break;
3903 default:
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003904 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003905 "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n");
3906 return -1;
3907 }
3908
Daniel Veillard1d211e22003-10-20 22:32:39 +00003909 if (pubid != 0) {
3910 if (sysid == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003911 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003912 "xmlTextWriterWriteDTDExternalEntityContents: system identifier needed!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +00003913 return -1;
3914 }
3915
3916 count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
3917 if (count < 0)
3918 return -1;
3919 sum += count;
3920
3921 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3922 if (count < 0)
3923 return -1;
3924 sum += count;
3925
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003926 count =
3927 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003928 if (count < 0)
3929 return -1;
3930 sum += count;
3931
3932 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3933 if (count < 0)
3934 return -1;
3935 sum += count;
3936 }
3937
3938 if (sysid != 0) {
3939 if (pubid == 0) {
3940 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
3941 if (count < 0)
3942 return -1;
3943 sum += count;
3944 }
3945
3946 count = xmlOutputBufferWriteString(writer->out, " ");
3947 if (count < 0)
3948 return -1;
3949 sum += count;
3950
3951 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3952 if (count < 0)
3953 return -1;
3954 sum += count;
3955
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003956 count =
3957 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003958 if (count < 0)
3959 return -1;
3960 sum += count;
3961
3962 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3963 if (count < 0)
3964 return -1;
3965 sum += count;
3966 }
3967
3968 if (ndataid != NULL) {
3969 count = xmlOutputBufferWriteString(writer->out, " NDATA ");
3970 if (count < 0)
3971 return -1;
3972 sum += count;
3973
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003974 count =
3975 xmlOutputBufferWriteString(writer->out,
3976 (const char *) ndataid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003977 if (count < 0)
3978 return -1;
3979 sum += count;
3980 }
3981
Daniel Veillard1d211e22003-10-20 22:32:39 +00003982 return sum;
3983}
3984
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003985/**
3986 * xmlTextWriterWriteDTDNotation:
3987 * @writer: the xmlTextWriterPtr
3988 * @name: the name of the xml notation
3989 * @pubid: the public identifier, which is an alternative to the system identifier
3990 * @sysid: the system identifier, which is the URI of the DTD
3991 *
3992 * Write a DTD entity.
3993 *
3994 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3995 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003996int
3997xmlTextWriterWriteDTDNotation(xmlTextWriterPtr writer,
3998 const xmlChar * name,
3999 const xmlChar * pubid, const xmlChar * sysid)
4000{
4001 int count;
4002 int sum;
4003 xmlLinkPtr lk;
4004 xmlTextWriterStackEntry *p;
4005
4006 if (writer == NULL || name == NULL || *name == '\0')
4007 return -1;
4008
4009 sum = 0;
4010 lk = xmlListFront(writer->nodes);
4011 if (lk == 0) {
4012 return -1;
4013 }
4014
4015 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
Daniel Veillard500a1de2004-03-22 15:22:58 +00004016 if (p != 0) {
4017 switch (p->state) {
4018 case XML_TEXTWRITER_DTD:
4019 count = xmlOutputBufferWriteString(writer->out, " [");
4020 if (count < 0)
4021 return -1;
4022 sum += count;
4023 if (writer->indent) {
4024 count = xmlOutputBufferWriteString(writer->out, "\n");
4025 if (count < 0)
4026 return -1;
4027 sum += count;
4028 }
4029 p->state = XML_TEXTWRITER_DTD_TEXT;
4030 /* fallthrough */
4031 case XML_TEXTWRITER_DTD_TEXT:
4032 break;
4033 default:
4034 return -1;
4035 }
4036 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00004037
Daniel Veillard500a1de2004-03-22 15:22:58 +00004038 if (writer->indent) {
4039 count = xmlTextWriterWriteIndent(writer);
4040 if (count < 0)
Daniel Veillard1d211e22003-10-20 22:32:39 +00004041 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00004042 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00004043 }
4044
4045 count = xmlOutputBufferWriteString(writer->out, "<!NOTATION ");
4046 if (count < 0)
4047 return -1;
4048 sum += count;
4049 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
4050 if (count < 0)
4051 return -1;
4052 sum += count;
4053
4054 if (pubid != 0) {
4055 count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
4056 if (count < 0)
4057 return -1;
4058 sum += count;
4059 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4060 if (count < 0)
4061 return -1;
4062 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004063 count =
4064 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004065 if (count < 0)
4066 return -1;
4067 sum += count;
4068 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4069 if (count < 0)
4070 return -1;
4071 sum += count;
4072 }
4073
4074 if (sysid != 0) {
4075 if (pubid == 0) {
4076 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
4077 if (count < 0)
4078 return -1;
4079 sum += count;
4080 }
4081 count = xmlOutputBufferWriteString(writer->out, " ");
4082 if (count < 0)
4083 return -1;
4084 sum += count;
4085 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4086 if (count < 0)
4087 return -1;
4088 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004089 count =
4090 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004091 if (count < 0)
4092 return -1;
4093 sum += count;
4094 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4095 if (count < 0)
4096 return -1;
4097 sum += count;
4098 }
4099
4100 count = xmlOutputBufferWriteString(writer->out, ">");
4101 if (count < 0)
4102 return -1;
4103 sum += count;
4104
4105 return sum;
4106}
4107
4108/**
4109 * xmlTextWriterFlush:
4110 * @writer: the xmlTextWriterPtr
4111 *
4112 * Flush the output buffer.
4113 *
4114 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
4115 */
4116int
4117xmlTextWriterFlush(xmlTextWriterPtr writer)
4118{
4119 int count;
4120
4121 if (writer == NULL)
4122 return -1;
4123
4124 if (writer->out == NULL)
4125 count = 0;
4126 else
4127 count = xmlOutputBufferFlush(writer->out);
4128
4129 return count;
4130}
4131
4132/**
4133 * misc
4134 */
4135
4136/**
4137 * xmlFreeTextWriterStackEntry:
4138 * @lk: the xmlLinkPtr
4139 *
4140 * Free callback for the xmlList.
4141 */
4142static void
4143xmlFreeTextWriterStackEntry(xmlLinkPtr lk)
4144{
4145 xmlTextWriterStackEntry *p;
4146
4147 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
4148 if (p == 0)
4149 return;
4150
4151 if (p->name != 0)
4152 xmlFree(p->name);
4153 xmlFree(p);
4154}
4155
4156/**
4157 * xmlCmpTextWriterStackEntry:
4158 * @data0: the first data
4159 * @data1: the second data
4160 *
4161 * Compare callback for the xmlList.
4162 *
4163 * Returns -1, 0, 1
4164 */
4165static int
4166xmlCmpTextWriterStackEntry(const void *data0, const void *data1)
4167{
4168 xmlTextWriterStackEntry *p0;
4169 xmlTextWriterStackEntry *p1;
4170
4171 if (data0 == data1)
4172 return 0;
4173
4174 if (data0 == 0)
4175 return -1;
4176
4177 if (data1 == 0)
4178 return 1;
4179
4180 p0 = (xmlTextWriterStackEntry *) data0;
4181 p1 = (xmlTextWriterStackEntry *) data1;
4182
4183 return xmlStrcmp(p0->name, p1->name);
4184}
4185
4186/**
4187 * misc
4188 */
4189
4190/**
4191 * xmlFreeTextWriterNsStackEntry:
4192 * @lk: the xmlLinkPtr
4193 *
4194 * Free callback for the xmlList.
4195 */
4196static void
4197xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk)
4198{
4199 xmlTextWriterNsStackEntry *p;
4200
4201 p = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
4202 if (p == 0)
4203 return;
4204
4205 if (p->prefix != 0)
4206 xmlFree(p->prefix);
4207 if (p->uri != 0)
4208 xmlFree(p->uri);
4209
4210 xmlFree(p);
4211}
4212
4213/**
4214 * xmlCmpTextWriterNsStackEntry:
4215 * @data0: the first data
4216 * @data1: the second data
4217 *
4218 * Compare callback for the xmlList.
4219 *
4220 * Returns -1, 0, 1
4221 */
4222static int
4223xmlCmpTextWriterNsStackEntry(const void *data0, const void *data1)
4224{
4225 xmlTextWriterNsStackEntry *p0;
4226 xmlTextWriterNsStackEntry *p1;
4227 int rc;
4228
4229 if (data0 == data1)
4230 return 0;
4231
4232 if (data0 == 0)
4233 return -1;
4234
4235 if (data1 == 0)
4236 return 1;
4237
4238 p0 = (xmlTextWriterNsStackEntry *) data0;
4239 p1 = (xmlTextWriterNsStackEntry *) data1;
4240
4241 rc = xmlStrcmp(p0->prefix, p1->prefix);
4242
4243 if (rc == 0)
4244 rc = p0->elem == p1->elem;
4245
4246 return rc;
4247}
4248
4249/**
4250 * xmlTextWriterWriteMemCallback:
4251 * @context: the xmlBufferPtr
4252 * @str: the data to write
4253 * @len: the length of the data
4254 *
4255 * Write callback for the xmlOutputBuffer with target xmlBuffer
4256 *
4257 * Returns -1, 0, 1
4258 */
4259static int
4260xmlTextWriterWriteMemCallback(void *context, const xmlChar * str, int len)
4261{
4262 xmlBufferPtr buf = (xmlBufferPtr) context;
4263
4264 xmlBufferAdd(buf, str, len);
4265
4266 return len;
4267}
4268
4269/**
4270 * xmlTextWriterCloseMemCallback:
4271 * @context: the xmlBufferPtr
4272 *
4273 * Close callback for the xmlOutputBuffer with target xmlBuffer
4274 *
4275 * Returns -1, 0, 1
4276 */
4277static int
4278xmlTextWriterCloseMemCallback(void *context ATTRIBUTE_UNUSED)
4279{
4280 return 0;
4281}
4282
4283/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004284 * xmlTextWriterWriteDocCallback:
4285 * @context: the xmlBufferPtr
4286 * @str: the data to write
4287 * @len: the length of the data
4288 *
4289 * Write callback for the xmlOutputBuffer with target xmlBuffer
4290 *
4291 * Returns -1, 0, 1
4292 */
4293static int
4294xmlTextWriterWriteDocCallback(void *context, const xmlChar * str, int len)
4295{
4296 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context;
4297 int rc;
4298
Daniel Veillard1d913862003-11-21 00:28:39 +00004299 if ((rc = xmlParseChunk(ctxt, (const char *) str, len, 0)) != 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004300 xmlWriterErrMsgInt(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004301 "xmlTextWriterWriteDocCallback : XML error %d !\n",
4302 rc);
4303 return -1;
4304 }
4305
4306 return len;
4307}
4308
4309/**
4310 * xmlTextWriterCloseDocCallback:
4311 * @context: the xmlBufferPtr
4312 *
4313 * Close callback for the xmlOutputBuffer with target xmlBuffer
4314 *
4315 * Returns -1, 0, 1
4316 */
4317static int
4318xmlTextWriterCloseDocCallback(void *context)
4319{
4320 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context;
4321 int rc;
4322
4323 if ((rc = xmlParseChunk(ctxt, NULL, 0, 1)) != 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004324 xmlWriterErrMsgInt(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004325 "xmlTextWriterWriteDocCallback : XML error %d !\n",
4326 rc);
4327 return -1;
4328 }
4329
4330 return 0;
4331}
4332
4333/**
Daniel Veillard1d211e22003-10-20 22:32:39 +00004334 * xmlTextWriterVSprintf:
4335 * @format: see printf
4336 * @argptr: pointer to the first member of the variable argument list.
4337 *
4338 * Utility function for formatted output
4339 *
4340 * Returns a new xmlChar buffer with the data or NULL on error. This buffer must be freed.
4341 */
4342static xmlChar *
4343xmlTextWriterVSprintf(const char *format, va_list argptr)
4344{
4345 int size;
4346 int count;
4347 xmlChar *buf;
4348
4349 size = BUFSIZ;
4350 buf = (xmlChar *) xmlMalloc(size);
4351 if (buf == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004352 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00004353 "xmlTextWriterVSprintf : out of memory!\n");
4354 return NULL;
4355 }
4356
4357 while (((count = vsnprintf((char *) buf, size, format, argptr)) < 0)
4358 || (count == size - 1) || (count == size) || (count > size)) {
4359 xmlFree(buf);
4360 size += BUFSIZ;
4361 buf = (xmlChar *) xmlMalloc(size);
4362 if (buf == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004363 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00004364 "xmlTextWriterVSprintf : out of memory!\n");
4365 return NULL;
4366 }
4367 }
4368
4369 return buf;
4370}
4371
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004372/**
4373 * xmlTextWriterStartDocumentCallback:
4374 * @ctx: the user data (XML parser context)
4375 *
4376 * called at the start of document processing.
4377 */
4378static void
4379xmlTextWriterStartDocumentCallback(void *ctx)
4380{
4381 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
4382 xmlDocPtr doc;
4383
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004384 if (ctxt->html) {
4385#ifdef LIBXML_HTML_ENABLED
4386 if (ctxt->myDoc == NULL)
4387 ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
4388 if (ctxt->myDoc == NULL) {
4389 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
4390 ctxt->sax->error(ctxt->userData,
4391 "SAX.startDocument(): out of memory\n");
4392 ctxt->errNo = XML_ERR_NO_MEMORY;
4393 ctxt->instate = XML_PARSER_EOF;
4394 ctxt->disableSAX = 1;
4395 return;
4396 }
4397#else
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004398 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004399 "libxml2 built without HTML support\n");
4400 ctxt->errNo = XML_ERR_INTERNAL_ERROR;
4401 ctxt->instate = XML_PARSER_EOF;
4402 ctxt->disableSAX = 1;
4403 return;
4404#endif
4405 } else {
4406 doc = ctxt->myDoc;
4407 if (doc == NULL)
4408 doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
4409 if (doc != NULL) {
4410 if (doc->children == NULL) {
4411 if (ctxt->encoding != NULL)
4412 doc->encoding = xmlStrdup(ctxt->encoding);
4413 else
4414 doc->encoding = NULL;
4415 doc->standalone = ctxt->standalone;
4416 }
4417 } else {
4418 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
4419 ctxt->sax->error(ctxt->userData,
4420 "SAX.startDocument(): out of memory\n");
4421 ctxt->errNo = XML_ERR_NO_MEMORY;
4422 ctxt->instate = XML_PARSER_EOF;
4423 ctxt->disableSAX = 1;
4424 return;
4425 }
4426 }
4427 if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) &&
4428 (ctxt->input != NULL) && (ctxt->input->filename != NULL)) {
4429 ctxt->myDoc->URL =
4430 xmlCanonicPath((const xmlChar *) ctxt->input->filename);
4431 if (ctxt->myDoc->URL == NULL)
4432 ctxt->myDoc->URL =
4433 xmlStrdup((const xmlChar *) ctxt->input->filename);
4434 }
4435}
4436
Daniel Veillard2cca4462004-01-02 20:04:23 +00004437/**
4438 * xmlTextWriterSetIndent:
4439 * @writer: the xmlTextWriterPtr
4440 * @indent: do indentation?
4441 *
4442 * Set indentation output. indent = 0 do not indentation. indent > 0 do indentation.
4443 *
4444 * Returns -1 on error or 0 otherwise.
4445 */
4446int
Daniel Veillardab69f362004-02-17 11:40:32 +00004447xmlTextWriterSetIndent(xmlTextWriterPtr writer, int indent)
Daniel Veillard2cca4462004-01-02 20:04:23 +00004448{
Daniel Veillarde43cc572004-11-03 11:50:29 +00004449 if ((writer == NULL) || (indent < 0))
Daniel Veillardab69f362004-02-17 11:40:32 +00004450 return -1;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004451
Daniel Veillardab69f362004-02-17 11:40:32 +00004452 writer->indent = indent;
4453 writer->doindent = 1;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004454
Daniel Veillardab69f362004-02-17 11:40:32 +00004455 return 0;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004456}
4457
4458/**
4459 * xmlTextWriterSetIndentString:
4460 * @writer: the xmlTextWriterPtr
4461 * @str: the xmlChar string
4462 *
4463 * Set string indentation.
4464 *
4465 * Returns -1 on error or 0 otherwise.
4466 */
4467int
Daniel Veillardab69f362004-02-17 11:40:32 +00004468xmlTextWriterSetIndentString(xmlTextWriterPtr writer, const xmlChar * str)
Daniel Veillard2cca4462004-01-02 20:04:23 +00004469{
Daniel Veillarde43cc572004-11-03 11:50:29 +00004470 if ((writer == NULL) || (!str))
Daniel Veillardab69f362004-02-17 11:40:32 +00004471 return -1;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004472
Daniel Veillardab69f362004-02-17 11:40:32 +00004473 if (writer->ichar != NULL)
4474 xmlFree(writer->ichar);
4475 writer->ichar = xmlStrdup(str);
4476
4477 if (!writer->ichar)
4478 return -1;
4479 else
4480 return 0;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004481}
4482
4483/**
4484 * xmlTextWriterWriteIndent:
4485 * @writer: the xmlTextWriterPtr
4486 *
4487 * Write indent string.
4488 *
4489 * Returns -1 on error or the number of strings written.
Daniel Veillardab69f362004-02-17 11:40:32 +00004490 */
Daniel Veillard2cca4462004-01-02 20:04:23 +00004491static int
Daniel Veillardab69f362004-02-17 11:40:32 +00004492xmlTextWriterWriteIndent(xmlTextWriterPtr writer)
Daniel Veillard2cca4462004-01-02 20:04:23 +00004493{
Daniel Veillardab69f362004-02-17 11:40:32 +00004494 int lksize;
4495 int i;
4496 int ret;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004497
Daniel Veillardab69f362004-02-17 11:40:32 +00004498 lksize = xmlListSize(writer->nodes);
4499 if (lksize < 1)
4500 return (-1); /* list is empty */
4501 for (i = 0; i < (lksize - 1); i++) {
4502 ret = xmlOutputBufferWriteString(writer->out,
4503 (const char *) writer->ichar);
4504 if (ret == -1)
4505 return (-1);
4506 }
4507
4508 return (lksize - 1);
Daniel Veillard2cca4462004-01-02 20:04:23 +00004509}
4510
Daniel Veillard500a1de2004-03-22 15:22:58 +00004511/**
4512 * xmlTextWriterHandleStateDependencies:
4513 * @writer: the xmlTextWriterPtr
4514 * @p: the xmlTextWriterStackEntry
4515 *
4516 * Write state dependent strings.
4517 *
4518 * Returns -1 on error or the number of characters written.
4519 */
4520static int
4521xmlTextWriterHandleStateDependencies(xmlTextWriterPtr writer,
4522 xmlTextWriterStackEntry * p)
4523{
4524 int count;
4525 int sum;
4526 char extra[3];
4527
4528 if (writer == NULL)
4529 return -1;
4530
4531 if (p == NULL)
4532 return 0;
4533
4534 sum = 0;
4535 extra[0] = extra[1] = extra[2] = '\0';
4536 if (p != 0) {
4537 sum = 0;
4538 switch (p->state) {
4539 case XML_TEXTWRITER_NAME:
4540 extra[0] = '>';
4541 p->state = XML_TEXTWRITER_TEXT;
4542 break;
4543 case XML_TEXTWRITER_PI:
4544 extra[0] = ' ';
4545 p->state = XML_TEXTWRITER_PI_TEXT;
4546 break;
4547 case XML_TEXTWRITER_DTD:
4548 extra[0] = ' ';
4549 extra[1] = '[';
4550 p->state = XML_TEXTWRITER_DTD_TEXT;
4551 break;
4552 case XML_TEXTWRITER_DTD_ELEM:
4553 extra[0] = ' ';
4554 p->state = XML_TEXTWRITER_DTD_ELEM_TEXT;
4555 break;
4556 case XML_TEXTWRITER_DTD_ATTL:
4557 extra[0] = ' ';
4558 p->state = XML_TEXTWRITER_DTD_ATTL_TEXT;
4559 break;
4560 case XML_TEXTWRITER_DTD_ENTY:
4561 case XML_TEXTWRITER_DTD_PENT:
4562 extra[0] = ' ';
4563 extra[1] = writer->qchar;
4564 p->state = XML_TEXTWRITER_DTD_ENTY_TEXT;
4565 break;
4566 default:
4567 break;
4568 }
4569 }
4570
4571 if (*extra != '\0') {
4572 count = xmlOutputBufferWriteString(writer->out, extra);
4573 if (count < 0)
4574 return -1;
4575 sum += count;
4576 }
4577
4578 return sum;
4579}
4580
Daniel Veillard1d211e22003-10-20 22:32:39 +00004581#endif