blob: a11ef25ebd5e2228421f4116cf00e107273a172a [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
148 *
149 * Returns the new xmlTextWriterPtr or NULL in case of error
150 */
151xmlTextWriterPtr
152xmlNewTextWriter(xmlOutputBufferPtr out)
153{
154 xmlTextWriterPtr ret;
155
156 ret = (xmlTextWriterPtr) xmlMalloc(sizeof(xmlTextWriter));
157 if (ret == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000158 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000159 "xmlNewTextWriter : out of memory!\n");
160 return NULL;
161 }
162 memset(ret, 0, (size_t) sizeof(xmlTextWriter));
163
164 ret->nodes = xmlListCreate((xmlListDeallocator)
165 xmlFreeTextWriterStackEntry,
166 (xmlListDataCompare)
167 xmlCmpTextWriterStackEntry);
168 if (ret->nodes == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000169 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000170 "xmlNewTextWriter : out of memory!\n");
171 xmlFree(ret);
172 return NULL;
173 }
174
175 ret->nsstack = xmlListCreate((xmlListDeallocator)
176 xmlFreeTextWriterNsStackEntry,
177 (xmlListDataCompare)
178 xmlCmpTextWriterNsStackEntry);
179 if (ret->nsstack == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000180 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000181 "xmlNewTextWriter : out of memory!\n");
Daniel Veillard500a1de2004-03-22 15:22:58 +0000182 xmlListDelete(ret->nodes);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000183 xmlFree(ret);
184 return NULL;
185 }
186
187 ret->out = out;
Daniel Veillardab69f362004-02-17 11:40:32 +0000188 ret->ichar = xmlStrdup(BAD_CAST " ");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000189 ret->qchar = '"';
190
Daniel Veillard500a1de2004-03-22 15:22:58 +0000191 if (!ret->ichar) {
192 xmlListDelete(ret->nodes);
193 xmlListDelete(ret->nsstack);
194 xmlFree(ret);
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000195 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000196 "xmlNewTextWriter : out of memory!\n");
Daniel Veillardab69f362004-02-17 11:40:32 +0000197 return NULL;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000198 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000199
Daniel Veillard1d211e22003-10-20 22:32:39 +0000200 return ret;
201}
202
203/**
204 * xmlNewTextWriterFilename:
205 * @uri: the URI of the resource for the output
206 * @compression: compress the output?
207 *
208 * Create a new xmlNewTextWriter structure with @uri as output
209 *
210 * Returns the new xmlTextWriterPtr or NULL in case of error
211 */
212xmlTextWriterPtr
213xmlNewTextWriterFilename(const char *uri, int compression)
214{
215 xmlTextWriterPtr ret;
216 xmlOutputBufferPtr out;
217
218 out = xmlOutputBufferCreateFilename(uri, NULL, compression);
219 if (out == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000220 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000221 "xmlNewTextWriterFilename : out of memory!\n");
222 return NULL;
223 }
224
225 ret = xmlNewTextWriter(out);
226 if (ret == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000227 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000228 "xmlNewTextWriterFilename : out of memory!\n");
229 xmlOutputBufferClose(out);
230 return NULL;
231 }
232
Daniel Veillard2cca4462004-01-02 20:04:23 +0000233 ret->indent = 0;
234 ret->doindent = 0;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000235 return ret;
236}
237
238/**
239 * xmlNewTextWriterMemory:
240 * @buf: xmlBufferPtr
241 * @compression: compress the output?
242 *
243 * Create a new xmlNewTextWriter structure with @buf as output
244 * TODO: handle compression
245 *
246 * Returns the new xmlTextWriterPtr or NULL in case of error
247 */
248xmlTextWriterPtr
249xmlNewTextWriterMemory(xmlBufferPtr buf, int compression ATTRIBUTE_UNUSED)
250{
251 xmlTextWriterPtr ret;
252 xmlOutputBufferPtr out;
253
254/*::todo handle compression */
255 out = xmlOutputBufferCreateIO((xmlOutputWriteCallback)
256 xmlTextWriterWriteMemCallback,
257 (xmlOutputCloseCallback)
258 xmlTextWriterCloseMemCallback,
259 (void *) buf, NULL);
260 if (out == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000261 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000262 "xmlNewTextWriterMemory : out of memory!\n");
263 return NULL;
264 }
265
266 ret = xmlNewTextWriter(out);
267 if (ret == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000268 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000269 "xmlNewTextWriterMemory : out of memory!\n");
270 xmlOutputBufferClose(out);
271 return NULL;
272 }
273
274 return ret;
275}
276
277/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000278 * xmlNewTextWriterPushParser:
279 * @ctxt: xmlParserCtxtPtr to hold the new XML document tree
280 * @compression: compress the output?
281 *
282 * Create a new xmlNewTextWriter structure with @ctxt as output
283 * TODO: handle compression
284 *
285 * Returns the new xmlTextWriterPtr or NULL in case of error
286 */
287xmlTextWriterPtr
Daniel Veillard1d913862003-11-21 00:28:39 +0000288xmlNewTextWriterPushParser(xmlParserCtxtPtr ctxt,
289 int compression ATTRIBUTE_UNUSED)
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000290{
291 xmlTextWriterPtr ret;
292 xmlOutputBufferPtr out;
293
Daniel Veillard500a1de2004-03-22 15:22:58 +0000294 if (ctxt == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000295 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000296 "xmlNewTextWriterPushParser : invalid context!\n");
297 return NULL;
298 }
299
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000300 out = xmlOutputBufferCreateIO((xmlOutputWriteCallback)
301 xmlTextWriterWriteDocCallback,
302 (xmlOutputCloseCallback)
303 xmlTextWriterCloseDocCallback,
304 (void *) ctxt, NULL);
305 if (out == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000306 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000307 "xmlNewTextWriterPushParser : error at xmlOutputBufferCreateIO!\n");
308 return NULL;
309 }
310
311 ret = xmlNewTextWriter(out);
312 if (ret == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000313 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000314 "xmlNewTextWriterPushParser : error at xmlNewTextWriter!\n");
315 xmlOutputBufferClose(out);
316 return NULL;
317 }
318
Daniel Veillard20c5e782004-01-21 09:57:31 +0000319 ret->ctxt = ctxt;
320
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000321 return ret;
322}
323
324/**
325 * xmlNewTextWriterDoc:
326 * @doc: address of a xmlDocPtr to hold the new XML document tree
327 * @compression: compress the output?
328 *
329 * Create a new xmlNewTextWriter structure with @*doc as output
330 *
331 * Returns the new xmlTextWriterPtr or NULL in case of error
332 */
333xmlTextWriterPtr
334xmlNewTextWriterDoc(xmlDocPtr * doc, int compression)
335{
336 xmlTextWriterPtr ret;
337 xmlSAXHandler saxHandler;
338 xmlParserCtxtPtr ctxt;
339
340 memset(&saxHandler, '\0', sizeof(saxHandler));
341 xmlSAX2InitDefaultSAXHandler(&saxHandler, 1);
342 saxHandler.startDocument = xmlTextWriterStartDocumentCallback;
343 saxHandler.startElement = xmlSAX2StartElement;
344 saxHandler.endElement = xmlSAX2EndElement;
345
346 ctxt = xmlCreatePushParserCtxt(&saxHandler, NULL, NULL, 0, NULL);
347 if (ctxt == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000348 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000349 "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\n");
350 return NULL;
351 }
Daniel Veillard03a53c32004-10-26 16:06:51 +0000352 /*
353 * For some reason this seems to completely break if node names
354 * are interned.
355 */
356 ctxt->dictNames = 0;
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000357
Daniel Veillard1d913862003-11-21 00:28:39 +0000358 ctxt->myDoc = xmlNewDoc(BAD_CAST XML_DEFAULT_VERSION);
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000359 if (ctxt->myDoc == NULL) {
360 xmlFreeParserCtxt(ctxt);
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000361 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000362 "xmlNewTextWriterDoc : error at xmlNewDoc!\n");
363 return NULL;
364 }
365
366 ret = xmlNewTextWriterPushParser(ctxt, compression);
367 if (ret == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000368 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000369 "xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n");
370 return NULL;
371 }
372
Daniel Veillard500a1de2004-03-22 15:22:58 +0000373 xmlSetDocCompressMode(ctxt->myDoc, compression);
374
375 if (doc != NULL)
376 *doc = ctxt->myDoc;
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000377
378 return ret;
379}
380
381/**
382 * xmlNewTextWriterTree:
383 * @doc: xmlDocPtr
384 * @node: xmlNodePtr or NULL for doc->children
385 * @compression: compress the output?
386 *
387 * Create a new xmlNewTextWriter structure with @doc as output
388 * starting at @node
389 *
390 * Returns the new xmlTextWriterPtr or NULL in case of error
391 */
392xmlTextWriterPtr
393xmlNewTextWriterTree(xmlDocPtr doc, xmlNodePtr node, int compression)
394{
395 xmlTextWriterPtr ret;
396 xmlSAXHandler saxHandler;
397 xmlParserCtxtPtr ctxt;
398
399 if (doc == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000400 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000401 "xmlNewTextWriterTree : invalid document tree!\n");
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000402 return NULL;
403 }
404
405 memset(&saxHandler, '\0', sizeof(saxHandler));
406 xmlSAX2InitDefaultSAXHandler(&saxHandler, 1);
407 saxHandler.startDocument = xmlTextWriterStartDocumentCallback;
408 saxHandler.startElement = xmlSAX2StartElement;
409 saxHandler.endElement = xmlSAX2EndElement;
410
411 ctxt = xmlCreatePushParserCtxt(&saxHandler, NULL, NULL, 0, NULL);
412 if (ctxt == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000413 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000414 "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\n");
415 return NULL;
416 }
Daniel Veillard03a53c32004-10-26 16:06:51 +0000417 /*
418 * For some reason this seems to completely break if node names
419 * are interned.
420 */
421 ctxt->dictNames = 0;
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000422
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000423 ret = xmlNewTextWriterPushParser(ctxt, compression);
424 if (ret == NULL) {
Daniel Veillard500a1de2004-03-22 15:22:58 +0000425 xmlFreeParserCtxt(ctxt);
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000426 xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000427 "xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n");
428 return NULL;
429 }
430
Daniel Veillard500a1de2004-03-22 15:22:58 +0000431 ctxt->myDoc = doc;
432 ctxt->node = node;
433
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000434 xmlSetDocCompressMode(doc, compression);
435
436 return ret;
437}
438
439/**
Daniel Veillard1d211e22003-10-20 22:32:39 +0000440 * xmlFreeTextWriter:
441 * @writer: the xmlTextWriterPtr
442 *
443 * Deallocate all the resources associated to the writer
444 */
445void
446xmlFreeTextWriter(xmlTextWriterPtr writer)
447{
448 if (writer == NULL)
449 return;
450
451 if (writer->out != NULL)
452 xmlOutputBufferClose(writer->out);
453
454 if (writer->nodes != NULL)
455 xmlListDelete(writer->nodes);
456
457 if (writer->nsstack != NULL)
458 xmlListDelete(writer->nsstack);
459
Daniel Veillard20c5e782004-01-21 09:57:31 +0000460 if (writer->ctxt != NULL)
461 xmlFreeParserCtxt(writer->ctxt);
462
Daniel Veillard4773df22004-01-23 13:15:13 +0000463 if (writer->ichar != NULL)
464 xmlFree(writer->ichar);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000465 xmlFree(writer);
466}
467
468/**
469 * xmlTextWriterStartDocument:
470 * @writer: the xmlTextWriterPtr
471 * @version: the xml version ("1.0") or NULL for default ("1.0")
472 * @encoding: the encoding or NULL for default
473 * @standalone: "yes" or "no" or NULL for default
474 *
475 * Start a new xml document
476 *
477 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
478 */
479int
480xmlTextWriterStartDocument(xmlTextWriterPtr writer, const char *version,
481 const char *encoding, const char *standalone)
482{
483 int count;
484 int sum;
485 xmlLinkPtr lk;
486 xmlCharEncodingHandlerPtr encoder;
487
Daniel Veillard500a1de2004-03-22 15:22:58 +0000488 if ((writer == NULL) || (writer->out == NULL)) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000489 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000490 "xmlTextWriterStartDocument : invalid writer!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000491 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000492 }
Daniel Veillard1d211e22003-10-20 22:32:39 +0000493
494 lk = xmlListFront(writer->nodes);
495 if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000496 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000497 "xmlTextWriterStartDocument : not allowed in this context!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000498 return -1;
499 }
500
501 encoder = NULL;
502 if (encoding != NULL) {
503 encoder = xmlFindCharEncodingHandler(encoding);
504 if (encoder == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000505 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000506 "xmlTextWriterStartDocument : out of memory!\n");
507 return -1;
508 }
509 }
510
511 writer->out->encoder = encoder;
512 if (encoder != NULL) {
513 writer->out->conv = xmlBufferCreateSize(4000);
514 xmlCharEncOutFunc(encoder, writer->out->conv, NULL);
515 } else
516 writer->out->conv = NULL;
517
518 sum = 0;
519 count = xmlOutputBufferWriteString(writer->out, "<?xml version=");
520 if (count < 0)
521 return -1;
522 sum += count;
523 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
524 if (count < 0)
525 return -1;
526 sum += count;
527 if (version != 0)
528 count = xmlOutputBufferWriteString(writer->out, version);
529 else
530 count = xmlOutputBufferWriteString(writer->out, "1.0");
531 if (count < 0)
532 return -1;
533 sum += count;
534 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
535 if (count < 0)
536 return -1;
537 sum += count;
538 if (writer->out->encoder != 0) {
539 count = xmlOutputBufferWriteString(writer->out, " encoding=");
540 if (count < 0)
541 return -1;
542 sum += count;
543 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
544 if (count < 0)
545 return -1;
546 sum += count;
547 count =
548 xmlOutputBufferWriteString(writer->out,
549 writer->out->encoder->name);
550 if (count < 0)
551 return -1;
552 sum += count;
553 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
554 if (count < 0)
555 return -1;
556 sum += count;
557 }
558
559 if (standalone != 0) {
560 count = xmlOutputBufferWriteString(writer->out, " standalone=");
561 if (count < 0)
562 return -1;
563 sum += count;
564 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
565 if (count < 0)
566 return -1;
567 sum += count;
568 count = xmlOutputBufferWriteString(writer->out, standalone);
569 if (count < 0)
570 return -1;
571 sum += count;
572 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
573 if (count < 0)
574 return -1;
575 sum += count;
576 }
577
578 count = xmlOutputBufferWriteString(writer->out, "?>\n");
579 if (count < 0)
580 return -1;
581 sum += count;
582
583 return sum;
584}
585
586/**
587 * xmlTextWriterEndDocument:
588 * @writer: the xmlTextWriterPtr
589 *
590 * End an xml document. All open elements are closed
591 *
592 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
593 */
594int
595xmlTextWriterEndDocument(xmlTextWriterPtr writer)
596{
597 int count;
598 int sum;
599 xmlLinkPtr lk;
600 xmlTextWriterStackEntry *p;
601
Daniel Veillard500a1de2004-03-22 15:22:58 +0000602 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000603 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000604 "xmlTextWriterEndDocument : invalid writer!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000605 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000606 }
Daniel Veillard1d211e22003-10-20 22:32:39 +0000607
608 sum = 0;
609 while ((lk = xmlListFront(writer->nodes)) != NULL) {
610 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
611 if (p == 0)
612 break;
613 switch (p->state) {
614 case XML_TEXTWRITER_NAME:
615 case XML_TEXTWRITER_ATTRIBUTE:
616 case XML_TEXTWRITER_TEXT:
617 count = xmlTextWriterEndElement(writer);
618 if (count < 0)
619 return -1;
620 sum += count;
621 break;
622 case XML_TEXTWRITER_PI:
623 case XML_TEXTWRITER_PI_TEXT:
624 count = xmlTextWriterEndPI(writer);
625 if (count < 0)
626 return -1;
627 sum += count;
628 break;
629 case XML_TEXTWRITER_CDATA:
630 count = xmlTextWriterEndCDATA(writer);
631 if (count < 0)
632 return -1;
633 sum += count;
634 break;
635 case XML_TEXTWRITER_DTD:
Daniel Veillard500a1de2004-03-22 15:22:58 +0000636 case XML_TEXTWRITER_DTD_TEXT:
637 case XML_TEXTWRITER_DTD_ELEM:
638 case XML_TEXTWRITER_DTD_ELEM_TEXT:
639 case XML_TEXTWRITER_DTD_ATTL:
640 case XML_TEXTWRITER_DTD_ATTL_TEXT:
641 case XML_TEXTWRITER_DTD_ENTY:
642 case XML_TEXTWRITER_DTD_ENTY_TEXT:
643 case XML_TEXTWRITER_DTD_PENT:
Daniel Veillard1d211e22003-10-20 22:32:39 +0000644 count = xmlTextWriterEndDTD(writer);
645 if (count < 0)
646 return -1;
647 sum += count;
648 break;
Daniel Veillardab69f362004-02-17 11:40:32 +0000649 case XML_TEXTWRITER_COMMENT:
650 count = xmlTextWriterEndComment(writer);
651 if (count < 0)
652 return -1;
653 sum += count;
654 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000655 default:
Daniel Veillardab69f362004-02-17 11:40:32 +0000656 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000657 }
658 }
659
Daniel Veillard2cca4462004-01-02 20:04:23 +0000660 if (!writer->indent) {
Daniel Veillardab69f362004-02-17 11:40:32 +0000661 count = xmlOutputBufferWriteString(writer->out, "\n");
662 if (count < 0)
663 return -1;
664 sum += count;
665 }
666 return sum;
667}
668
Daniel Veillardab69f362004-02-17 11:40:32 +0000669/**
670 * xmlTextWriterStartComment:
671 * @writer: the xmlTextWriterPtr
672 *
673 * Start an xml comment.
674 *
675 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
676 */
677int
678xmlTextWriterStartComment(xmlTextWriterPtr writer)
679{
680 int count;
681 int sum;
682 xmlLinkPtr lk;
683 xmlTextWriterStackEntry *p;
684
Daniel Veillard500a1de2004-03-22 15:22:58 +0000685 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000686 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000687 "xmlTextWriterStartComment : invalid writer!\n");
Daniel Veillardab69f362004-02-17 11:40:32 +0000688 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000689 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000690
691 sum = 0;
692 lk = xmlListFront(writer->nodes);
693 if (lk != 0) {
694 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
695 if (p != 0) {
696 switch (p->state) {
697 case XML_TEXTWRITER_TEXT:
698 case XML_TEXTWRITER_NONE:
699 break;
700 case XML_TEXTWRITER_NAME:
701 count = xmlOutputBufferWriteString(writer->out, ">");
702 if (count < 0)
703 return -1;
704 sum += count;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000705 if (writer->indent) {
706 count =
707 xmlOutputBufferWriteString(writer->out, "\n");
708 if (count < 0)
709 return -1;
710 sum += count;
711 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000712 p->state = XML_TEXTWRITER_TEXT;
713 break;
714 default:
715 return -1;
716 }
717 }
718 }
719
720 p = (xmlTextWriterStackEntry *)
721 xmlMalloc(sizeof(xmlTextWriterStackEntry));
722 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000723 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillardab69f362004-02-17 11:40:32 +0000724 "xmlTextWriterStartElement : out of memory!\n");
725 return -1;
726 }
727
728 p->name = 0;
729 p->state = XML_TEXTWRITER_COMMENT;
730
731 xmlListPushFront(writer->nodes, p);
732
733 if (writer->indent) {
Daniel Veillardab69f362004-02-17 11:40:32 +0000734 count = xmlTextWriterWriteIndent(writer);
735 if (count < 0)
736 return -1;
737 sum += count;
738 }
739
740 count = xmlOutputBufferWriteString(writer->out, "<!--");
741 if (count < 0)
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000742 return -1;
743 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +0000744
745 return sum;
746}
747
748/**
749 * xmlTextWriterEndComment:
750 * @writer: the xmlTextWriterPtr
751 *
752 * End the current xml coment.
753 *
754 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
755 */
756int
757xmlTextWriterEndComment(xmlTextWriterPtr writer)
758{
759 int count;
760 int sum;
761 xmlLinkPtr lk;
762 xmlTextWriterStackEntry *p;
763
Daniel Veillard500a1de2004-03-22 15:22:58 +0000764 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000765 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000766 "xmlTextWriterEndComment : invalid writer!\n");
Daniel Veillardab69f362004-02-17 11:40:32 +0000767 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000768 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000769
770 lk = xmlListFront(writer->nodes);
Daniel Veillard500a1de2004-03-22 15:22:58 +0000771 if (lk == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000772 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000773 "xmlTextWriterEndComment : not allowed in this context!\n");
Daniel Veillardab69f362004-02-17 11:40:32 +0000774 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000775 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000776
777 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
778 if (p == 0)
779 return -1;
780
781 sum = 0;
782 switch (p->state) {
783 case XML_TEXTWRITER_COMMENT:
784 count = xmlOutputBufferWriteString(writer->out, "-->");
785 if (count < 0)
786 return -1;
787 sum += count;
788 break;
789 default:
790 return -1;
Daniel Veillard2cca4462004-01-02 20:04:23 +0000791 }
Daniel Veillardab69f362004-02-17 11:40:32 +0000792
793 if (writer->indent) {
794 count = xmlOutputBufferWriteString(writer->out, "\n");
795 if (count < 0)
796 return -1;
797 sum += count;
798 }
799
800 xmlListPopFront(writer->nodes);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000801 return sum;
802}
803
804/**
805 * xmlTextWriterWriteFormatComment:
806 * @writer: the xmlTextWriterPtr
807 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +0000808 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +0000809 *
810 * Write an xml comment.
811 *
812 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
813 */
814int
815xmlTextWriterWriteFormatComment(xmlTextWriterPtr writer,
816 const char *format, ...)
817{
818 int rc;
819 va_list ap;
820
821 va_start(ap, format);
822
823 rc = xmlTextWriterWriteVFormatComment(writer, format, ap);
824
825 va_end(ap);
826 return rc;
827}
828
829/**
830 * xmlTextWriterWriteVFormatComment:
831 * @writer: the xmlTextWriterPtr
832 * @format: format string (see printf)
833 * @argptr: pointer to the first member of the variable argument list.
834 *
835 * Write an xml comment.
836 *
837 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
838 */
839int
840xmlTextWriterWriteVFormatComment(xmlTextWriterPtr writer,
841 const char *format, va_list argptr)
842{
843 int rc;
844 xmlChar *buf;
845
Daniel Veillard500a1de2004-03-22 15:22:58 +0000846 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000847 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +0000848 "xmlTextWriterWriteVFormatComment : invalid writer!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000849 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +0000850 }
Daniel Veillard1d211e22003-10-20 22:32:39 +0000851
852 buf = xmlTextWriterVSprintf(format, argptr);
853 if (buf == 0)
854 return 0;
855
856 rc = xmlTextWriterWriteComment(writer, buf);
857
858 xmlFree(buf);
859 return rc;
860}
861
862/**
863 * xmlTextWriterWriteComment:
864 * @writer: the xmlTextWriterPtr
865 * @content: comment string
866 *
867 * Write an xml comment.
868 *
869 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
870 */
871int
872xmlTextWriterWriteComment(xmlTextWriterPtr writer, const xmlChar * content)
873{
874 int count;
875 int sum;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000876
877 sum = 0;
Daniel Veillardab69f362004-02-17 11:40:32 +0000878 count = xmlTextWriterStartComment(writer);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000879 if (count < 0)
880 return -1;
881 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +0000882 count = xmlTextWriterWriteString(writer, content);
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 = xmlTextWriterEndComment(writer);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000887 if (count < 0)
888 return -1;
889 sum += count;
890
891 return sum;
892}
893
894/**
895 * xmlTextWriterStartElement:
896 * @writer: the xmlTextWriterPtr
897 * @name: element name
898 *
899 * Start an xml element.
900 *
901 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
902 */
903int
904xmlTextWriterStartElement(xmlTextWriterPtr writer, const xmlChar * name)
905{
906 int count;
907 int sum;
908 xmlLinkPtr lk;
909 xmlTextWriterStackEntry *p;
910
911 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
912 return -1;
913
914 sum = 0;
915 lk = xmlListFront(writer->nodes);
916 if (lk != 0) {
917 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
918 if (p != 0) {
919 switch (p->state) {
920 case XML_TEXTWRITER_PI:
921 case XML_TEXTWRITER_PI_TEXT:
922 return -1;
923 case XML_TEXTWRITER_NONE:
924 break;
925 case XML_TEXTWRITER_NAME:
926 count = xmlOutputBufferWriteString(writer->out, ">");
927 if (count < 0)
928 return -1;
929 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +0000930 if (writer->indent)
931 count =
932 xmlOutputBufferWriteString(writer->out, "\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000933 p->state = XML_TEXTWRITER_TEXT;
934 break;
Daniel Veillardab69f362004-02-17 11:40:32 +0000935 default:
936 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000937 }
938 }
939 }
940
941 p = (xmlTextWriterStackEntry *)
942 xmlMalloc(sizeof(xmlTextWriterStackEntry));
943 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000944 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000945 "xmlTextWriterStartElement : out of memory!\n");
946 return -1;
947 }
948
949 p->name = xmlStrdup(name);
950 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +0000951 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +0000952 "xmlTextWriterStartElement : out of memory!\n");
953 xmlFree(p);
954 return -1;
955 }
956 p->state = XML_TEXTWRITER_NAME;
957
958 xmlListPushFront(writer->nodes, p);
959
Daniel Veillardab69f362004-02-17 11:40:32 +0000960 if (writer->indent) {
961 count = xmlTextWriterWriteIndent(writer);
962 sum += count;
Daniel Veillard2cca4462004-01-02 20:04:23 +0000963 }
964
Daniel Veillard1d211e22003-10-20 22:32:39 +0000965 count = xmlOutputBufferWriteString(writer->out, "<");
966 if (count < 0)
967 return -1;
968 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000969 count =
970 xmlOutputBufferWriteString(writer->out, (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000971 if (count < 0)
972 return -1;
973 sum += count;
974
975 return sum;
976}
977
978/**
979 * xmlTextWriterStartElementNS:
980 * @writer: the xmlTextWriterPtr
981 * @prefix: namespace prefix or NULL
982 * @name: element local name
983 * @namespaceURI: namespace URI or NULL
984 *
985 * Start an xml element with namespace support.
986 *
987 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
988 */
989int
990xmlTextWriterStartElementNS(xmlTextWriterPtr writer,
991 const xmlChar * prefix, const xmlChar * name,
992 const xmlChar * namespaceURI)
993{
994 int count;
995 int sum;
996 xmlChar *buf;
997
998 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
999 return -1;
1000
1001 buf = 0;
1002 if (prefix != 0) {
1003 buf = xmlStrdup(prefix);
1004 buf = xmlStrcat(buf, BAD_CAST ":");
1005 }
1006 buf = xmlStrcat(buf, name);
1007
1008 sum = 0;
1009 count = xmlTextWriterStartElement(writer, buf);
1010 xmlFree(buf);
1011 if (count < 0)
1012 return -1;
1013 sum += count;
1014
1015 if (namespaceURI != 0) {
1016 buf = xmlStrdup(BAD_CAST "xmlns");
1017 if (prefix != 0) {
1018 buf = xmlStrcat(buf, BAD_CAST ":");
1019 buf = xmlStrcat(buf, prefix);
1020 }
1021
1022 count = xmlTextWriterWriteAttribute(writer, buf, namespaceURI);
1023 xmlFree(buf);
1024 if (count < 0)
1025 return -1;
1026 sum += count;
1027 }
1028
1029 return sum;
1030}
1031
1032/**
1033 * xmlTextWriterEndElement:
1034 * @writer: the xmlTextWriterPtr
1035 *
1036 * End the current xml element.
1037 *
1038 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1039 */
1040int
1041xmlTextWriterEndElement(xmlTextWriterPtr writer)
1042{
1043 int count;
1044 int sum;
1045 xmlLinkPtr lk;
1046 xmlTextWriterStackEntry *p;
1047
1048 if (writer == NULL)
1049 return -1;
1050
1051 lk = xmlListFront(writer->nodes);
1052 if (lk == 0)
1053 return -1;
1054
1055 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1056 if (p == 0)
1057 return -1;
1058
1059 sum = 0;
1060 switch (p->state) {
1061 case XML_TEXTWRITER_ATTRIBUTE:
1062 count = xmlTextWriterEndAttribute(writer);
1063 if (count < 0)
1064 return -1;
1065 sum += count;
1066 /* fallthrough */
1067 case XML_TEXTWRITER_NAME:
Daniel Veillardab69f362004-02-17 11:40:32 +00001068 if (writer->indent) /* next element needs indent */
1069 writer->doindent = 1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001070 count = xmlOutputBufferWriteString(writer->out, "/>");
1071 if (count < 0)
1072 return -1;
1073 sum += count;
1074 break;
1075 case XML_TEXTWRITER_TEXT:
Daniel Veillardab69f362004-02-17 11:40:32 +00001076 if ((writer->indent) && (writer->doindent)) {
1077 count = xmlTextWriterWriteIndent(writer);
1078 sum += count;
1079 writer->doindent = 1;
1080 } else
1081 writer->doindent = 1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001082 count = xmlOutputBufferWriteString(writer->out, "</");
1083 if (count < 0)
1084 return -1;
1085 sum += count;
1086 count = xmlOutputBufferWriteString(writer->out,
Daniel Veillardab69f362004-02-17 11:40:32 +00001087 (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001088 if (count < 0)
1089 return -1;
1090 sum += count;
1091 count = xmlOutputBufferWriteString(writer->out, ">");
1092 if (count < 0)
1093 return -1;
1094 sum += count;
1095 break;
1096 default:
1097 return -1;
1098 }
1099
Daniel Veillard2cca4462004-01-02 20:04:23 +00001100 if (writer->indent) {
Daniel Veillardab69f362004-02-17 11:40:32 +00001101 count = xmlOutputBufferWriteString(writer->out, "\n");
1102 sum += count;
Daniel Veillard2cca4462004-01-02 20:04:23 +00001103 }
1104
Daniel Veillard1d211e22003-10-20 22:32:39 +00001105 xmlListPopFront(writer->nodes);
1106 return sum;
1107}
1108
1109/**
1110 * xmlTextWriterFullEndElement:
1111 * @writer: the xmlTextWriterPtr
1112 *
1113 * End the current xml element. Writes an end tag even if the element is empty
1114 *
1115 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1116 */
1117int
1118xmlTextWriterFullEndElement(xmlTextWriterPtr writer)
1119{
1120 int count;
1121 int sum;
1122 xmlLinkPtr lk;
1123 xmlTextWriterStackEntry *p;
1124
1125 if (writer == NULL)
1126 return -1;
1127
1128 lk = xmlListFront(writer->nodes);
1129 if (lk == 0)
1130 return -1;
1131
1132 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1133 if (p == 0)
1134 return -1;
1135
1136 sum = 0;
1137 switch (p->state) {
1138 case XML_TEXTWRITER_ATTRIBUTE:
1139 count = xmlTextWriterEndAttribute(writer);
1140 if (count < 0)
1141 return -1;
1142 sum += count;
1143 /* fallthrough */
1144 case XML_TEXTWRITER_NAME:
1145 count = xmlOutputBufferWriteString(writer->out, ">");
1146 if (count < 0)
1147 return -1;
1148 sum += count;
1149 /* fallthrough */
1150 case XML_TEXTWRITER_TEXT:
1151 count = xmlOutputBufferWriteString(writer->out, "</");
1152 if (count < 0)
1153 return -1;
1154 sum += count;
1155 count = xmlOutputBufferWriteString(writer->out,
Daniel Veillardab69f362004-02-17 11:40:32 +00001156 (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001157 if (count < 0)
1158 return -1;
1159 sum += count;
1160 count = xmlOutputBufferWriteString(writer->out, ">");
1161 if (count < 0)
1162 return -1;
1163 sum += count;
1164 break;
1165 default:
1166 return -1;
1167 }
1168
1169 xmlListPopFront(writer->nodes);
1170 return sum;
1171}
1172
1173/**
1174 * xmlTextWriterWriteFormatRaw:
1175 * @writer: the xmlTextWriterPtr
1176 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001177 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001178 *
1179 * Write a formatted raw xml text.
1180 *
1181 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1182 */
1183int
1184xmlTextWriterWriteFormatRaw(xmlTextWriterPtr writer, const char *format,
1185 ...)
1186{
1187 int rc;
1188 va_list ap;
1189
1190 va_start(ap, format);
1191
1192 rc = xmlTextWriterWriteVFormatRaw(writer, format, ap);
1193
1194 va_end(ap);
1195 return rc;
1196}
1197
1198/**
1199 * xmlTextWriterWriteVFormatRaw:
1200 * @writer: the xmlTextWriterPtr
1201 * @format: format string (see printf)
1202 * @argptr: pointer to the first member of the variable argument list.
1203 *
1204 * Write a formatted raw xml text.
1205 *
1206 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1207 */
1208int
1209xmlTextWriterWriteVFormatRaw(xmlTextWriterPtr writer, const char *format,
1210 va_list argptr)
1211{
1212 int rc;
1213 xmlChar *buf;
1214
1215 if (writer == NULL)
1216 return -1;
1217
1218 buf = xmlTextWriterVSprintf(format, argptr);
1219 if (buf == 0)
1220 return 0;
1221
1222 rc = xmlTextWriterWriteRaw(writer, buf);
1223
1224 xmlFree(buf);
1225 return rc;
1226}
1227
1228/**
Daniel Veillard1e906612003-12-05 14:57:46 +00001229 * xmlTextWriterWriteRawLen:
Daniel Veillard1d211e22003-10-20 22:32:39 +00001230 * @writer: the xmlTextWriterPtr
1231 * @content: text string
1232 * @len: length of the text string
1233 *
1234 * Write an xml text.
1235 * TODO: what about entities and special chars??
1236 *
1237 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1238 */
1239int
1240xmlTextWriterWriteRawLen(xmlTextWriterPtr writer, const xmlChar * content,
1241 int len)
1242{
1243 int count;
1244 int sum;
1245 xmlLinkPtr lk;
1246 xmlTextWriterStackEntry *p;
1247
Daniel Veillard500a1de2004-03-22 15:22:58 +00001248 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00001249 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00001250 "xmlTextWriterWriteRawLen : invalid writer!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +00001251 return -1;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001252 }
1253
Daniel Veillarde43cc572004-11-03 11:50:29 +00001254 if ((content == NULL) || (len < 0)) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00001255 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00001256 "xmlTextWriterWriteRawLen : invalid content!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +00001257 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001258 }
1259
1260 sum = 0;
1261 lk = xmlListFront(writer->nodes);
1262 if (lk != 0) {
1263 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1264 count = xmlTextWriterHandleStateDependencies(writer, p);
1265 if (count < 0)
1266 return -1;
1267 sum += count;
1268 }
1269
1270 if (writer->indent)
1271 writer->doindent = 0;
1272
1273 if (content != NULL) {
1274 count =
1275 xmlOutputBufferWrite(writer->out, len, (const char *) content);
1276 if (count < 0)
1277 return -1;
1278 sum += count;
1279 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001280
1281 return sum;
1282}
1283
1284/**
1285 * xmlTextWriterWriteRaw:
1286 * @writer: the xmlTextWriterPtr
1287 * @content: text string
1288 *
1289 * Write a raw xml text.
1290 *
1291 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1292 */
1293int
1294xmlTextWriterWriteRaw(xmlTextWriterPtr writer, const xmlChar * content)
1295{
1296 return xmlTextWriterWriteRawLen(writer, content, xmlStrlen(content));
1297}
1298
1299/**
1300 * xmlTextWriterWriteFormatString:
1301 * @writer: the xmlTextWriterPtr
1302 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001303 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001304 *
1305 * Write a formatted xml text.
1306 *
1307 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1308 */
1309int
1310xmlTextWriterWriteFormatString(xmlTextWriterPtr writer, const char *format,
1311 ...)
1312{
1313 int rc;
1314 va_list ap;
1315
Daniel Veillarde43cc572004-11-03 11:50:29 +00001316 if ((writer == NULL) || (format == NULL))
1317 return -1;
1318
Daniel Veillard1d211e22003-10-20 22:32:39 +00001319 va_start(ap, format);
1320
1321 rc = xmlTextWriterWriteVFormatString(writer, format, ap);
1322
1323 va_end(ap);
1324 return rc;
1325}
1326
1327/**
1328 * xmlTextWriterWriteVFormatString:
1329 * @writer: the xmlTextWriterPtr
1330 * @format: format string (see printf)
1331 * @argptr: pointer to the first member of the variable argument list.
1332 *
1333 * Write a formatted xml text.
1334 *
1335 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1336 */
1337int
1338xmlTextWriterWriteVFormatString(xmlTextWriterPtr writer,
1339 const char *format, va_list argptr)
1340{
1341 int rc;
1342 xmlChar *buf;
1343
Daniel Veillarde43cc572004-11-03 11:50:29 +00001344 if ((writer == NULL) || (format == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00001345 return -1;
1346
1347 buf = xmlTextWriterVSprintf(format, argptr);
1348 if (buf == 0)
1349 return 0;
1350
1351 rc = xmlTextWriterWriteString(writer, buf);
1352
1353 xmlFree(buf);
1354 return rc;
1355}
1356
1357/**
1358 * xmlTextWriterWriteString:
1359 * @writer: the xmlTextWriterPtr
1360 * @content: text string
1361 *
1362 * Write an xml text.
1363 *
1364 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1365 */
1366int
1367xmlTextWriterWriteString(xmlTextWriterPtr writer, const xmlChar * content)
1368{
Daniel Veillard500a1de2004-03-22 15:22:58 +00001369 int count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001370 int sum;
1371 xmlLinkPtr lk;
1372 xmlTextWriterStackEntry *p;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001373 xmlChar *buf;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001374
Daniel Veillarde43cc572004-11-03 11:50:29 +00001375 if ((writer == NULL) || (content == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00001376 return -1;
1377
Daniel Veillard1d211e22003-10-20 22:32:39 +00001378 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001379 buf = (xmlChar *) content;
1380 lk = xmlListFront(writer->nodes);
1381 if (lk != 0) {
1382 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1383 if (p != 0) {
1384 switch (p->state) {
1385 case XML_TEXTWRITER_NAME:
1386 case XML_TEXTWRITER_TEXT:
Daniel Veillard62040be2004-05-17 03:17:26 +00001387#if 0
1388 buf = NULL;
1389 xmlOutputBufferWriteEscape(writer->out, content, NULL);
1390#endif
Daniel Veillard500a1de2004-03-22 15:22:58 +00001391 buf = xmlEncodeSpecialChars(NULL, content);
1392 break;
1393 case XML_TEXTWRITER_ATTRIBUTE:
1394 buf = NULL;
1395 xmlAttrSerializeTxtContent(writer->out->buffer, NULL,
1396 NULL, content);
1397 break;
William M. Brack87640d52004-04-17 14:58:15 +00001398 default:
1399 break;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001400 }
1401 }
1402 }
1403
1404 if (buf != NULL) {
1405 count = xmlTextWriterWriteRaw(writer, buf);
1406 if (count < 0)
Daniel Veillard1d211e22003-10-20 22:32:39 +00001407 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001408 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001409
Daniel Veillard500a1de2004-03-22 15:22:58 +00001410 if (buf != content) /* buf was allocated by us, so free it */
1411 xmlFree(buf);
William M. Bracka9c612c2004-02-01 10:04:05 +00001412 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001413
1414 return sum;
1415}
1416
1417/**
1418 * xmlOutputBufferWriteBase64:
1419 * @out: the xmlOutputBufferPtr
1420 * @data: binary data
1421 * @len: the number of bytes to encode
1422 *
1423 * Write base64 encoded data to an xmlOutputBuffer.
1424 * Adapted from John Walker's base64.c (http://www.fourmilab.ch/).
1425 *
1426 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1427 */
1428static int
1429xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len,
1430 const unsigned char *data)
1431{
1432 static unsigned char dtable[64] =
William M. Brack47a31882004-09-11 16:09:09 +00001433 {'A','B','C','D','E','F','G','H','I','J','K','L','M',
1434 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
1435 'a','b','c','d','e','f','g','h','i','j','k','l','m',
1436 'n','o','p','q','r','s','t','u','v','w','x','y','z',
1437 '0','1','2','3','4','5','6','7','8','9','+','/'};
1438
Daniel Veillard1d211e22003-10-20 22:32:39 +00001439 int i;
1440 int linelen;
1441 int count;
1442 int sum;
1443
Daniel Veillarde43cc572004-11-03 11:50:29 +00001444 if ((out == NULL) || (len < 0) || (data == NULL))
1445 return(-1);
1446
Daniel Veillard1d211e22003-10-20 22:32:39 +00001447 linelen = 0;
1448 sum = 0;
1449
1450 i = 0;
1451 while (1) {
1452 unsigned char igroup[3];
1453 unsigned char ogroup[4];
1454 int c;
1455 int n;
1456
1457 igroup[0] = igroup[1] = igroup[2] = 0;
1458 for (n = 0; n < 3 && i < len; n++, i++) {
1459 c = data[i];
1460 igroup[n] = (unsigned char) c;
1461 }
1462
1463 if (n > 0) {
1464 ogroup[0] = dtable[igroup[0] >> 2];
1465 ogroup[1] = dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)];
1466 ogroup[2] =
1467 dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)];
1468 ogroup[3] = dtable[igroup[2] & 0x3F];
1469
1470 if (n < 3) {
1471 ogroup[3] = '=';
1472 if (n < 2) {
1473 ogroup[2] = '=';
1474 }
1475 }
1476
1477 if (linelen >= B64LINELEN) {
1478 count = xmlOutputBufferWrite(out, 2, B64CRLF);
1479 if (count == -1)
1480 return -1;
1481 sum += count;
1482 linelen = 0;
1483 }
1484 count = xmlOutputBufferWrite(out, 4, (const char *) ogroup);
1485 if (count == -1)
1486 return -1;
1487 sum += count;
1488
1489 linelen += 4;
1490 }
Daniel Veillard929714b2003-10-22 12:34:36 +00001491
1492 if (i >= len)
1493 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001494 }
1495
Daniel Veillard1d211e22003-10-20 22:32:39 +00001496 return sum;
1497}
1498
1499/**
1500 * xmlTextWriterWriteBase64:
1501 * @writer: the xmlTextWriterPtr
1502 * @data: binary data
1503 * @start: the position within the data of the first byte to encode
1504 * @len: the number of bytes to encode
1505 *
1506 * Write an base64 encoded xml text.
1507 *
1508 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1509 */
1510int
Daniel Veillardab69f362004-02-17 11:40:32 +00001511xmlTextWriterWriteBase64(xmlTextWriterPtr writer, const char *data,
Daniel Veillard1d211e22003-10-20 22:32:39 +00001512 int start, int len)
1513{
1514 int count;
1515 int sum;
1516 xmlLinkPtr lk;
1517 xmlTextWriterStackEntry *p;
1518
Daniel Veillarde43cc572004-11-03 11:50:29 +00001519 if ((writer == NULL) || (data == NULL) || (start < 0) || (len < 0))
Daniel Veillard1d211e22003-10-20 22:32:39 +00001520 return -1;
1521
Daniel Veillard1d211e22003-10-20 22:32:39 +00001522 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001523 lk = xmlListFront(writer->nodes);
1524 if (lk != 0) {
1525 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1526 if (p != 0) {
1527 count = xmlTextWriterHandleStateDependencies(writer, p);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001528 if (count < 0)
1529 return -1;
1530 sum += count;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001531 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001532 }
1533
Daniel Veillardab69f362004-02-17 11:40:32 +00001534 if (writer->indent)
1535 writer->doindent = 0;
1536
Daniel Veillard1d211e22003-10-20 22:32:39 +00001537 count =
1538 xmlOutputBufferWriteBase64(writer->out, len,
1539 (unsigned char *) data + start);
1540 if (count < 0)
1541 return -1;
1542 sum += count;
1543
1544 return sum;
1545}
1546
1547/**
1548 * xmlOutputBufferWriteBinHex:
1549 * @out: the xmlOutputBufferPtr
1550 * @data: binary data
1551 * @len: the number of bytes to encode
1552 *
1553 * Write hqx encoded data to an xmlOutputBuffer.
1554 * ::todo
1555 *
William M. Brack47a31882004-09-11 16:09:09 +00001556 * Returns the bytes written (may be 0 because of buffering)
1557 * or -1 in case of error
Daniel Veillard1d211e22003-10-20 22:32:39 +00001558 */
1559static int
Daniel Veillardab69f362004-02-17 11:40:32 +00001560xmlOutputBufferWriteBinHex(xmlOutputBufferPtr out,
1561 int len, const unsigned char *data)
Daniel Veillard1d211e22003-10-20 22:32:39 +00001562{
Daniel Veillardab69f362004-02-17 11:40:32 +00001563 int count;
1564 int sum;
William M. Brack47a31882004-09-11 16:09:09 +00001565 static char hex[16] =
1566 {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
Daniel Veillardab69f362004-02-17 11:40:32 +00001567 int i;
1568
Daniel Veillarde43cc572004-11-03 11:50:29 +00001569 if ((out == NULL) || (data == NULL) || (len < 0)) {
Daniel Veillardab69f362004-02-17 11:40:32 +00001570 return -1;
1571 }
1572
1573 sum = 0;
1574 for (i = 0; i < len; i++) {
1575 count =
1576 xmlOutputBufferWrite(out, 1,
1577 (const char *) &hex[data[i] >> 4]);
1578 if (count == -1)
1579 return -1;
1580 sum += count;
1581 count =
1582 xmlOutputBufferWrite(out, 1,
1583 (const char *) &hex[data[i] & 0xF]);
1584 if (count == -1)
1585 return -1;
1586 sum += count;
1587 }
1588
1589 return sum;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001590}
1591
1592/**
1593 * xmlTextWriterWriteBinHex:
1594 * @writer: the xmlTextWriterPtr
1595 * @data: binary data
1596 * @start: the position within the data of the first byte to encode
1597 * @len: the number of bytes to encode
1598 *
1599 * Write a BinHex encoded xml text.
1600 *
1601 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1602 */
1603int
Daniel Veillardab69f362004-02-17 11:40:32 +00001604xmlTextWriterWriteBinHex(xmlTextWriterPtr writer, const char *data,
Daniel Veillard1d211e22003-10-20 22:32:39 +00001605 int start, int len)
1606{
1607 int count;
1608 int sum;
1609 xmlLinkPtr lk;
1610 xmlTextWriterStackEntry *p;
1611
Daniel Veillarde43cc572004-11-03 11:50:29 +00001612 if ((writer == NULL) || (data == NULL) || (start < 0) || (len < 0))
Daniel Veillard1d211e22003-10-20 22:32:39 +00001613 return -1;
1614
Daniel Veillard1d211e22003-10-20 22:32:39 +00001615 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001616 lk = xmlListFront(writer->nodes);
1617 if (lk != 0) {
1618 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1619 if (p != 0) {
1620 count = xmlTextWriterHandleStateDependencies(writer, p);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001621 if (count < 0)
1622 return -1;
1623 sum += count;
Daniel Veillard500a1de2004-03-22 15:22:58 +00001624 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00001625 }
1626
Daniel Veillardab69f362004-02-17 11:40:32 +00001627 if (writer->indent)
1628 writer->doindent = 0;
1629
Daniel Veillard1d211e22003-10-20 22:32:39 +00001630 count =
1631 xmlOutputBufferWriteBinHex(writer->out, len,
1632 (unsigned char *) data + start);
1633 if (count < 0)
1634 return -1;
1635 sum += count;
1636
1637 return sum;
1638}
1639
1640/**
1641 * xmlTextWriterStartAttribute:
1642 * @writer: the xmlTextWriterPtr
1643 * @name: element name
1644 *
1645 * Start an xml attribute.
1646 *
1647 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1648 */
1649int
1650xmlTextWriterStartAttribute(xmlTextWriterPtr writer, const xmlChar * name)
1651{
1652 int count;
1653 int sum;
1654 xmlLinkPtr lk;
1655 xmlTextWriterStackEntry *p;
1656
1657 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1658 return -1;
1659
1660 sum = 0;
1661 lk = xmlListFront(writer->nodes);
1662 if (lk == 0)
1663 return -1;
1664
1665 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1666 if (p == 0)
1667 return -1;
1668
1669 switch (p->state) {
1670 case XML_TEXTWRITER_ATTRIBUTE:
1671 count = xmlTextWriterEndAttribute(writer);
1672 if (count < 0)
1673 return -1;
1674 sum += count;
1675 /* fallthrough */
1676 case XML_TEXTWRITER_NAME:
1677 count = xmlOutputBufferWriteString(writer->out, " ");
1678 if (count < 0)
1679 return -1;
1680 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00001681 count =
1682 xmlOutputBufferWriteString(writer->out,
1683 (const char *) name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001684 if (count < 0)
1685 return -1;
1686 sum += count;
1687 count = xmlOutputBufferWriteString(writer->out, "=");
1688 if (count < 0)
1689 return -1;
1690 sum += count;
1691 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
1692 if (count < 0)
1693 return -1;
1694 sum += count;
1695 p->state = XML_TEXTWRITER_ATTRIBUTE;
1696 break;
1697 default:
1698 return -1;
1699 }
1700
1701 return sum;
1702}
1703
1704/**
1705 * xmlTextWriterStartAttributeNS:
1706 * @writer: the xmlTextWriterPtr
1707 * @prefix: namespace prefix or NULL
1708 * @name: element local name
1709 * @namespaceURI: namespace URI or NULL
1710 *
1711 * Start an xml attribute with namespace support.
1712 *
1713 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1714 */
1715int
1716xmlTextWriterStartAttributeNS(xmlTextWriterPtr writer,
1717 const xmlChar * prefix, const xmlChar * name,
1718 const xmlChar * namespaceURI)
1719{
1720 int count;
1721 int sum;
1722 xmlChar *buf;
1723 xmlTextWriterNsStackEntry *p;
1724
1725 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1726 return -1;
1727
1728 buf = 0;
1729 if (prefix != 0) {
1730 buf = xmlStrdup(prefix);
1731 buf = xmlStrcat(buf, BAD_CAST ":");
1732 }
1733 buf = xmlStrcat(buf, name);
1734
1735 sum = 0;
1736 count = xmlTextWriterStartAttribute(writer, buf);
1737 xmlFree(buf);
1738 if (count < 0)
1739 return -1;
1740 sum += count;
1741
1742 if (namespaceURI != 0) {
1743 buf = xmlStrdup(BAD_CAST "xmlns");
1744 if (prefix != 0) {
1745 buf = xmlStrcat(buf, BAD_CAST ":");
1746 buf = xmlStrcat(buf, prefix);
1747 }
1748
1749 p = (xmlTextWriterNsStackEntry *)
1750 xmlMalloc(sizeof(xmlTextWriterNsStackEntry));
1751 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00001752 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00001753 "xmlTextWriterStartAttributeNS : out of memory!\n");
1754 return -1;
1755 }
1756
1757 p->prefix = buf;
1758 p->uri = xmlStrdup(namespaceURI);
1759 if (p->uri == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00001760 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00001761 "xmlTextWriterStartAttributeNS : out of memory!\n");
1762 xmlFree(p);
1763 return -1;
1764 }
1765 p->elem = xmlListFront(writer->nodes);
1766
1767 xmlListPushFront(writer->nsstack, p);
1768 }
1769
1770 return sum;
1771}
1772
1773/**
1774 * xmlTextWriterEndAttribute:
1775 * @writer: the xmlTextWriterPtr
1776 *
1777 * End the current xml element.
1778 *
1779 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1780 */
1781int
1782xmlTextWriterEndAttribute(xmlTextWriterPtr writer)
1783{
1784 int count;
1785 int sum;
1786 xmlLinkPtr lk;
1787 xmlTextWriterStackEntry *p;
1788 xmlTextWriterNsStackEntry *np;
1789
1790 if (writer == NULL)
1791 return -1;
1792
1793 lk = xmlListFront(writer->nodes);
1794 if (lk == 0) {
1795 xmlListDelete(writer->nsstack);
Daniel Veillarde43cc572004-11-03 11:50:29 +00001796 writer->nsstack = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001797 return -1;
1798 }
1799
1800 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1801 if (p == 0) {
1802 xmlListDelete(writer->nsstack);
Daniel Veillarde43cc572004-11-03 11:50:29 +00001803 writer->nsstack = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001804 return -1;
1805 }
1806
1807 sum = 0;
1808 switch (p->state) {
1809 case XML_TEXTWRITER_ATTRIBUTE:
1810 p->state = XML_TEXTWRITER_NAME;
1811
1812 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
1813 if (count < 0) {
1814 xmlListDelete(writer->nsstack);
Daniel Veillarde43cc572004-11-03 11:50:29 +00001815 writer->nsstack = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001816 return -1;
1817 }
1818 sum += count;
1819
1820 while (!xmlListEmpty(writer->nsstack)) {
1821 lk = xmlListFront(writer->nsstack);
1822 np = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
1823 if (np != 0) {
1824 count =
1825 xmlTextWriterWriteAttribute(writer, np->prefix,
1826 np->uri);
1827 if (count < 0) {
1828 xmlListDelete(writer->nsstack);
Daniel Veillarde43cc572004-11-03 11:50:29 +00001829 writer->nsstack = NULL;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001830 return -1;
1831 }
1832 sum += count;
1833 }
1834
1835 xmlListPopFront(writer->nsstack);
1836 }
1837 break;
1838
1839 default:
1840 xmlListClear(writer->nsstack);
1841 return -1;
1842 }
1843
1844 return sum;
1845}
1846
1847/**
1848 * xmlTextWriterWriteFormatAttribute:
1849 * @writer: the xmlTextWriterPtr
1850 * @name: attribute name
1851 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001852 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001853 *
1854 * Write a formatted xml attribute.
1855 *
1856 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1857 */
1858int
1859xmlTextWriterWriteFormatAttribute(xmlTextWriterPtr writer,
1860 const xmlChar * name, const char *format,
1861 ...)
1862{
1863 int rc;
1864 va_list ap;
1865
1866 va_start(ap, format);
1867
1868 rc = xmlTextWriterWriteVFormatAttribute(writer, name, format, ap);
1869
1870 va_end(ap);
1871 return rc;
1872}
1873
1874/**
1875 * xmlTextWriterWriteVFormatAttribute:
1876 * @writer: the xmlTextWriterPtr
1877 * @name: attribute name
1878 * @format: format string (see printf)
1879 * @argptr: pointer to the first member of the variable argument list.
1880 *
1881 * Write a formatted xml attribute.
1882 *
1883 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1884 */
1885int
1886xmlTextWriterWriteVFormatAttribute(xmlTextWriterPtr writer,
1887 const xmlChar * name,
1888 const char *format, va_list argptr)
1889{
1890 int rc;
1891 xmlChar *buf;
1892
1893 if (writer == NULL)
1894 return -1;
1895
1896 buf = xmlTextWriterVSprintf(format, argptr);
1897 if (buf == 0)
1898 return 0;
1899
1900 rc = xmlTextWriterWriteAttribute(writer, name, buf);
1901
1902 xmlFree(buf);
1903 return rc;
1904}
1905
1906/**
1907 * xmlTextWriterWriteAttribute:
1908 * @writer: the xmlTextWriterPtr
1909 * @name: attribute name
1910 * @content: attribute content
1911 *
1912 * Write an xml attribute.
1913 *
1914 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1915 */
1916int
1917xmlTextWriterWriteAttribute(xmlTextWriterPtr writer, const xmlChar * name,
1918 const xmlChar * content)
1919{
1920 int count;
1921 int sum;
1922
1923 sum = 0;
1924 count = xmlTextWriterStartAttribute(writer, name);
1925 if (count < 0)
1926 return -1;
1927 sum += count;
1928 count = xmlTextWriterWriteString(writer, content);
1929 if (count < 0)
1930 return -1;
1931 sum += count;
1932 count = xmlTextWriterEndAttribute(writer);
1933 if (count < 0)
1934 return -1;
1935 sum += count;
1936
1937 return sum;
1938}
1939
1940/**
1941 * xmlTextWriterWriteFormatAttributeNS:
1942 * @writer: the xmlTextWriterPtr
1943 * @prefix: namespace prefix
1944 * @name: attribute local name
1945 * @namespaceURI: namespace URI
1946 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001947 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001948 *
1949 * Write a formatted xml attribute.with namespace support
1950 *
1951 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1952 */
1953int
1954xmlTextWriterWriteFormatAttributeNS(xmlTextWriterPtr writer,
1955 const xmlChar * prefix,
1956 const xmlChar * name,
1957 const xmlChar * namespaceURI,
1958 const char *format, ...)
1959{
1960 int rc;
1961 va_list ap;
1962
1963 va_start(ap, format);
1964
1965 rc = xmlTextWriterWriteVFormatAttributeNS(writer, prefix, name,
1966 namespaceURI, format, ap);
1967
1968 va_end(ap);
1969 return rc;
1970}
1971
1972/**
1973 * xmlTextWriterWriteVFormatAttributeNS:
1974 * @writer: the xmlTextWriterPtr
1975 * @prefix: namespace prefix
1976 * @name: attribute local name
1977 * @namespaceURI: namespace URI
1978 * @format: format string (see printf)
1979 * @argptr: pointer to the first member of the variable argument list.
1980 *
1981 * Write a formatted xml attribute.with namespace support
1982 *
1983 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1984 */
1985int
1986xmlTextWriterWriteVFormatAttributeNS(xmlTextWriterPtr writer,
1987 const xmlChar * prefix,
1988 const xmlChar * name,
1989 const xmlChar * namespaceURI,
1990 const char *format, va_list argptr)
1991{
1992 int rc;
1993 xmlChar *buf;
1994
1995 if (writer == NULL)
1996 return -1;
1997
1998 buf = xmlTextWriterVSprintf(format, argptr);
1999 if (buf == 0)
2000 return 0;
2001
2002 rc = xmlTextWriterWriteAttributeNS(writer, prefix, name, namespaceURI,
2003 buf);
2004
2005 xmlFree(buf);
2006 return rc;
2007}
2008
2009/**
2010 * xmlTextWriterWriteAttributeNS:
2011 * @writer: the xmlTextWriterPtr
2012 * @prefix: namespace prefix
2013 * @name: attribute local name
2014 * @namespaceURI: namespace URI
2015 * @content: attribute content
2016 *
2017 * Write an xml attribute.
2018 *
2019 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2020 */
2021int
2022xmlTextWriterWriteAttributeNS(xmlTextWriterPtr writer,
2023 const xmlChar * prefix, const xmlChar * name,
2024 const xmlChar * namespaceURI,
2025 const xmlChar * content)
2026{
2027 int count;
2028 int sum;
2029 xmlChar *buf;
2030
2031 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
2032 return -1;
2033
2034 buf = 0;
2035 if (prefix != NULL) {
2036 buf = xmlStrdup(prefix);
2037 buf = xmlStrcat(buf, BAD_CAST ":");
2038 }
2039 buf = xmlStrcat(buf, name);
2040
2041 sum = 0;
2042 count = xmlTextWriterWriteAttribute(writer, buf, content);
2043 xmlFree(buf);
2044 if (count < 0)
2045 return -1;
2046 sum += count;
2047
2048 if (namespaceURI != NULL) {
2049 buf = 0;
2050 buf = xmlStrdup(BAD_CAST "xmlns");
2051 if (prefix != NULL) {
2052 buf = xmlStrcat(buf, BAD_CAST ":");
2053 buf = xmlStrcat(buf, prefix);
2054 }
2055 count = xmlTextWriterWriteAttribute(writer, buf, namespaceURI);
2056 xmlFree(buf);
2057 if (count < 0)
2058 return -1;
2059 sum += count;
2060 }
2061 return sum;
2062}
2063
2064/**
2065 * xmlTextWriterWriteFormatElement:
2066 * @writer: the xmlTextWriterPtr
2067 * @name: element name
2068 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002069 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002070 *
2071 * Write a formatted xml element.
2072 *
2073 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2074 */
2075int
2076xmlTextWriterWriteFormatElement(xmlTextWriterPtr writer,
2077 const xmlChar * name, const char *format,
2078 ...)
2079{
2080 int rc;
2081 va_list ap;
2082
2083 va_start(ap, format);
2084
2085 rc = xmlTextWriterWriteVFormatElement(writer, name, format, ap);
2086
2087 va_end(ap);
2088 return rc;
2089}
2090
2091/**
2092 * xmlTextWriterWriteVFormatElement:
2093 * @writer: the xmlTextWriterPtr
2094 * @name: element name
2095 * @format: format string (see printf)
2096 * @argptr: pointer to the first member of the variable argument list.
2097 *
2098 * Write a formatted xml element.
2099 *
2100 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2101 */
2102int
2103xmlTextWriterWriteVFormatElement(xmlTextWriterPtr writer,
2104 const xmlChar * name, const char *format,
2105 va_list argptr)
2106{
2107 int rc;
2108 xmlChar *buf;
2109
2110 if (writer == NULL)
2111 return -1;
2112
2113 buf = xmlTextWriterVSprintf(format, argptr);
2114 if (buf == 0)
2115 return 0;
2116
2117 rc = xmlTextWriterWriteElement(writer, name, buf);
2118
2119 xmlFree(buf);
2120 return rc;
2121}
2122
2123/**
2124 * xmlTextWriterWriteElement:
2125 * @writer: the xmlTextWriterPtr
2126 * @name: element name
2127 * @content: element content
2128 *
2129 * Write an xml element.
2130 *
2131 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2132 */
2133int
2134xmlTextWriterWriteElement(xmlTextWriterPtr writer, const xmlChar * name,
2135 const xmlChar * content)
2136{
2137 int count;
2138 int sum;
2139
2140 sum = 0;
2141 count = xmlTextWriterStartElement(writer, name);
2142 if (count == -1)
2143 return -1;
2144 sum += count;
2145 count = xmlTextWriterWriteString(writer, content);
2146 if (count == -1)
2147 return -1;
2148 sum += count;
2149 count = xmlTextWriterEndElement(writer);
2150 if (count == -1)
2151 return -1;
2152 sum += count;
2153
2154 return sum;
2155}
2156
2157/**
2158 * xmlTextWriterWriteFormatElementNS:
2159 * @writer: the xmlTextWriterPtr
2160 * @prefix: namespace prefix
2161 * @name: element local name
2162 * @namespaceURI: namespace URI
2163 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002164 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002165 *
2166 * Write a formatted xml element with namespace support.
2167 *
2168 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2169 */
2170int
2171xmlTextWriterWriteFormatElementNS(xmlTextWriterPtr writer,
2172 const xmlChar * prefix,
2173 const xmlChar * name,
2174 const xmlChar * namespaceURI,
2175 const char *format, ...)
2176{
2177 int rc;
2178 va_list ap;
2179
2180 va_start(ap, format);
2181
2182 rc = xmlTextWriterWriteVFormatElementNS(writer, prefix, name,
2183 namespaceURI, format, ap);
2184
2185 va_end(ap);
2186 return rc;
2187}
2188
2189/**
2190 * xmlTextWriterWriteVFormatElementNS:
2191 * @writer: the xmlTextWriterPtr
2192 * @prefix: namespace prefix
2193 * @name: element local name
2194 * @namespaceURI: namespace URI
2195 * @format: format string (see printf)
2196 * @argptr: pointer to the first member of the variable argument list.
2197 *
2198 * Write a formatted xml element with namespace support.
2199 *
2200 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2201 */
2202int
2203xmlTextWriterWriteVFormatElementNS(xmlTextWriterPtr writer,
2204 const xmlChar * prefix,
2205 const xmlChar * name,
2206 const xmlChar * namespaceURI,
2207 const char *format, va_list argptr)
2208{
2209 int rc;
2210 xmlChar *buf;
2211
2212 if (writer == NULL)
2213 return -1;
2214
2215 buf = xmlTextWriterVSprintf(format, argptr);
2216 if (buf == 0)
2217 return 0;
2218
2219 rc = xmlTextWriterWriteElementNS(writer, prefix, name, namespaceURI,
2220 buf);
2221
2222 xmlFree(buf);
2223 return rc;
2224}
2225
2226/**
2227 * xmlTextWriterWriteElementNS:
2228 * @writer: the xmlTextWriterPtr
2229 * @prefix: namespace prefix
2230 * @name: element local name
2231 * @namespaceURI: namespace URI
2232 * @content: element content
2233 *
2234 * Write an xml element with namespace support.
2235 *
2236 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2237 */
2238int
2239xmlTextWriterWriteElementNS(xmlTextWriterPtr writer,
2240 const xmlChar * prefix, const xmlChar * name,
2241 const xmlChar * namespaceURI,
2242 const xmlChar * content)
2243{
2244 int count;
2245 int sum;
2246
2247 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
2248 return -1;
2249
2250 sum = 0;
2251 count =
2252 xmlTextWriterStartElementNS(writer, prefix, name, namespaceURI);
2253 if (count < 0)
2254 return -1;
2255 sum += count;
2256 count = xmlTextWriterWriteString(writer, content);
2257 if (count == -1)
2258 return -1;
2259 sum += count;
2260 count = xmlTextWriterEndElement(writer);
2261 if (count == -1)
2262 return -1;
2263 sum += count;
2264
2265 return sum;
2266}
2267
2268/**
2269 * xmlTextWriterStartPI:
2270 * @writer: the xmlTextWriterPtr
2271 * @target: PI target
2272 *
2273 * Start an xml PI.
2274 *
2275 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2276 */
2277int
2278xmlTextWriterStartPI(xmlTextWriterPtr writer, const xmlChar * target)
2279{
2280 int count;
2281 int sum;
2282 xmlLinkPtr lk;
2283 xmlTextWriterStackEntry *p;
2284
2285 if ((writer == NULL) || (target == NULL) || (*target == '\0'))
2286 return -1;
2287
2288 if (xmlStrcasecmp(target, (const xmlChar *) "xml") == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002289 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002290 "xmlTextWriterStartPI : target name [Xx][Mm][Ll] is reserved for xml standardization!\n");
2291 return -1;
2292 }
2293
2294 sum = 0;
2295 lk = xmlListFront(writer->nodes);
2296 if (lk != 0) {
2297 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2298 if (p != 0) {
2299 switch (p->state) {
2300 case XML_TEXTWRITER_ATTRIBUTE:
2301 count = xmlTextWriterEndAttribute(writer);
2302 if (count < 0)
2303 return -1;
2304 sum += count;
2305 /* fallthrough */
2306 case XML_TEXTWRITER_NAME:
2307 count = xmlOutputBufferWriteString(writer->out, ">");
2308 if (count < 0)
2309 return -1;
2310 sum += count;
2311 p->state = XML_TEXTWRITER_TEXT;
2312 break;
Daniel Veillardab69f362004-02-17 11:40:32 +00002313 case XML_TEXTWRITER_NONE:
2314 case XML_TEXTWRITER_TEXT:
2315 case XML_TEXTWRITER_DTD:
2316 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002317 case XML_TEXTWRITER_PI:
2318 case XML_TEXTWRITER_PI_TEXT:
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002319 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002320 "xmlTextWriterStartPI : nested PI!\n");
2321 return -1;
2322 default:
2323 return -1;
2324 }
2325 }
2326 }
2327
2328 p = (xmlTextWriterStackEntry *)
2329 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2330 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002331 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002332 "xmlTextWriterStartPI : out of memory!\n");
2333 return -1;
2334 }
2335
2336 p->name = xmlStrdup(target);
2337 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002338 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002339 "xmlTextWriterStartPI : out of memory!\n");
2340 xmlFree(p);
2341 return -1;
2342 }
2343 p->state = XML_TEXTWRITER_PI;
2344
2345 xmlListPushFront(writer->nodes, p);
2346
2347 count = xmlOutputBufferWriteString(writer->out, "<?");
2348 if (count < 0)
2349 return -1;
2350 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002351 count =
2352 xmlOutputBufferWriteString(writer->out, (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002353 if (count < 0)
2354 return -1;
2355 sum += count;
2356
2357 return sum;
2358}
2359
2360/**
2361 * xmlTextWriterEndPI:
2362 * @writer: the xmlTextWriterPtr
2363 *
2364 * End the current xml PI.
2365 *
2366 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2367 */
2368int
2369xmlTextWriterEndPI(xmlTextWriterPtr writer)
2370{
2371 int count;
2372 int sum;
2373 xmlLinkPtr lk;
2374 xmlTextWriterStackEntry *p;
2375
2376 if (writer == NULL)
2377 return -1;
2378
2379 lk = xmlListFront(writer->nodes);
2380 if (lk == 0)
2381 return 0;
2382
2383 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2384 if (p == 0)
2385 return 0;
2386
2387 sum = 0;
2388 switch (p->state) {
2389 case XML_TEXTWRITER_PI:
2390 case XML_TEXTWRITER_PI_TEXT:
2391 count = xmlOutputBufferWriteString(writer->out, "?>");
2392 if (count < 0)
2393 return -1;
2394 sum += count;
2395 break;
2396 default:
2397 return -1;
2398 }
2399
2400 xmlListPopFront(writer->nodes);
2401 return sum;
2402}
2403
2404/**
2405 * xmlTextWriterWriteFormatPI:
2406 * @writer: the xmlTextWriterPtr
2407 * @target: PI target
2408 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002409 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002410 *
2411 * Write a formatted PI.
2412 *
2413 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2414 */
2415int
2416xmlTextWriterWriteFormatPI(xmlTextWriterPtr writer, const xmlChar * target,
2417 const char *format, ...)
2418{
2419 int rc;
2420 va_list ap;
2421
2422 va_start(ap, format);
2423
2424 rc = xmlTextWriterWriteVFormatPI(writer, target, format, ap);
2425
2426 va_end(ap);
2427 return rc;
2428}
2429
2430/**
2431 * xmlTextWriterWriteVFormatPI:
2432 * @writer: the xmlTextWriterPtr
2433 * @target: PI target
2434 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002435 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00002436 *
2437 * Write a formatted xml PI.
2438 *
2439 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2440 */
2441int
2442xmlTextWriterWriteVFormatPI(xmlTextWriterPtr writer,
2443 const xmlChar * target, const char *format,
2444 va_list argptr)
2445{
2446 int rc;
2447 xmlChar *buf;
2448
2449 if (writer == NULL)
2450 return -1;
2451
2452 buf = xmlTextWriterVSprintf(format, argptr);
2453 if (buf == 0)
2454 return 0;
2455
2456 rc = xmlTextWriterWritePI(writer, target, buf);
2457
2458 xmlFree(buf);
2459 return rc;
2460}
2461
2462/**
2463 * xmlTextWriterWritePI:
2464 * @writer: the xmlTextWriterPtr
2465 * @target: PI target
2466 * @content: PI content
2467 *
2468 * Write an xml PI.
2469 *
2470 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2471 */
2472int
2473xmlTextWriterWritePI(xmlTextWriterPtr writer, const xmlChar * target,
2474 const xmlChar * content)
2475{
2476 int count;
2477 int sum;
2478
2479 sum = 0;
2480 count = xmlTextWriterStartPI(writer, target);
2481 if (count == -1)
2482 return -1;
2483 sum += count;
2484 if (content != 0) {
2485 count = xmlTextWriterWriteString(writer, content);
2486 if (count == -1)
2487 return -1;
2488 sum += count;
2489 }
2490 count = xmlTextWriterEndPI(writer);
2491 if (count == -1)
2492 return -1;
2493 sum += count;
2494
2495 return sum;
2496}
2497
2498/**
2499 * xmlTextWriterStartCDATA:
2500 * @writer: the xmlTextWriterPtr
2501 *
2502 * Start an xml CDATA section.
2503 *
2504 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2505 */
2506int
2507xmlTextWriterStartCDATA(xmlTextWriterPtr writer)
2508{
2509 int count;
2510 int sum;
2511 xmlLinkPtr lk;
2512 xmlTextWriterStackEntry *p;
2513
2514 if (writer == NULL)
2515 return -1;
2516
2517 sum = 0;
2518 lk = xmlListFront(writer->nodes);
2519 if (lk != 0) {
2520 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2521 if (p != 0) {
2522 switch (p->state) {
2523 case XML_TEXTWRITER_NONE:
2524 case XML_TEXTWRITER_PI:
2525 case XML_TEXTWRITER_PI_TEXT:
2526 break;
2527 case XML_TEXTWRITER_ATTRIBUTE:
2528 count = xmlTextWriterEndAttribute(writer);
2529 if (count < 0)
2530 return -1;
2531 sum += count;
2532 /* fallthrough */
2533 case XML_TEXTWRITER_NAME:
2534 count = xmlOutputBufferWriteString(writer->out, ">");
2535 if (count < 0)
2536 return -1;
2537 sum += count;
2538 p->state = XML_TEXTWRITER_TEXT;
2539 break;
2540 case XML_TEXTWRITER_CDATA:
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002541 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002542 "xmlTextWriterStartCDATA : CDATA not allowed in this context!\n");
2543 return -1;
2544 default:
2545 return -1;
2546 }
2547 }
2548 }
2549
2550 p = (xmlTextWriterStackEntry *)
2551 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2552 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002553 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002554 "xmlTextWriterStartCDATA : out of memory!\n");
2555 return -1;
2556 }
2557
2558 p->name = 0;
2559 p->state = XML_TEXTWRITER_CDATA;
2560
2561 xmlListPushFront(writer->nodes, p);
2562
2563 count = xmlOutputBufferWriteString(writer->out, "<![CDATA[");
2564 if (count < 0)
2565 return -1;
2566 sum += count;
2567
2568 return sum;
2569}
2570
2571/**
2572 * xmlTextWriterEndCDATA:
2573 * @writer: the xmlTextWriterPtr
2574 *
2575 * End an xml CDATA section.
2576 *
2577 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2578 */
2579int
2580xmlTextWriterEndCDATA(xmlTextWriterPtr writer)
2581{
2582 int count;
2583 int sum;
2584 xmlLinkPtr lk;
2585 xmlTextWriterStackEntry *p;
2586
2587 if (writer == NULL)
2588 return -1;
2589
2590 lk = xmlListFront(writer->nodes);
2591 if (lk == 0)
2592 return -1;
2593
2594 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2595 if (p == 0)
2596 return -1;
2597
2598 sum = 0;
2599 switch (p->state) {
2600 case XML_TEXTWRITER_CDATA:
2601 count = xmlOutputBufferWriteString(writer->out, "]]>");
2602 if (count < 0)
2603 return -1;
2604 sum += count;
2605 break;
2606 default:
2607 return -1;
2608 }
2609
2610 xmlListPopFront(writer->nodes);
2611 return sum;
2612}
2613
2614/**
2615 * xmlTextWriterWriteFormatCDATA:
2616 * @writer: the xmlTextWriterPtr
2617 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002618 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002619 *
2620 * Write a formatted xml CDATA.
2621 *
2622 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2623 */
2624int
2625xmlTextWriterWriteFormatCDATA(xmlTextWriterPtr writer, const char *format,
2626 ...)
2627{
2628 int rc;
2629 va_list ap;
2630
2631 va_start(ap, format);
2632
2633 rc = xmlTextWriterWriteVFormatCDATA(writer, format, ap);
2634
2635 va_end(ap);
2636 return rc;
2637}
2638
2639/**
2640 * xmlTextWriterWriteVFormatCDATA:
2641 * @writer: the xmlTextWriterPtr
2642 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002643 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00002644 *
2645 * Write a formatted xml CDATA.
2646 *
2647 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2648 */
2649int
2650xmlTextWriterWriteVFormatCDATA(xmlTextWriterPtr writer, const char *format,
2651 va_list argptr)
2652{
2653 int rc;
2654 xmlChar *buf;
2655
2656 if (writer == NULL)
2657 return -1;
2658
2659 buf = xmlTextWriterVSprintf(format, argptr);
2660 if (buf == 0)
2661 return 0;
2662
2663 rc = xmlTextWriterWriteCDATA(writer, buf);
2664
2665 xmlFree(buf);
2666 return rc;
2667}
2668
2669/**
2670 * xmlTextWriterWriteCDATA:
2671 * @writer: the xmlTextWriterPtr
2672 * @content: CDATA content
2673 *
2674 * Write an xml CDATA.
2675 *
2676 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2677 */
2678int
2679xmlTextWriterWriteCDATA(xmlTextWriterPtr writer, const xmlChar * content)
2680{
2681 int count;
2682 int sum;
2683
2684 sum = 0;
2685 count = xmlTextWriterStartCDATA(writer);
2686 if (count == -1)
2687 return -1;
2688 sum += count;
2689 if (content != 0) {
2690 count = xmlTextWriterWriteString(writer, content);
2691 if (count == -1)
2692 return -1;
2693 sum += count;
2694 }
2695 count = xmlTextWriterEndCDATA(writer);
2696 if (count == -1)
2697 return -1;
2698 sum += count;
2699
2700 return sum;
2701}
2702
2703/**
2704 * xmlTextWriterStartDTD:
2705 * @writer: the xmlTextWriterPtr
2706 * @name: the name of the DTD
2707 * @pubid: the public identifier, which is an alternative to the system identifier
2708 * @sysid: the system identifier, which is the URI of the DTD
2709 *
2710 * Start an xml DTD.
2711 *
2712 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2713 */
2714int
2715xmlTextWriterStartDTD(xmlTextWriterPtr writer,
2716 const xmlChar * name,
2717 const xmlChar * pubid, const xmlChar * sysid)
2718{
2719 int count;
2720 int sum;
2721 xmlLinkPtr lk;
2722 xmlTextWriterStackEntry *p;
2723
2724 if (writer == NULL || name == NULL || *name == '\0')
2725 return -1;
2726
2727 sum = 0;
2728 lk = xmlListFront(writer->nodes);
Daniel Veillardab69f362004-02-17 11:40:32 +00002729 if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002730 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002731 "xmlTextWriterStartDTD : DTD allowed only in prolog!\n");
2732 return -1;
2733 }
2734
2735 p = (xmlTextWriterStackEntry *)
2736 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2737 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002738 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002739 "xmlTextWriterStartDTD : out of memory!\n");
2740 return -1;
2741 }
2742
2743 p->name = xmlStrdup(name);
2744 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002745 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002746 "xmlTextWriterStartDTD : out of memory!\n");
2747 xmlFree(p);
2748 return -1;
2749 }
2750 p->state = XML_TEXTWRITER_DTD;
2751
2752 xmlListPushFront(writer->nodes, p);
2753
2754 count = xmlOutputBufferWriteString(writer->out, "<!DOCTYPE ");
2755 if (count < 0)
2756 return -1;
2757 sum += count;
2758 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
2759 if (count < 0)
2760 return -1;
2761 sum += count;
2762
2763 if (pubid != 0) {
2764 if (sysid == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00002765 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard1d211e22003-10-20 22:32:39 +00002766 "xmlTextWriterStartDTD : system identifier needed!\n");
2767 return -1;
2768 }
2769
Daniel Veillard500a1de2004-03-22 15:22:58 +00002770 if (writer->indent)
2771 count = xmlOutputBufferWrite(writer->out, 1, "\n");
2772 else
2773 count = xmlOutputBufferWrite(writer->out, 1, " ");
2774 if (count < 0)
2775 return -1;
2776 sum += count;
2777
2778 count = xmlOutputBufferWriteString(writer->out, "PUBLIC ");
2779 if (count < 0)
2780 return -1;
2781 sum += count;
2782
2783 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002784 if (count < 0)
2785 return -1;
2786 sum += count;
2787
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002788 count =
2789 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002790 if (count < 0)
2791 return -1;
2792 sum += count;
2793
Daniel Veillard500a1de2004-03-22 15:22:58 +00002794 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002795 if (count < 0)
2796 return -1;
2797 sum += count;
2798 }
2799
2800 if (sysid != 0) {
2801 if (pubid == 0) {
Daniel Veillard500a1de2004-03-22 15:22:58 +00002802 if (writer->indent)
2803 count = xmlOutputBufferWrite(writer->out, 1, "\n");
2804 else
2805 count = xmlOutputBufferWrite(writer->out, 1, " ");
2806 if (count < 0)
2807 return -1;
2808 sum += count;
2809 count = xmlOutputBufferWriteString(writer->out, "SYSTEM ");
2810 if (count < 0)
2811 return -1;
2812 sum += count;
2813 } else if (writer->indent) {
2814 count = xmlOutputBufferWriteString(writer->out, "\n ");
Daniel Veillard1d211e22003-10-20 22:32:39 +00002815 if (count < 0)
2816 return -1;
2817 sum += count;
2818 }
2819
Daniel Veillard500a1de2004-03-22 15:22:58 +00002820 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002821 if (count < 0)
2822 return -1;
2823 sum += count;
2824
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002825 count =
2826 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002827 if (count < 0)
2828 return -1;
2829 sum += count;
2830
Daniel Veillard500a1de2004-03-22 15:22:58 +00002831 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002832 if (count < 0)
2833 return -1;
2834 sum += count;
2835 }
2836
2837 return sum;
2838}
2839
2840/**
2841 * xmlTextWriterEndDTD:
2842 * @writer: the xmlTextWriterPtr
2843 *
2844 * End an xml DTD.
2845 *
2846 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2847 */
2848int
2849xmlTextWriterEndDTD(xmlTextWriterPtr writer)
2850{
Daniel Veillard500a1de2004-03-22 15:22:58 +00002851 int loop;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002852 int count;
2853 int sum;
2854 xmlLinkPtr lk;
2855 xmlTextWriterStackEntry *p;
2856
2857 if (writer == NULL)
2858 return -1;
2859
2860 sum = 0;
Daniel Veillard500a1de2004-03-22 15:22:58 +00002861 loop = 1;
2862 while (loop) {
2863 lk = xmlListFront(writer->nodes);
2864 if (lk == NULL)
Daniel Veillard1d211e22003-10-20 22:32:39 +00002865 break;
Daniel Veillard500a1de2004-03-22 15:22:58 +00002866 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2867 if (p == 0)
2868 break;
2869 switch (p->state) {
2870 case XML_TEXTWRITER_DTD_TEXT:
2871 count = xmlOutputBufferWriteString(writer->out, "]");
2872 if (count < 0)
2873 return -1;
2874 sum += count;
2875 /* fallthrough */
2876 case XML_TEXTWRITER_DTD:
2877 count = xmlOutputBufferWriteString(writer->out, ">");
2878
2879 if (writer->indent) {
2880 if (count < 0)
2881 return -1;
2882 sum += count;
2883 count = xmlOutputBufferWriteString(writer->out, "\n");
2884 }
2885
2886 xmlListPopFront(writer->nodes);
2887 break;
2888 case XML_TEXTWRITER_DTD_ELEM:
2889 case XML_TEXTWRITER_DTD_ELEM_TEXT:
2890 count = xmlTextWriterEndDTDElement(writer);
2891 break;
2892 case XML_TEXTWRITER_DTD_ATTL:
2893 case XML_TEXTWRITER_DTD_ATTL_TEXT:
2894 count = xmlTextWriterEndDTDAttlist(writer);
2895 break;
2896 case XML_TEXTWRITER_DTD_ENTY:
2897 case XML_TEXTWRITER_DTD_PENT:
2898 case XML_TEXTWRITER_DTD_ENTY_TEXT:
2899 count = xmlTextWriterEndDTDEntity(writer);
2900 break;
2901 case XML_TEXTWRITER_COMMENT:
2902 count = xmlTextWriterEndComment(writer);
2903 break;
2904 default:
2905 loop = 0;
2906 continue;
2907 }
2908
2909 if (count < 0)
Daniel Veillard1d211e22003-10-20 22:32:39 +00002910 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00002911 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002912 }
2913
Daniel Veillard1d211e22003-10-20 22:32:39 +00002914 return sum;
2915}
2916
2917/**
2918 * xmlTextWriterWriteFormatDTD:
2919 * @writer: the xmlTextWriterPtr
2920 * @name: the name of the DTD
2921 * @pubid: the public identifier, which is an alternative to the system identifier
2922 * @sysid: the system identifier, which is the URI of the DTD
2923 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002924 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002925 *
2926 * Write a DTD with a formatted markup declarations part.
2927 *
2928 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2929 */
2930int
2931xmlTextWriterWriteFormatDTD(xmlTextWriterPtr writer,
2932 const xmlChar * name,
2933 const xmlChar * pubid,
2934 const xmlChar * sysid, const char *format, ...)
2935{
2936 int rc;
2937 va_list ap;
2938
2939 va_start(ap, format);
2940
2941 rc = xmlTextWriterWriteVFormatDTD(writer, name, pubid, sysid, format,
2942 ap);
2943
2944 va_end(ap);
2945 return rc;
2946}
2947
2948/**
2949 * xmlTextWriterWriteVFormatDTD:
2950 * @writer: the xmlTextWriterPtr
2951 * @name: the name of the DTD
2952 * @pubid: the public identifier, which is an alternative to the system identifier
2953 * @sysid: the system identifier, which is the URI of the DTD
2954 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002955 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00002956 *
2957 * Write a DTD with a formatted markup declarations part.
2958 *
2959 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2960 */
2961int
2962xmlTextWriterWriteVFormatDTD(xmlTextWriterPtr writer,
2963 const xmlChar * name,
2964 const xmlChar * pubid,
2965 const xmlChar * sysid,
2966 const char *format, va_list argptr)
2967{
2968 int rc;
2969 xmlChar *buf;
2970
2971 if (writer == NULL)
2972 return -1;
2973
2974 buf = xmlTextWriterVSprintf(format, argptr);
2975 if (buf == 0)
2976 return 0;
2977
2978 rc = xmlTextWriterWriteDTD(writer, name, pubid, sysid, buf);
2979
2980 xmlFree(buf);
2981 return rc;
2982}
2983
2984/**
2985 * xmlTextWriterWriteDTD:
2986 * @writer: the xmlTextWriterPtr
2987 * @name: the name of the DTD
2988 * @pubid: the public identifier, which is an alternative to the system identifier
2989 * @sysid: the system identifier, which is the URI of the DTD
William M. Brackb1d53162003-11-18 06:54:40 +00002990 * @subset: string content of the DTD
Daniel Veillard1d211e22003-10-20 22:32:39 +00002991 *
2992 * Write a DTD.
2993 *
2994 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2995 */
2996int
2997xmlTextWriterWriteDTD(xmlTextWriterPtr writer,
2998 const xmlChar * name,
2999 const xmlChar * pubid,
3000 const xmlChar * sysid, const xmlChar * subset)
3001{
3002 int count;
3003 int sum;
3004
3005 sum = 0;
3006 count = xmlTextWriterStartDTD(writer, name, pubid, sysid);
3007 if (count == -1)
3008 return -1;
3009 sum += count;
3010 if (subset != 0) {
3011 count = xmlTextWriterWriteString(writer, subset);
3012 if (count == -1)
3013 return -1;
3014 sum += count;
3015 }
3016 count = xmlTextWriterEndDTD(writer);
3017 if (count == -1)
3018 return -1;
3019 sum += count;
3020
3021 return sum;
3022}
3023
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003024/**
3025 * xmlTextWriterStartDTDElement:
3026 * @writer: the xmlTextWriterPtr
3027 * @name: the name of the DTD element
3028 *
3029 * Start an xml DTD element.
3030 *
3031 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3032 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003033int
3034xmlTextWriterStartDTDElement(xmlTextWriterPtr writer, const xmlChar * name)
3035{
3036 int count;
3037 int sum;
3038 xmlLinkPtr lk;
3039 xmlTextWriterStackEntry *p;
3040
3041 if (writer == NULL || name == NULL || *name == '\0')
3042 return -1;
3043
3044 sum = 0;
3045 lk = xmlListFront(writer->nodes);
3046 if (lk == 0) {
3047 return -1;
3048 }
3049
3050 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
Daniel Veillard500a1de2004-03-22 15:22:58 +00003051 if (p != 0) {
3052 switch (p->state) {
3053 case XML_TEXTWRITER_DTD:
3054 count = xmlOutputBufferWriteString(writer->out, " [");
3055 if (count < 0)
3056 return -1;
3057 sum += count;
3058 if (writer->indent) {
3059 count = xmlOutputBufferWriteString(writer->out, "\n");
3060 if (count < 0)
3061 return -1;
3062 sum += count;
3063 }
3064 p->state = XML_TEXTWRITER_DTD_TEXT;
3065 /* fallthrough */
3066 case XML_TEXTWRITER_DTD_TEXT:
3067 case XML_TEXTWRITER_NONE:
3068 break;
3069 default:
Daniel Veillard1d211e22003-10-20 22:32:39 +00003070 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00003071 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00003072 }
3073
3074 p = (xmlTextWriterStackEntry *)
3075 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3076 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003077 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003078 "xmlTextWriterStartDTDElement : out of memory!\n");
3079 return -1;
3080 }
3081
3082 p->name = xmlStrdup(name);
3083 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003084 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003085 "xmlTextWriterStartDTDElement : out of memory!\n");
3086 xmlFree(p);
3087 return -1;
3088 }
3089 p->state = XML_TEXTWRITER_DTD_ELEM;
3090
3091 xmlListPushFront(writer->nodes, p);
3092
Daniel Veillard500a1de2004-03-22 15:22:58 +00003093 if (writer->indent) {
3094 count = xmlTextWriterWriteIndent(writer);
3095 if (count < 0)
3096 return -1;
3097 sum += count;
3098 }
3099
Daniel Veillard1d211e22003-10-20 22:32:39 +00003100 count = xmlOutputBufferWriteString(writer->out, "<!ELEMENT ");
3101 if (count < 0)
3102 return -1;
3103 sum += count;
3104 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
3105 if (count < 0)
3106 return -1;
3107 sum += count;
3108
3109 return sum;
3110}
3111
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003112/**
Daniel Veillard500a1de2004-03-22 15:22:58 +00003113 * xmlTextWriterEndDTDElement:
3114 * @writer: the xmlTextWriterPtr
3115 *
3116 * End an xml DTD element.
3117 *
3118 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3119 */
3120int
3121xmlTextWriterEndDTDElement(xmlTextWriterPtr writer)
3122{
3123 int count;
3124 int sum;
3125 xmlLinkPtr lk;
3126 xmlTextWriterStackEntry *p;
3127
3128 if (writer == NULL)
3129 return -1;
3130
3131 sum = 0;
3132 lk = xmlListFront(writer->nodes);
3133 if (lk == 0)
3134 return -1;
3135
3136 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3137 if (p == 0)
3138 return -1;
3139
3140 switch (p->state) {
3141 case XML_TEXTWRITER_DTD_ELEM:
3142 case XML_TEXTWRITER_DTD_ELEM_TEXT:
3143 count = xmlOutputBufferWriteString(writer->out, ">");
3144 if (count < 0)
3145 return -1;
3146 sum += count;
3147 break;
3148 default:
3149 return -1;
3150 }
3151
3152 if (writer->indent) {
3153 count = xmlOutputBufferWriteString(writer->out, "\n");
3154 if (count < 0)
3155 return -1;
3156 sum += count;
3157 }
3158
3159 xmlListPopFront(writer->nodes);
3160 return sum;
3161}
3162
3163/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003164 * xmlTextWriterWriteFormatDTDElement:
3165 * @writer: the xmlTextWriterPtr
3166 * @name: the name of the DTD element
3167 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003168 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003169 *
3170 * Write a formatted DTD element.
3171 *
3172 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3173 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003174int
3175xmlTextWriterWriteFormatDTDElement(xmlTextWriterPtr writer,
3176 const xmlChar * name,
3177 const char *format, ...)
3178{
3179 int rc;
3180 va_list ap;
3181
3182 va_start(ap, format);
3183
3184 rc = xmlTextWriterWriteVFormatDTDElement(writer, name, format, ap);
3185
3186 va_end(ap);
3187 return rc;
3188}
3189
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003190/**
3191 * xmlTextWriterWriteVFormatDTDElement:
3192 * @writer: the xmlTextWriterPtr
3193 * @name: the name of the DTD element
3194 * @format: format string (see printf)
3195 * @argptr: pointer to the first member of the variable argument list.
3196 *
3197 * Write a formatted DTD element.
3198 *
3199 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3200 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003201int
3202xmlTextWriterWriteVFormatDTDElement(xmlTextWriterPtr writer,
3203 const xmlChar * name,
3204 const char *format, va_list argptr)
3205{
3206 int rc;
3207 xmlChar *buf;
3208
3209 if (writer == NULL)
3210 return -1;
3211
3212 buf = xmlTextWriterVSprintf(format, argptr);
3213 if (buf == 0)
3214 return 0;
3215
3216 rc = xmlTextWriterWriteDTDElement(writer, name, buf);
3217
3218 xmlFree(buf);
3219 return rc;
3220}
3221
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003222/**
3223 * xmlTextWriterWriteDTDElement:
3224 * @writer: the xmlTextWriterPtr
3225 * @name: the name of the DTD element
3226 * @content: content of the element
3227 *
3228 * Write a DTD element.
3229 *
3230 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3231 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003232int
3233xmlTextWriterWriteDTDElement(xmlTextWriterPtr writer,
3234 const xmlChar * name, const xmlChar * content)
3235{
3236 int count;
3237 int sum;
3238
3239 if (content == NULL)
3240 return -1;
3241
3242 sum = 0;
3243 count = xmlTextWriterStartDTDElement(writer, name);
3244 if (count == -1)
3245 return -1;
3246 sum += count;
3247
Daniel Veillard1d211e22003-10-20 22:32:39 +00003248 count = xmlTextWriterWriteString(writer, content);
3249 if (count == -1)
3250 return -1;
3251 sum += count;
3252
3253 count = xmlTextWriterEndDTDElement(writer);
3254 if (count == -1)
3255 return -1;
3256 sum += count;
3257
3258 return sum;
3259}
3260
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003261/**
3262 * xmlTextWriterStartDTDAttlist:
3263 * @writer: the xmlTextWriterPtr
3264 * @name: the name of the DTD ATTLIST
3265 *
3266 * Start an xml DTD ATTLIST.
3267 *
3268 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3269 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003270int
3271xmlTextWriterStartDTDAttlist(xmlTextWriterPtr writer, const xmlChar * name)
3272{
3273 int count;
3274 int sum;
3275 xmlLinkPtr lk;
3276 xmlTextWriterStackEntry *p;
3277
3278 if (writer == NULL || name == NULL || *name == '\0')
3279 return -1;
3280
3281 sum = 0;
3282 lk = xmlListFront(writer->nodes);
3283 if (lk == 0) {
3284 return -1;
3285 }
3286
3287 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
Daniel Veillard500a1de2004-03-22 15:22:58 +00003288 if (p != 0) {
3289 switch (p->state) {
3290 case XML_TEXTWRITER_DTD:
3291 count = xmlOutputBufferWriteString(writer->out, " [");
3292 if (count < 0)
3293 return -1;
3294 sum += count;
3295 if (writer->indent) {
3296 count = xmlOutputBufferWriteString(writer->out, "\n");
3297 if (count < 0)
3298 return -1;
3299 sum += count;
3300 }
3301 p->state = XML_TEXTWRITER_DTD_TEXT;
3302 /* fallthrough */
3303 case XML_TEXTWRITER_DTD_TEXT:
3304 case XML_TEXTWRITER_NONE:
3305 break;
3306 default:
Daniel Veillard1d211e22003-10-20 22:32:39 +00003307 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00003308 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00003309 }
3310
3311 p = (xmlTextWriterStackEntry *)
3312 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3313 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003314 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003315 "xmlTextWriterStartDTDAttlist : out of memory!\n");
3316 return -1;
3317 }
3318
3319 p->name = xmlStrdup(name);
3320 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003321 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003322 "xmlTextWriterStartDTDAttlist : out of memory!\n");
3323 xmlFree(p);
3324 return -1;
3325 }
3326 p->state = XML_TEXTWRITER_DTD_ATTL;
3327
3328 xmlListPushFront(writer->nodes, p);
3329
Daniel Veillard500a1de2004-03-22 15:22:58 +00003330 if (writer->indent) {
3331 count = xmlTextWriterWriteIndent(writer);
3332 if (count < 0)
3333 return -1;
3334 sum += count;
3335 }
3336
Daniel Veillard1d211e22003-10-20 22:32:39 +00003337 count = xmlOutputBufferWriteString(writer->out, "<!ATTLIST ");
3338 if (count < 0)
3339 return -1;
3340 sum += count;
Daniel Veillardab69f362004-02-17 11:40:32 +00003341 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003342 if (count < 0)
3343 return -1;
3344 sum += count;
3345
3346 return sum;
3347}
3348
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003349/**
Daniel Veillard500a1de2004-03-22 15:22:58 +00003350 * xmlTextWriterEndDTDAttlist:
3351 * @writer: the xmlTextWriterPtr
3352 *
3353 * End an xml DTD attribute list.
3354 *
3355 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3356 */
3357int
3358xmlTextWriterEndDTDAttlist(xmlTextWriterPtr writer)
3359{
3360 int count;
3361 int sum;
3362 xmlLinkPtr lk;
3363 xmlTextWriterStackEntry *p;
3364
3365 if (writer == NULL)
3366 return -1;
3367
3368 sum = 0;
3369 lk = xmlListFront(writer->nodes);
3370 if (lk == 0)
3371 return -1;
3372
3373 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3374 if (p == 0)
3375 return -1;
3376
3377 switch (p->state) {
3378 case XML_TEXTWRITER_DTD_ATTL:
3379 case XML_TEXTWRITER_DTD_ATTL_TEXT:
3380 count = xmlOutputBufferWriteString(writer->out, ">");
3381 if (count < 0)
3382 return -1;
3383 sum += count;
3384 break;
3385 default:
3386 return -1;
3387 }
3388
3389 if (writer->indent) {
3390 count = xmlOutputBufferWriteString(writer->out, "\n");
3391 if (count < 0)
3392 return -1;
3393 sum += count;
3394 }
3395
3396 xmlListPopFront(writer->nodes);
3397 return sum;
3398}
3399
3400/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003401 * xmlTextWriterWriteFormatDTDAttlist:
3402 * @writer: the xmlTextWriterPtr
3403 * @name: the name of the DTD ATTLIST
3404 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003405 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003406 *
3407 * Write a formatted DTD ATTLIST.
3408 *
3409 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3410 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003411int
3412xmlTextWriterWriteFormatDTDAttlist(xmlTextWriterPtr writer,
3413 const xmlChar * name,
3414 const char *format, ...)
3415{
3416 int rc;
3417 va_list ap;
3418
3419 va_start(ap, format);
3420
3421 rc = xmlTextWriterWriteVFormatDTDAttlist(writer, name, format, ap);
3422
3423 va_end(ap);
3424 return rc;
3425}
3426
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003427/**
3428 * xmlTextWriterWriteVFormatDTDAttlist:
3429 * @writer: the xmlTextWriterPtr
3430 * @name: the name of the DTD ATTLIST
3431 * @format: format string (see printf)
3432 * @argptr: pointer to the first member of the variable argument list.
3433 *
3434 * Write a formatted DTD ATTLIST.
3435 *
3436 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3437 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003438int
3439xmlTextWriterWriteVFormatDTDAttlist(xmlTextWriterPtr writer,
3440 const xmlChar * name,
3441 const char *format, va_list argptr)
3442{
3443 int rc;
3444 xmlChar *buf;
3445
3446 if (writer == NULL)
3447 return -1;
3448
3449 buf = xmlTextWriterVSprintf(format, argptr);
3450 if (buf == 0)
3451 return 0;
3452
3453 rc = xmlTextWriterWriteDTDAttlist(writer, name, buf);
3454
3455 xmlFree(buf);
3456 return rc;
3457}
3458
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003459/**
3460 * xmlTextWriterWriteDTDAttlist:
3461 * @writer: the xmlTextWriterPtr
3462 * @name: the name of the DTD ATTLIST
3463 * @content: content of the ATTLIST
3464 *
3465 * Write a DTD ATTLIST.
3466 *
3467 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3468 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003469int
3470xmlTextWriterWriteDTDAttlist(xmlTextWriterPtr writer,
3471 const xmlChar * name, const xmlChar * content)
3472{
3473 int count;
3474 int sum;
3475
3476 if (content == NULL)
3477 return -1;
3478
3479 sum = 0;
3480 count = xmlTextWriterStartDTDAttlist(writer, name);
3481 if (count == -1)
3482 return -1;
3483 sum += count;
3484
Daniel Veillard1d211e22003-10-20 22:32:39 +00003485 count = xmlTextWriterWriteString(writer, content);
3486 if (count == -1)
3487 return -1;
3488 sum += count;
3489
3490 count = xmlTextWriterEndDTDAttlist(writer);
3491 if (count == -1)
3492 return -1;
3493 sum += count;
3494
3495 return sum;
3496}
3497
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003498/**
3499 * xmlTextWriterStartDTDEntity:
3500 * @writer: the xmlTextWriterPtr
3501 * @pe: TRUE if this is a parameter entity, FALSE if not
3502 * @name: the name of the DTD ATTLIST
3503 *
3504 * Start an xml DTD ATTLIST.
3505 *
3506 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3507 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003508int
3509xmlTextWriterStartDTDEntity(xmlTextWriterPtr writer,
3510 int pe, const xmlChar * name)
3511{
3512 int count;
3513 int sum;
3514 xmlLinkPtr lk;
3515 xmlTextWriterStackEntry *p;
3516
3517 if (writer == NULL || name == NULL || *name == '\0')
3518 return -1;
3519
3520 sum = 0;
3521 lk = xmlListFront(writer->nodes);
Daniel Veillard500a1de2004-03-22 15:22:58 +00003522 if (lk != 0) {
Daniel Veillard1d211e22003-10-20 22:32:39 +00003523
Daniel Veillard500a1de2004-03-22 15:22:58 +00003524 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3525 if (p != 0) {
3526 switch (p->state) {
3527 case XML_TEXTWRITER_DTD:
3528 count = xmlOutputBufferWriteString(writer->out, " [");
3529 if (count < 0)
3530 return -1;
3531 sum += count;
3532 if (writer->indent) {
3533 count =
3534 xmlOutputBufferWriteString(writer->out, "\n");
3535 if (count < 0)
3536 return -1;
3537 sum += count;
3538 }
3539 p->state = XML_TEXTWRITER_DTD_TEXT;
3540 /* fallthrough */
3541 case XML_TEXTWRITER_DTD_TEXT:
3542 case XML_TEXTWRITER_NONE:
3543 break;
3544 default:
3545 return -1;
3546 }
3547 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00003548 }
3549
3550 p = (xmlTextWriterStackEntry *)
3551 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3552 if (p == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003553 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003554 "xmlTextWriterStartDTDElement : out of memory!\n");
3555 return -1;
3556 }
3557
3558 p->name = xmlStrdup(name);
3559 if (p->name == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003560 xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00003561 "xmlTextWriterStartDTDElement : out of memory!\n");
3562 xmlFree(p);
3563 return -1;
3564 }
Daniel Veillard500a1de2004-03-22 15:22:58 +00003565
3566 if (pe != 0)
3567 p->state = XML_TEXTWRITER_DTD_PENT;
3568 else
3569 p->state = XML_TEXTWRITER_DTD_ENTY;
Daniel Veillard1d211e22003-10-20 22:32:39 +00003570
3571 xmlListPushFront(writer->nodes, p);
3572
Daniel Veillard500a1de2004-03-22 15:22:58 +00003573 if (writer->indent) {
3574 count = xmlTextWriterWriteIndent(writer);
3575 if (count < 0)
3576 return -1;
3577 sum += count;
3578 }
3579
Daniel Veillard1d211e22003-10-20 22:32:39 +00003580 count = xmlOutputBufferWriteString(writer->out, "<!ENTITY ");
3581 if (count < 0)
3582 return -1;
3583 sum += count;
3584
3585 if (pe != 0) {
Daniel Veillard500a1de2004-03-22 15:22:58 +00003586 count = xmlOutputBufferWriteString(writer->out, "% ");
Daniel Veillard1d211e22003-10-20 22:32:39 +00003587 if (count < 0)
3588 return -1;
3589 sum += count;
3590 }
3591
Daniel Veillardab69f362004-02-17 11:40:32 +00003592 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003593 if (count < 0)
3594 return -1;
3595 sum += count;
3596
3597 return sum;
3598}
3599
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003600/**
Daniel Veillard500a1de2004-03-22 15:22:58 +00003601 * xmlTextWriterEndDTDEntity:
3602 * @writer: the xmlTextWriterPtr
3603 *
3604 * End an xml DTD entity.
3605 *
3606 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3607 */
3608int
3609xmlTextWriterEndDTDEntity(xmlTextWriterPtr writer)
3610{
3611 int count;
3612 int sum;
3613 xmlLinkPtr lk;
3614 xmlTextWriterStackEntry *p;
3615
3616 if (writer == NULL)
3617 return -1;
3618
3619 sum = 0;
3620 lk = xmlListFront(writer->nodes);
3621 if (lk == 0)
3622 return -1;
3623
3624 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3625 if (p == 0)
3626 return -1;
3627
3628 switch (p->state) {
3629 case XML_TEXTWRITER_DTD_ENTY_TEXT:
3630 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3631 if (count < 0)
3632 return -1;
3633 sum += count;
3634 case XML_TEXTWRITER_DTD_ENTY:
3635 case XML_TEXTWRITER_DTD_PENT:
Daniel Veillard500a1de2004-03-22 15:22:58 +00003636 count = xmlOutputBufferWriteString(writer->out, ">");
3637 if (count < 0)
3638 return -1;
3639 sum += count;
3640 break;
3641 default:
3642 return -1;
3643 }
3644
3645 if (writer->indent) {
3646 count = xmlOutputBufferWriteString(writer->out, "\n");
3647 if (count < 0)
3648 return -1;
3649 sum += count;
3650 }
3651
3652 xmlListPopFront(writer->nodes);
3653 return sum;
3654}
3655
3656/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003657 * xmlTextWriterWriteFormatDTDInternalEntity:
3658 * @writer: the xmlTextWriterPtr
3659 * @pe: TRUE if this is a parameter entity, FALSE if not
3660 * @name: the name of the DTD entity
3661 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003662 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003663 *
3664 * Write a formatted DTD internal entity.
3665 *
3666 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3667 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003668int
3669xmlTextWriterWriteFormatDTDInternalEntity(xmlTextWriterPtr writer,
3670 int pe,
3671 const xmlChar * name,
3672 const char *format, ...)
3673{
3674 int rc;
3675 va_list ap;
3676
3677 va_start(ap, format);
3678
3679 rc = xmlTextWriterWriteVFormatDTDInternalEntity(writer, pe, name,
3680 format, ap);
3681
3682 va_end(ap);
3683 return rc;
3684}
3685
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003686/**
3687 * xmlTextWriterWriteVFormatDTDInternalEntity:
3688 * @writer: the xmlTextWriterPtr
3689 * @pe: TRUE if this is a parameter entity, FALSE if not
3690 * @name: the name of the DTD entity
3691 * @format: format string (see printf)
3692 * @argptr: pointer to the first member of the variable argument list.
3693 *
3694 * Write a formatted DTD internal entity.
3695 *
3696 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3697 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003698int
3699xmlTextWriterWriteVFormatDTDInternalEntity(xmlTextWriterPtr writer,
3700 int pe,
3701 const xmlChar * name,
3702 const char *format,
3703 va_list argptr)
3704{
3705 int rc;
3706 xmlChar *buf;
3707
3708 if (writer == NULL)
3709 return -1;
3710
3711 buf = xmlTextWriterVSprintf(format, argptr);
3712 if (buf == 0)
3713 return 0;
3714
3715 rc = xmlTextWriterWriteDTDInternalEntity(writer, pe, name, buf);
3716
3717 xmlFree(buf);
3718 return rc;
3719}
3720
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003721/**
3722 * xmlTextWriterWriteDTDEntity:
3723 * @writer: the xmlTextWriterPtr
3724 * @pe: TRUE if this is a parameter entity, FALSE if not
3725 * @name: the name of the DTD entity
3726 * @pubid: the public identifier, which is an alternative to the system identifier
3727 * @sysid: the system identifier, which is the URI of the DTD
3728 * @ndataid: the xml notation name.
3729 * @content: content of the entity
3730 *
3731 * Write a DTD entity.
3732 *
3733 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3734 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003735int
3736xmlTextWriterWriteDTDEntity(xmlTextWriterPtr writer,
3737 int pe,
3738 const xmlChar * name,
3739 const xmlChar * pubid,
3740 const xmlChar * sysid,
3741 const xmlChar * ndataid,
3742 const xmlChar * content)
3743{
Daniel Veillard500a1de2004-03-22 15:22:58 +00003744 if ((content == NULL) && (pubid == NULL) && (sysid == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00003745 return -1;
3746 if ((pe != 0) && (ndataid != NULL))
3747 return -1;
3748
Daniel Veillard500a1de2004-03-22 15:22:58 +00003749 if ((pubid == NULL) && (sysid == NULL))
Daniel Veillard1d211e22003-10-20 22:32:39 +00003750 return xmlTextWriterWriteDTDInternalEntity(writer, pe, name,
3751 content);
3752
3753 return xmlTextWriterWriteDTDExternalEntity(writer, pe, name, pubid,
3754 sysid, ndataid);
3755}
3756
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003757/**
3758 * xmlTextWriterWriteDTDInternalEntity:
3759 * @writer: the xmlTextWriterPtr
3760 * @pe: TRUE if this is a parameter entity, FALSE if not
3761 * @name: the name of the DTD entity
3762 * @content: content of the entity
3763 *
3764 * Write a DTD internal entity.
3765 *
3766 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3767 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003768int
3769xmlTextWriterWriteDTDInternalEntity(xmlTextWriterPtr writer,
3770 int pe,
3771 const xmlChar * name,
3772 const xmlChar * content)
3773{
3774 int count;
3775 int sum;
3776
3777 if ((name == NULL) || (*name == '\0') || (content == NULL))
3778 return -1;
3779
3780 sum = 0;
3781 count = xmlTextWriterStartDTDEntity(writer, pe, name);
3782 if (count == -1)
3783 return -1;
3784 sum += count;
3785
Daniel Veillard1d211e22003-10-20 22:32:39 +00003786 count = xmlTextWriterWriteString(writer, content);
3787 if (count == -1)
3788 return -1;
3789 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00003790
3791 count = xmlTextWriterEndDTDEntity(writer);
3792 if (count == -1)
3793 return -1;
3794 sum += count;
3795
3796 return sum;
3797}
3798
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003799/**
3800 * xmlTextWriterWriteDTDExternalEntity:
3801 * @writer: the xmlTextWriterPtr
3802 * @pe: TRUE if this is a parameter entity, FALSE if not
3803 * @name: the name of the DTD entity
3804 * @pubid: the public identifier, which is an alternative to the system identifier
3805 * @sysid: the system identifier, which is the URI of the DTD
3806 * @ndataid: the xml notation name.
3807 *
Daniel Veillard500a1de2004-03-22 15:22:58 +00003808 * Write a DTD external entity. The entity must have been started with xmlTextWriterStartDTDEntity
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003809 *
3810 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3811 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003812int
3813xmlTextWriterWriteDTDExternalEntity(xmlTextWriterPtr writer,
3814 int pe,
3815 const xmlChar * name,
3816 const xmlChar * pubid,
3817 const xmlChar * sysid,
3818 const xmlChar * ndataid)
3819{
3820 int count;
3821 int sum;
3822
Daniel Veillard500a1de2004-03-22 15:22:58 +00003823 if (((pubid == NULL) && (sysid == NULL)))
Daniel Veillard1d211e22003-10-20 22:32:39 +00003824 return -1;
3825 if ((pe != 0) && (ndataid != NULL))
3826 return -1;
3827
3828 sum = 0;
3829 count = xmlTextWriterStartDTDEntity(writer, pe, name);
3830 if (count == -1)
3831 return -1;
3832 sum += count;
3833
Daniel Veillard500a1de2004-03-22 15:22:58 +00003834 count =
3835 xmlTextWriterWriteDTDExternalEntityContents(writer, pubid, sysid,
3836 ndataid);
3837 if (count < 0)
3838 return -1;
3839 sum += count;
3840
3841 count = xmlTextWriterEndDTDEntity(writer);
3842 if (count == -1)
3843 return -1;
3844 sum += count;
3845
3846 return sum;
3847}
3848
3849/**
3850 * xmlTextWriterWriteDTDExternalEntityContents:
3851 * @writer: the xmlTextWriterPtr
3852 * @pubid: the public identifier, which is an alternative to the system identifier
3853 * @sysid: the system identifier, which is the URI of the DTD
3854 * @ndataid: the xml notation name.
3855 *
3856 * Write the contents of a DTD external entity.
3857 *
3858 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3859 */
3860int
3861xmlTextWriterWriteDTDExternalEntityContents(xmlTextWriterPtr writer,
3862 const xmlChar * pubid,
3863 const xmlChar * sysid,
3864 const xmlChar * ndataid)
3865{
3866 int count;
3867 int sum;
3868 xmlLinkPtr lk;
3869 xmlTextWriterStackEntry *p;
3870
3871 if (writer == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003872 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003873 "xmlTextWriterWriteDTDExternalEntityContents: xmlTextWriterPtr invalid!\n");
3874 return -1;
3875 }
3876
3877 sum = 0;
3878 lk = xmlListFront(writer->nodes);
3879 if (lk == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003880 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003881 "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n");
3882 return -1;
3883 }
3884
3885 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3886 if (p == 0)
3887 return -1;
3888
3889 switch (p->state) {
3890 case XML_TEXTWRITER_DTD_ENTY:
3891 break;
3892 case XML_TEXTWRITER_DTD_PENT:
3893 if (ndataid != NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003894 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003895 "xmlTextWriterWriteDTDExternalEntityContents: notation not allowed with parameter entities!\n");
3896 return -1;
3897 }
3898 break;
3899 default:
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003900 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003901 "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n");
3902 return -1;
3903 }
3904
Daniel Veillard1d211e22003-10-20 22:32:39 +00003905 if (pubid != 0) {
3906 if (sysid == 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00003907 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard500a1de2004-03-22 15:22:58 +00003908 "xmlTextWriterWriteDTDExternalEntityContents: system identifier needed!\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +00003909 return -1;
3910 }
3911
3912 count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
3913 if (count < 0)
3914 return -1;
3915 sum += count;
3916
3917 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3918 if (count < 0)
3919 return -1;
3920 sum += count;
3921
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003922 count =
3923 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003924 if (count < 0)
3925 return -1;
3926 sum += count;
3927
3928 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3929 if (count < 0)
3930 return -1;
3931 sum += count;
3932 }
3933
3934 if (sysid != 0) {
3935 if (pubid == 0) {
3936 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
3937 if (count < 0)
3938 return -1;
3939 sum += count;
3940 }
3941
3942 count = xmlOutputBufferWriteString(writer->out, " ");
3943 if (count < 0)
3944 return -1;
3945 sum += count;
3946
3947 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3948 if (count < 0)
3949 return -1;
3950 sum += count;
3951
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003952 count =
3953 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003954 if (count < 0)
3955 return -1;
3956 sum += count;
3957
3958 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3959 if (count < 0)
3960 return -1;
3961 sum += count;
3962 }
3963
3964 if (ndataid != NULL) {
3965 count = xmlOutputBufferWriteString(writer->out, " NDATA ");
3966 if (count < 0)
3967 return -1;
3968 sum += count;
3969
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003970 count =
3971 xmlOutputBufferWriteString(writer->out,
3972 (const char *) ndataid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003973 if (count < 0)
3974 return -1;
3975 sum += count;
3976 }
3977
Daniel Veillard1d211e22003-10-20 22:32:39 +00003978 return sum;
3979}
3980
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003981/**
3982 * xmlTextWriterWriteDTDNotation:
3983 * @writer: the xmlTextWriterPtr
3984 * @name: the name of the xml notation
3985 * @pubid: the public identifier, which is an alternative to the system identifier
3986 * @sysid: the system identifier, which is the URI of the DTD
3987 *
3988 * Write a DTD entity.
3989 *
3990 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3991 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003992int
3993xmlTextWriterWriteDTDNotation(xmlTextWriterPtr writer,
3994 const xmlChar * name,
3995 const xmlChar * pubid, const xmlChar * sysid)
3996{
3997 int count;
3998 int sum;
3999 xmlLinkPtr lk;
4000 xmlTextWriterStackEntry *p;
4001
4002 if (writer == NULL || name == NULL || *name == '\0')
4003 return -1;
4004
4005 sum = 0;
4006 lk = xmlListFront(writer->nodes);
4007 if (lk == 0) {
4008 return -1;
4009 }
4010
4011 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
Daniel Veillard500a1de2004-03-22 15:22:58 +00004012 if (p != 0) {
4013 switch (p->state) {
4014 case XML_TEXTWRITER_DTD:
4015 count = xmlOutputBufferWriteString(writer->out, " [");
4016 if (count < 0)
4017 return -1;
4018 sum += count;
4019 if (writer->indent) {
4020 count = xmlOutputBufferWriteString(writer->out, "\n");
4021 if (count < 0)
4022 return -1;
4023 sum += count;
4024 }
4025 p->state = XML_TEXTWRITER_DTD_TEXT;
4026 /* fallthrough */
4027 case XML_TEXTWRITER_DTD_TEXT:
4028 break;
4029 default:
4030 return -1;
4031 }
4032 }
Daniel Veillard1d211e22003-10-20 22:32:39 +00004033
Daniel Veillard500a1de2004-03-22 15:22:58 +00004034 if (writer->indent) {
4035 count = xmlTextWriterWriteIndent(writer);
4036 if (count < 0)
Daniel Veillard1d211e22003-10-20 22:32:39 +00004037 return -1;
Daniel Veillard500a1de2004-03-22 15:22:58 +00004038 sum += count;
Daniel Veillard1d211e22003-10-20 22:32:39 +00004039 }
4040
4041 count = xmlOutputBufferWriteString(writer->out, "<!NOTATION ");
4042 if (count < 0)
4043 return -1;
4044 sum += count;
4045 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
4046 if (count < 0)
4047 return -1;
4048 sum += count;
4049
4050 if (pubid != 0) {
4051 count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
4052 if (count < 0)
4053 return -1;
4054 sum += count;
4055 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4056 if (count < 0)
4057 return -1;
4058 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004059 count =
4060 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004061 if (count < 0)
4062 return -1;
4063 sum += count;
4064 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4065 if (count < 0)
4066 return -1;
4067 sum += count;
4068 }
4069
4070 if (sysid != 0) {
4071 if (pubid == 0) {
4072 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
4073 if (count < 0)
4074 return -1;
4075 sum += count;
4076 }
4077 count = xmlOutputBufferWriteString(writer->out, " ");
4078 if (count < 0)
4079 return -1;
4080 sum += count;
4081 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4082 if (count < 0)
4083 return -1;
4084 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004085 count =
4086 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00004087 if (count < 0)
4088 return -1;
4089 sum += count;
4090 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4091 if (count < 0)
4092 return -1;
4093 sum += count;
4094 }
4095
4096 count = xmlOutputBufferWriteString(writer->out, ">");
4097 if (count < 0)
4098 return -1;
4099 sum += count;
4100
4101 return sum;
4102}
4103
4104/**
4105 * xmlTextWriterFlush:
4106 * @writer: the xmlTextWriterPtr
4107 *
4108 * Flush the output buffer.
4109 *
4110 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
4111 */
4112int
4113xmlTextWriterFlush(xmlTextWriterPtr writer)
4114{
4115 int count;
4116
4117 if (writer == NULL)
4118 return -1;
4119
4120 if (writer->out == NULL)
4121 count = 0;
4122 else
4123 count = xmlOutputBufferFlush(writer->out);
4124
4125 return count;
4126}
4127
4128/**
4129 * misc
4130 */
4131
4132/**
4133 * xmlFreeTextWriterStackEntry:
4134 * @lk: the xmlLinkPtr
4135 *
4136 * Free callback for the xmlList.
4137 */
4138static void
4139xmlFreeTextWriterStackEntry(xmlLinkPtr lk)
4140{
4141 xmlTextWriterStackEntry *p;
4142
4143 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
4144 if (p == 0)
4145 return;
4146
4147 if (p->name != 0)
4148 xmlFree(p->name);
4149 xmlFree(p);
4150}
4151
4152/**
4153 * xmlCmpTextWriterStackEntry:
4154 * @data0: the first data
4155 * @data1: the second data
4156 *
4157 * Compare callback for the xmlList.
4158 *
4159 * Returns -1, 0, 1
4160 */
4161static int
4162xmlCmpTextWriterStackEntry(const void *data0, const void *data1)
4163{
4164 xmlTextWriterStackEntry *p0;
4165 xmlTextWriterStackEntry *p1;
4166
4167 if (data0 == data1)
4168 return 0;
4169
4170 if (data0 == 0)
4171 return -1;
4172
4173 if (data1 == 0)
4174 return 1;
4175
4176 p0 = (xmlTextWriterStackEntry *) data0;
4177 p1 = (xmlTextWriterStackEntry *) data1;
4178
4179 return xmlStrcmp(p0->name, p1->name);
4180}
4181
4182/**
4183 * misc
4184 */
4185
4186/**
4187 * xmlFreeTextWriterNsStackEntry:
4188 * @lk: the xmlLinkPtr
4189 *
4190 * Free callback for the xmlList.
4191 */
4192static void
4193xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk)
4194{
4195 xmlTextWriterNsStackEntry *p;
4196
4197 p = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
4198 if (p == 0)
4199 return;
4200
4201 if (p->prefix != 0)
4202 xmlFree(p->prefix);
4203 if (p->uri != 0)
4204 xmlFree(p->uri);
4205
4206 xmlFree(p);
4207}
4208
4209/**
4210 * xmlCmpTextWriterNsStackEntry:
4211 * @data0: the first data
4212 * @data1: the second data
4213 *
4214 * Compare callback for the xmlList.
4215 *
4216 * Returns -1, 0, 1
4217 */
4218static int
4219xmlCmpTextWriterNsStackEntry(const void *data0, const void *data1)
4220{
4221 xmlTextWriterNsStackEntry *p0;
4222 xmlTextWriterNsStackEntry *p1;
4223 int rc;
4224
4225 if (data0 == data1)
4226 return 0;
4227
4228 if (data0 == 0)
4229 return -1;
4230
4231 if (data1 == 0)
4232 return 1;
4233
4234 p0 = (xmlTextWriterNsStackEntry *) data0;
4235 p1 = (xmlTextWriterNsStackEntry *) data1;
4236
4237 rc = xmlStrcmp(p0->prefix, p1->prefix);
4238
4239 if (rc == 0)
4240 rc = p0->elem == p1->elem;
4241
4242 return rc;
4243}
4244
4245/**
4246 * xmlTextWriterWriteMemCallback:
4247 * @context: the xmlBufferPtr
4248 * @str: the data to write
4249 * @len: the length of the data
4250 *
4251 * Write callback for the xmlOutputBuffer with target xmlBuffer
4252 *
4253 * Returns -1, 0, 1
4254 */
4255static int
4256xmlTextWriterWriteMemCallback(void *context, const xmlChar * str, int len)
4257{
4258 xmlBufferPtr buf = (xmlBufferPtr) context;
4259
4260 xmlBufferAdd(buf, str, len);
4261
4262 return len;
4263}
4264
4265/**
4266 * xmlTextWriterCloseMemCallback:
4267 * @context: the xmlBufferPtr
4268 *
4269 * Close callback for the xmlOutputBuffer with target xmlBuffer
4270 *
4271 * Returns -1, 0, 1
4272 */
4273static int
4274xmlTextWriterCloseMemCallback(void *context ATTRIBUTE_UNUSED)
4275{
4276 return 0;
4277}
4278
4279/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004280 * xmlTextWriterWriteDocCallback:
4281 * @context: the xmlBufferPtr
4282 * @str: the data to write
4283 * @len: the length of the data
4284 *
4285 * Write callback for the xmlOutputBuffer with target xmlBuffer
4286 *
4287 * Returns -1, 0, 1
4288 */
4289static int
4290xmlTextWriterWriteDocCallback(void *context, const xmlChar * str, int len)
4291{
4292 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context;
4293 int rc;
4294
Daniel Veillard1d913862003-11-21 00:28:39 +00004295 if ((rc = xmlParseChunk(ctxt, (const char *) str, len, 0)) != 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004296 xmlWriterErrMsgInt(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004297 "xmlTextWriterWriteDocCallback : XML error %d !\n",
4298 rc);
4299 return -1;
4300 }
4301
4302 return len;
4303}
4304
4305/**
4306 * xmlTextWriterCloseDocCallback:
4307 * @context: the xmlBufferPtr
4308 *
4309 * Close callback for the xmlOutputBuffer with target xmlBuffer
4310 *
4311 * Returns -1, 0, 1
4312 */
4313static int
4314xmlTextWriterCloseDocCallback(void *context)
4315{
4316 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context;
4317 int rc;
4318
4319 if ((rc = xmlParseChunk(ctxt, NULL, 0, 1)) != 0) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004320 xmlWriterErrMsgInt(NULL, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004321 "xmlTextWriterWriteDocCallback : XML error %d !\n",
4322 rc);
4323 return -1;
4324 }
4325
4326 return 0;
4327}
4328
4329/**
Daniel Veillard1d211e22003-10-20 22:32:39 +00004330 * xmlTextWriterVSprintf:
4331 * @format: see printf
4332 * @argptr: pointer to the first member of the variable argument list.
4333 *
4334 * Utility function for formatted output
4335 *
4336 * Returns a new xmlChar buffer with the data or NULL on error. This buffer must be freed.
4337 */
4338static xmlChar *
4339xmlTextWriterVSprintf(const char *format, va_list argptr)
4340{
4341 int size;
4342 int count;
4343 xmlChar *buf;
4344
4345 size = BUFSIZ;
4346 buf = (xmlChar *) xmlMalloc(size);
4347 if (buf == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004348 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00004349 "xmlTextWriterVSprintf : out of memory!\n");
4350 return NULL;
4351 }
4352
4353 while (((count = vsnprintf((char *) buf, size, format, argptr)) < 0)
4354 || (count == size - 1) || (count == size) || (count > size)) {
4355 xmlFree(buf);
4356 size += BUFSIZ;
4357 buf = (xmlChar *) xmlMalloc(size);
4358 if (buf == NULL) {
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004359 xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
Daniel Veillard1d211e22003-10-20 22:32:39 +00004360 "xmlTextWriterVSprintf : out of memory!\n");
4361 return NULL;
4362 }
4363 }
4364
4365 return buf;
4366}
4367
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004368/**
4369 * xmlTextWriterStartDocumentCallback:
4370 * @ctx: the user data (XML parser context)
4371 *
4372 * called at the start of document processing.
4373 */
4374static void
4375xmlTextWriterStartDocumentCallback(void *ctx)
4376{
4377 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
4378 xmlDocPtr doc;
4379
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004380 if (ctxt->html) {
4381#ifdef LIBXML_HTML_ENABLED
4382 if (ctxt->myDoc == NULL)
4383 ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
4384 if (ctxt->myDoc == NULL) {
4385 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
4386 ctxt->sax->error(ctxt->userData,
4387 "SAX.startDocument(): out of memory\n");
4388 ctxt->errNo = XML_ERR_NO_MEMORY;
4389 ctxt->instate = XML_PARSER_EOF;
4390 ctxt->disableSAX = 1;
4391 return;
4392 }
4393#else
Daniel Veillarddd6d3002004-11-03 14:20:29 +00004394 xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
Daniel Veillard5841f0e2003-11-20 11:59:09 +00004395 "libxml2 built without HTML support\n");
4396 ctxt->errNo = XML_ERR_INTERNAL_ERROR;
4397 ctxt->instate = XML_PARSER_EOF;
4398 ctxt->disableSAX = 1;
4399 return;
4400#endif
4401 } else {
4402 doc = ctxt->myDoc;
4403 if (doc == NULL)
4404 doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
4405 if (doc != NULL) {
4406 if (doc->children == NULL) {
4407 if (ctxt->encoding != NULL)
4408 doc->encoding = xmlStrdup(ctxt->encoding);
4409 else
4410 doc->encoding = NULL;
4411 doc->standalone = ctxt->standalone;
4412 }
4413 } else {
4414 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
4415 ctxt->sax->error(ctxt->userData,
4416 "SAX.startDocument(): out of memory\n");
4417 ctxt->errNo = XML_ERR_NO_MEMORY;
4418 ctxt->instate = XML_PARSER_EOF;
4419 ctxt->disableSAX = 1;
4420 return;
4421 }
4422 }
4423 if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) &&
4424 (ctxt->input != NULL) && (ctxt->input->filename != NULL)) {
4425 ctxt->myDoc->URL =
4426 xmlCanonicPath((const xmlChar *) ctxt->input->filename);
4427 if (ctxt->myDoc->URL == NULL)
4428 ctxt->myDoc->URL =
4429 xmlStrdup((const xmlChar *) ctxt->input->filename);
4430 }
4431}
4432
Daniel Veillard2cca4462004-01-02 20:04:23 +00004433/**
4434 * xmlTextWriterSetIndent:
4435 * @writer: the xmlTextWriterPtr
4436 * @indent: do indentation?
4437 *
4438 * Set indentation output. indent = 0 do not indentation. indent > 0 do indentation.
4439 *
4440 * Returns -1 on error or 0 otherwise.
4441 */
4442int
Daniel Veillardab69f362004-02-17 11:40:32 +00004443xmlTextWriterSetIndent(xmlTextWriterPtr writer, int indent)
Daniel Veillard2cca4462004-01-02 20:04:23 +00004444{
Daniel Veillarde43cc572004-11-03 11:50:29 +00004445 if ((writer == NULL) || (indent < 0))
Daniel Veillardab69f362004-02-17 11:40:32 +00004446 return -1;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004447
Daniel Veillardab69f362004-02-17 11:40:32 +00004448 writer->indent = indent;
4449 writer->doindent = 1;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004450
Daniel Veillardab69f362004-02-17 11:40:32 +00004451 return 0;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004452}
4453
4454/**
4455 * xmlTextWriterSetIndentString:
4456 * @writer: the xmlTextWriterPtr
4457 * @str: the xmlChar string
4458 *
4459 * Set string indentation.
4460 *
4461 * Returns -1 on error or 0 otherwise.
4462 */
4463int
Daniel Veillardab69f362004-02-17 11:40:32 +00004464xmlTextWriterSetIndentString(xmlTextWriterPtr writer, const xmlChar * str)
Daniel Veillard2cca4462004-01-02 20:04:23 +00004465{
Daniel Veillarde43cc572004-11-03 11:50:29 +00004466 if ((writer == NULL) || (!str))
Daniel Veillardab69f362004-02-17 11:40:32 +00004467 return -1;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004468
Daniel Veillardab69f362004-02-17 11:40:32 +00004469 if (writer->ichar != NULL)
4470 xmlFree(writer->ichar);
4471 writer->ichar = xmlStrdup(str);
4472
4473 if (!writer->ichar)
4474 return -1;
4475 else
4476 return 0;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004477}
4478
4479/**
4480 * xmlTextWriterWriteIndent:
4481 * @writer: the xmlTextWriterPtr
4482 *
4483 * Write indent string.
4484 *
4485 * Returns -1 on error or the number of strings written.
Daniel Veillardab69f362004-02-17 11:40:32 +00004486 */
Daniel Veillard2cca4462004-01-02 20:04:23 +00004487static int
Daniel Veillardab69f362004-02-17 11:40:32 +00004488xmlTextWriterWriteIndent(xmlTextWriterPtr writer)
Daniel Veillard2cca4462004-01-02 20:04:23 +00004489{
Daniel Veillardab69f362004-02-17 11:40:32 +00004490 int lksize;
4491 int i;
4492 int ret;
Daniel Veillard2cca4462004-01-02 20:04:23 +00004493
Daniel Veillardab69f362004-02-17 11:40:32 +00004494 lksize = xmlListSize(writer->nodes);
4495 if (lksize < 1)
4496 return (-1); /* list is empty */
4497 for (i = 0; i < (lksize - 1); i++) {
4498 ret = xmlOutputBufferWriteString(writer->out,
4499 (const char *) writer->ichar);
4500 if (ret == -1)
4501 return (-1);
4502 }
4503
4504 return (lksize - 1);
Daniel Veillard2cca4462004-01-02 20:04:23 +00004505}
4506
Daniel Veillard500a1de2004-03-22 15:22:58 +00004507/**
4508 * xmlTextWriterHandleStateDependencies:
4509 * @writer: the xmlTextWriterPtr
4510 * @p: the xmlTextWriterStackEntry
4511 *
4512 * Write state dependent strings.
4513 *
4514 * Returns -1 on error or the number of characters written.
4515 */
4516static int
4517xmlTextWriterHandleStateDependencies(xmlTextWriterPtr writer,
4518 xmlTextWriterStackEntry * p)
4519{
4520 int count;
4521 int sum;
4522 char extra[3];
4523
4524 if (writer == NULL)
4525 return -1;
4526
4527 if (p == NULL)
4528 return 0;
4529
4530 sum = 0;
4531 extra[0] = extra[1] = extra[2] = '\0';
4532 if (p != 0) {
4533 sum = 0;
4534 switch (p->state) {
4535 case XML_TEXTWRITER_NAME:
4536 extra[0] = '>';
4537 p->state = XML_TEXTWRITER_TEXT;
4538 break;
4539 case XML_TEXTWRITER_PI:
4540 extra[0] = ' ';
4541 p->state = XML_TEXTWRITER_PI_TEXT;
4542 break;
4543 case XML_TEXTWRITER_DTD:
4544 extra[0] = ' ';
4545 extra[1] = '[';
4546 p->state = XML_TEXTWRITER_DTD_TEXT;
4547 break;
4548 case XML_TEXTWRITER_DTD_ELEM:
4549 extra[0] = ' ';
4550 p->state = XML_TEXTWRITER_DTD_ELEM_TEXT;
4551 break;
4552 case XML_TEXTWRITER_DTD_ATTL:
4553 extra[0] = ' ';
4554 p->state = XML_TEXTWRITER_DTD_ATTL_TEXT;
4555 break;
4556 case XML_TEXTWRITER_DTD_ENTY:
4557 case XML_TEXTWRITER_DTD_PENT:
4558 extra[0] = ' ';
4559 extra[1] = writer->qchar;
4560 p->state = XML_TEXTWRITER_DTD_ENTY_TEXT;
4561 break;
4562 default:
4563 break;
4564 }
4565 }
4566
4567 if (*extra != '\0') {
4568 count = xmlOutputBufferWriteString(writer->out, extra);
4569 if (count < 0)
4570 return -1;
4571 sum += count;
4572 }
4573
4574 return sum;
4575}
4576
Daniel Veillard1d211e22003-10-20 22:32:39 +00004577#endif