blob: 3cda897aa7d96f93dd5cbd0732f13e4566d685a3 [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,
41 XML_TEXTWRITER_DTD_ATTL,
42 XML_TEXTWRITER_DTD_ENTY
43} xmlTextWriterState;
44
45typedef struct _xmlTextWriterStackEntry xmlTextWriterStackEntry;
46
47struct _xmlTextWriterStackEntry {
48 xmlChar *name;
49 xmlTextWriterState state;
50};
51
52typedef struct _xmlTextWriterNsStackEntry xmlTextWriterNsStackEntry;
53struct _xmlTextWriterNsStackEntry {
54 xmlChar *prefix;
55 xmlChar *uri;
56 xmlLinkPtr elem;
57};
58
59struct _xmlTextWriter {
60 xmlOutputBufferPtr out; /* output buffer */
61 xmlListPtr nodes; /* element name stack */
62 xmlListPtr nsstack; /* name spaces stack */
63 int level;
Daniel Veillard2cca4462004-01-02 20:04:23 +000064 int indent; /* enable indent */
65 int doindent; /* internal indent flag */
66 xmlChar *ichar; /* indent character */
Daniel Veillard1d211e22003-10-20 22:32:39 +000067 char qchar; /* character used for quoting attribute values */
Daniel Veillard20c5e782004-01-21 09:57:31 +000068 xmlParserCtxtPtr ctxt;
Daniel Veillard1d211e22003-10-20 22:32:39 +000069};
70
71static void xmlFreeTextWriterStackEntry(xmlLinkPtr lk);
72static int xmlCmpTextWriterStackEntry(const void *data0,
73 const void *data1);
74static void xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk);
75static int xmlCmpTextWriterNsStackEntry(const void *data0,
76 const void *data1);
77static int xmlTextWriterWriteMemCallback(void *context,
78 const xmlChar * str, int len);
79static int xmlTextWriterCloseMemCallback(void *context);
Daniel Veillard5841f0e2003-11-20 11:59:09 +000080static int xmlTextWriterWriteDocCallback(void *context,
81 const xmlChar * str, int len);
82static int xmlTextWriterCloseDocCallback(void *context);
83
Daniel Veillard1d211e22003-10-20 22:32:39 +000084static xmlChar *xmlTextWriterVSprintf(const char *format, va_list argptr);
85static int xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len,
86 const unsigned char *data);
Daniel Veillard5841f0e2003-11-20 11:59:09 +000087static void xmlTextWriterStartDocumentCallback(void *ctx);
Daniel Veillard2cca4462004-01-02 20:04:23 +000088static int xmlTextWriterWriteIndent (xmlTextWriterPtr writer);
Daniel Veillard1d211e22003-10-20 22:32:39 +000089
90/**
91 * xmlNewTextWriter:
92 * @out: an xmlOutputBufferPtr
93 *
94 * Create a new xmlNewTextWriter structure using an xmlOutputBufferPtr
95 *
96 * Returns the new xmlTextWriterPtr or NULL in case of error
97 */
98xmlTextWriterPtr
99xmlNewTextWriter(xmlOutputBufferPtr out)
100{
101 xmlTextWriterPtr ret;
102
103 ret = (xmlTextWriterPtr) xmlMalloc(sizeof(xmlTextWriter));
104 if (ret == NULL) {
105 xmlGenericError(xmlGenericErrorContext,
106 "xmlNewTextWriter : out of memory!\n");
107 return NULL;
108 }
109 memset(ret, 0, (size_t) sizeof(xmlTextWriter));
110
111 ret->nodes = xmlListCreate((xmlListDeallocator)
112 xmlFreeTextWriterStackEntry,
113 (xmlListDataCompare)
114 xmlCmpTextWriterStackEntry);
115 if (ret->nodes == NULL) {
116 xmlGenericError(xmlGenericErrorContext,
117 "xmlNewTextWriter : out of memory!\n");
118 xmlFree(ret);
119 return NULL;
120 }
121
122 ret->nsstack = xmlListCreate((xmlListDeallocator)
123 xmlFreeTextWriterNsStackEntry,
124 (xmlListDataCompare)
125 xmlCmpTextWriterNsStackEntry);
126 if (ret->nsstack == NULL) {
127 xmlGenericError(xmlGenericErrorContext,
128 "xmlNewTextWriter : out of memory!\n");
129 xmlFree(ret->nodes);
130 xmlFree(ret);
131 return NULL;
132 }
133
134 ret->out = out;
Daniel Veillard2cca4462004-01-02 20:04:23 +0000135 ret->ichar = xmlStrdup (BAD_CAST " ");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000136 ret->qchar = '"';
137
Daniel Veillard2cca4462004-01-02 20:04:23 +0000138 if (!ret->ichar) return NULL;
139
Daniel Veillard1d211e22003-10-20 22:32:39 +0000140 return ret;
141}
142
143/**
144 * xmlNewTextWriterFilename:
145 * @uri: the URI of the resource for the output
146 * @compression: compress the output?
147 *
148 * Create a new xmlNewTextWriter structure with @uri as output
149 *
150 * Returns the new xmlTextWriterPtr or NULL in case of error
151 */
152xmlTextWriterPtr
153xmlNewTextWriterFilename(const char *uri, int compression)
154{
155 xmlTextWriterPtr ret;
156 xmlOutputBufferPtr out;
157
158 out = xmlOutputBufferCreateFilename(uri, NULL, compression);
159 if (out == NULL) {
160 xmlGenericError(xmlGenericErrorContext,
161 "xmlNewTextWriterFilename : out of memory!\n");
162 return NULL;
163 }
164
165 ret = xmlNewTextWriter(out);
166 if (ret == NULL) {
167 xmlGenericError(xmlGenericErrorContext,
168 "xmlNewTextWriterFilename : out of memory!\n");
169 xmlOutputBufferClose(out);
170 return NULL;
171 }
172
Daniel Veillard2cca4462004-01-02 20:04:23 +0000173 ret->indent = 0;
174 ret->doindent = 0;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000175 return ret;
176}
177
178/**
179 * xmlNewTextWriterMemory:
180 * @buf: xmlBufferPtr
181 * @compression: compress the output?
182 *
183 * Create a new xmlNewTextWriter structure with @buf as output
184 * TODO: handle compression
185 *
186 * Returns the new xmlTextWriterPtr or NULL in case of error
187 */
188xmlTextWriterPtr
189xmlNewTextWriterMemory(xmlBufferPtr buf, int compression ATTRIBUTE_UNUSED)
190{
191 xmlTextWriterPtr ret;
192 xmlOutputBufferPtr out;
193
194/*::todo handle compression */
195 out = xmlOutputBufferCreateIO((xmlOutputWriteCallback)
196 xmlTextWriterWriteMemCallback,
197 (xmlOutputCloseCallback)
198 xmlTextWriterCloseMemCallback,
199 (void *) buf, NULL);
200 if (out == NULL) {
201 xmlGenericError(xmlGenericErrorContext,
202 "xmlNewTextWriterMemory : out of memory!\n");
203 return NULL;
204 }
205
206 ret = xmlNewTextWriter(out);
207 if (ret == NULL) {
208 xmlGenericError(xmlGenericErrorContext,
209 "xmlNewTextWriterMemory : out of memory!\n");
210 xmlOutputBufferClose(out);
211 return NULL;
212 }
213
214 return ret;
215}
216
217/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000218 * xmlNewTextWriterPushParser:
219 * @ctxt: xmlParserCtxtPtr to hold the new XML document tree
220 * @compression: compress the output?
221 *
222 * Create a new xmlNewTextWriter structure with @ctxt as output
223 * TODO: handle compression
224 *
225 * Returns the new xmlTextWriterPtr or NULL in case of error
226 */
227xmlTextWriterPtr
Daniel Veillard1d913862003-11-21 00:28:39 +0000228xmlNewTextWriterPushParser(xmlParserCtxtPtr ctxt,
229 int compression ATTRIBUTE_UNUSED)
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000230{
231 xmlTextWriterPtr ret;
232 xmlOutputBufferPtr out;
233
234 out = xmlOutputBufferCreateIO((xmlOutputWriteCallback)
235 xmlTextWriterWriteDocCallback,
236 (xmlOutputCloseCallback)
237 xmlTextWriterCloseDocCallback,
238 (void *) ctxt, NULL);
239 if (out == NULL) {
240 xmlGenericError(xmlGenericErrorContext,
241 "xmlNewTextWriterPushParser : error at xmlOutputBufferCreateIO!\n");
242 return NULL;
243 }
244
245 ret = xmlNewTextWriter(out);
246 if (ret == NULL) {
247 xmlGenericError(xmlGenericErrorContext,
248 "xmlNewTextWriterPushParser : error at xmlNewTextWriter!\n");
249 xmlOutputBufferClose(out);
250 return NULL;
251 }
252
Daniel Veillard20c5e782004-01-21 09:57:31 +0000253 ret->ctxt = ctxt;
254
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000255 return ret;
256}
257
258/**
259 * xmlNewTextWriterDoc:
260 * @doc: address of a xmlDocPtr to hold the new XML document tree
261 * @compression: compress the output?
262 *
263 * Create a new xmlNewTextWriter structure with @*doc as output
264 *
265 * Returns the new xmlTextWriterPtr or NULL in case of error
266 */
267xmlTextWriterPtr
268xmlNewTextWriterDoc(xmlDocPtr * doc, int compression)
269{
270 xmlTextWriterPtr ret;
271 xmlSAXHandler saxHandler;
272 xmlParserCtxtPtr ctxt;
273
274 memset(&saxHandler, '\0', sizeof(saxHandler));
275 xmlSAX2InitDefaultSAXHandler(&saxHandler, 1);
276 saxHandler.startDocument = xmlTextWriterStartDocumentCallback;
277 saxHandler.startElement = xmlSAX2StartElement;
278 saxHandler.endElement = xmlSAX2EndElement;
279
280 ctxt = xmlCreatePushParserCtxt(&saxHandler, NULL, NULL, 0, NULL);
281 if (ctxt == NULL) {
282 xmlGenericError(xmlGenericErrorContext,
283 "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\n");
284 return NULL;
285 }
286
Daniel Veillard1d913862003-11-21 00:28:39 +0000287 ctxt->myDoc = xmlNewDoc(BAD_CAST XML_DEFAULT_VERSION);
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000288 if (ctxt->myDoc == NULL) {
289 xmlFreeParserCtxt(ctxt);
290 xmlGenericError(xmlGenericErrorContext,
291 "xmlNewTextWriterDoc : error at xmlNewDoc!\n");
292 return NULL;
293 }
294
295 ret = xmlNewTextWriterPushParser(ctxt, compression);
296 if (ret == NULL) {
297 xmlGenericError(xmlGenericErrorContext,
298 "xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n");
299 return NULL;
300 }
301
302 *doc = ctxt->myDoc;
303 xmlSetDocCompressMode(*doc, compression);
304
305 return ret;
306}
307
308/**
309 * xmlNewTextWriterTree:
310 * @doc: xmlDocPtr
311 * @node: xmlNodePtr or NULL for doc->children
312 * @compression: compress the output?
313 *
314 * Create a new xmlNewTextWriter structure with @doc as output
315 * starting at @node
316 *
317 * Returns the new xmlTextWriterPtr or NULL in case of error
318 */
319xmlTextWriterPtr
320xmlNewTextWriterTree(xmlDocPtr doc, xmlNodePtr node, int compression)
321{
322 xmlTextWriterPtr ret;
323 xmlSAXHandler saxHandler;
324 xmlParserCtxtPtr ctxt;
325
326 if (doc == NULL) {
327 return NULL;
328 }
329
330 memset(&saxHandler, '\0', sizeof(saxHandler));
331 xmlSAX2InitDefaultSAXHandler(&saxHandler, 1);
332 saxHandler.startDocument = xmlTextWriterStartDocumentCallback;
333 saxHandler.startElement = xmlSAX2StartElement;
334 saxHandler.endElement = xmlSAX2EndElement;
335
336 ctxt = xmlCreatePushParserCtxt(&saxHandler, NULL, NULL, 0, NULL);
337 if (ctxt == NULL) {
338 xmlGenericError(xmlGenericErrorContext,
339 "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\n");
340 return NULL;
341 }
342
343 ctxt->myDoc = doc;
344 ctxt->node = node;
345
346 ret = xmlNewTextWriterPushParser(ctxt, compression);
347 if (ret == NULL) {
348 xmlGenericError(xmlGenericErrorContext,
349 "xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n");
350 return NULL;
351 }
352
353 xmlSetDocCompressMode(doc, compression);
354
355 return ret;
356}
357
358/**
Daniel Veillard1d211e22003-10-20 22:32:39 +0000359 * xmlFreeTextWriter:
360 * @writer: the xmlTextWriterPtr
361 *
362 * Deallocate all the resources associated to the writer
363 */
364void
365xmlFreeTextWriter(xmlTextWriterPtr writer)
366{
367 if (writer == NULL)
368 return;
369
370 if (writer->out != NULL)
371 xmlOutputBufferClose(writer->out);
372
373 if (writer->nodes != NULL)
374 xmlListDelete(writer->nodes);
375
376 if (writer->nsstack != NULL)
377 xmlListDelete(writer->nsstack);
378
Daniel Veillard20c5e782004-01-21 09:57:31 +0000379 if (writer->ctxt != NULL)
380 xmlFreeParserCtxt(writer->ctxt);
381
Daniel Veillard4773df22004-01-23 13:15:13 +0000382 if (writer->ichar != NULL)
383 xmlFree(writer->ichar);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000384 xmlFree(writer);
385}
386
387/**
388 * xmlTextWriterStartDocument:
389 * @writer: the xmlTextWriterPtr
390 * @version: the xml version ("1.0") or NULL for default ("1.0")
391 * @encoding: the encoding or NULL for default
392 * @standalone: "yes" or "no" or NULL for default
393 *
394 * Start a new xml document
395 *
396 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
397 */
398int
399xmlTextWriterStartDocument(xmlTextWriterPtr writer, const char *version,
400 const char *encoding, const char *standalone)
401{
402 int count;
403 int sum;
404 xmlLinkPtr lk;
405 xmlCharEncodingHandlerPtr encoder;
406
407 if ((writer == NULL) || (writer->out == NULL))
408 return -1;
409
410 lk = xmlListFront(writer->nodes);
411 if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) {
412 xmlGenericError(xmlGenericErrorContext,
413 "xmlTextWriterStartDocument : only one prolog allowed in an XML document!\n");
414 return -1;
415 }
416
417 encoder = NULL;
418 if (encoding != NULL) {
419 encoder = xmlFindCharEncodingHandler(encoding);
420 if (encoder == NULL) {
421 xmlGenericError(xmlGenericErrorContext,
422 "xmlTextWriterStartDocument : out of memory!\n");
423 return -1;
424 }
425 }
426
427 writer->out->encoder = encoder;
428 if (encoder != NULL) {
429 writer->out->conv = xmlBufferCreateSize(4000);
430 xmlCharEncOutFunc(encoder, writer->out->conv, NULL);
431 } else
432 writer->out->conv = NULL;
433
434 sum = 0;
435 count = xmlOutputBufferWriteString(writer->out, "<?xml version=");
436 if (count < 0)
437 return -1;
438 sum += count;
439 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
440 if (count < 0)
441 return -1;
442 sum += count;
443 if (version != 0)
444 count = xmlOutputBufferWriteString(writer->out, version);
445 else
446 count = xmlOutputBufferWriteString(writer->out, "1.0");
447 if (count < 0)
448 return -1;
449 sum += count;
450 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
451 if (count < 0)
452 return -1;
453 sum += count;
454 if (writer->out->encoder != 0) {
455 count = xmlOutputBufferWriteString(writer->out, " encoding=");
456 if (count < 0)
457 return -1;
458 sum += count;
459 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
460 if (count < 0)
461 return -1;
462 sum += count;
463 count =
464 xmlOutputBufferWriteString(writer->out,
465 writer->out->encoder->name);
466 if (count < 0)
467 return -1;
468 sum += count;
469 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
470 if (count < 0)
471 return -1;
472 sum += count;
473 }
474
475 if (standalone != 0) {
476 count = xmlOutputBufferWriteString(writer->out, " standalone=");
477 if (count < 0)
478 return -1;
479 sum += count;
480 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
481 if (count < 0)
482 return -1;
483 sum += count;
484 count = xmlOutputBufferWriteString(writer->out, standalone);
485 if (count < 0)
486 return -1;
487 sum += count;
488 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
489 if (count < 0)
490 return -1;
491 sum += count;
492 }
493
494 count = xmlOutputBufferWriteString(writer->out, "?>\n");
495 if (count < 0)
496 return -1;
497 sum += count;
498
499 return sum;
500}
501
502/**
503 * xmlTextWriterEndDocument:
504 * @writer: the xmlTextWriterPtr
505 *
506 * End an xml document. All open elements are closed
507 *
508 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
509 */
510int
511xmlTextWriterEndDocument(xmlTextWriterPtr writer)
512{
513 int count;
514 int sum;
515 xmlLinkPtr lk;
516 xmlTextWriterStackEntry *p;
517
518 if (writer == NULL)
519 return -1;
520
521 sum = 0;
522 while ((lk = xmlListFront(writer->nodes)) != NULL) {
523 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
524 if (p == 0)
525 break;
526 switch (p->state) {
527 case XML_TEXTWRITER_NAME:
528 case XML_TEXTWRITER_ATTRIBUTE:
529 case XML_TEXTWRITER_TEXT:
530 count = xmlTextWriterEndElement(writer);
531 if (count < 0)
532 return -1;
533 sum += count;
534 break;
535 case XML_TEXTWRITER_PI:
536 case XML_TEXTWRITER_PI_TEXT:
537 count = xmlTextWriterEndPI(writer);
538 if (count < 0)
539 return -1;
540 sum += count;
541 break;
542 case XML_TEXTWRITER_CDATA:
543 count = xmlTextWriterEndCDATA(writer);
544 if (count < 0)
545 return -1;
546 sum += count;
547 break;
548 case XML_TEXTWRITER_DTD:
549 count = xmlTextWriterEndDTD(writer);
550 if (count < 0)
551 return -1;
552 sum += count;
553 break;
554 default:
555 break;
556 }
557 }
558
Daniel Veillard2cca4462004-01-02 20:04:23 +0000559 if (!writer->indent) {
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000560 count = xmlOutputBufferWriteString(writer->out, "\n");
561 if(count < 0)
562 return -1;
563 sum += count;
Daniel Veillard2cca4462004-01-02 20:04:23 +0000564 }
Daniel Veillard1d211e22003-10-20 22:32:39 +0000565 return sum;
566}
567
568/**
569 * xmlTextWriterWriteFormatComment:
570 * @writer: the xmlTextWriterPtr
571 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +0000572 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +0000573 *
574 * Write an xml comment.
575 *
576 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
577 */
578int
579xmlTextWriterWriteFormatComment(xmlTextWriterPtr writer,
580 const char *format, ...)
581{
582 int rc;
583 va_list ap;
584
585 va_start(ap, format);
586
587 rc = xmlTextWriterWriteVFormatComment(writer, format, ap);
588
589 va_end(ap);
590 return rc;
591}
592
593/**
594 * xmlTextWriterWriteVFormatComment:
595 * @writer: the xmlTextWriterPtr
596 * @format: format string (see printf)
597 * @argptr: pointer to the first member of the variable argument list.
598 *
599 * Write an xml comment.
600 *
601 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
602 */
603int
604xmlTextWriterWriteVFormatComment(xmlTextWriterPtr writer,
605 const char *format, va_list argptr)
606{
607 int rc;
608 xmlChar *buf;
609
610 if (writer == NULL)
611 return -1;
612
613 buf = xmlTextWriterVSprintf(format, argptr);
614 if (buf == 0)
615 return 0;
616
617 rc = xmlTextWriterWriteComment(writer, buf);
618
619 xmlFree(buf);
620 return rc;
621}
622
623/**
624 * xmlTextWriterWriteComment:
625 * @writer: the xmlTextWriterPtr
626 * @content: comment string
627 *
628 * Write an xml comment.
629 *
630 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
631 */
632int
633xmlTextWriterWriteComment(xmlTextWriterPtr writer, const xmlChar * content)
634{
635 int count;
636 int sum;
637 xmlLinkPtr lk;
638 xmlTextWriterStackEntry *p;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000639
640 if ((writer == NULL) || (writer->out == NULL))
641 return -1;
642
643 if (content == NULL)
644 return 0;
645
646 sum = 0;
647 lk = xmlListFront(writer->nodes);
648 if (lk != 0) {
649 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
650 if (p != 0) {
651 switch (p->state) {
652 case XML_TEXTWRITER_PI:
653 case XML_TEXTWRITER_PI_TEXT:
654 return -1;
655 case XML_TEXTWRITER_NONE:
656 case XML_TEXTWRITER_TEXT:
657 break;
658 case XML_TEXTWRITER_NAME:
659 count = xmlOutputBufferWriteString(writer->out, ">");
660 if (count < 0)
661 return -1;
662 sum += count;
663 p->state = XML_TEXTWRITER_TEXT;
664 break;
665 default:
666 break;
667 }
668 }
669 }
670
Daniel Veillard2cca4462004-01-02 20:04:23 +0000671 if (writer->indent) {
672 count = xmlOutputBufferWriteString (writer->out, "\n");
673 sum += count;
674 }
675
Daniel Veillard1d211e22003-10-20 22:32:39 +0000676 count = xmlOutputBufferWriteString(writer->out, "<!--");
677 if (count < 0)
678 return -1;
679 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000680 count = xmlOutputBufferWriteString(writer->out,
681 (const char *) content);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000682 if (count < 0)
683 return -1;
684 sum += count;
685 count = xmlOutputBufferWriteString(writer->out, "-->");
686 if (count < 0)
687 return -1;
688 sum += count;
689
Daniel Veillard2cca4462004-01-02 20:04:23 +0000690 if (writer->indent) {
691 count = xmlOutputBufferWriteString (writer->out, "\n");
692 sum += count;
693 }
694
Daniel Veillard1d211e22003-10-20 22:32:39 +0000695 return sum;
696}
697
698/**
699 * xmlTextWriterStartElement:
700 * @writer: the xmlTextWriterPtr
701 * @name: element name
702 *
703 * Start an xml element.
704 *
705 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
706 */
707int
708xmlTextWriterStartElement(xmlTextWriterPtr writer, const xmlChar * name)
709{
710 int count;
711 int sum;
712 xmlLinkPtr lk;
713 xmlTextWriterStackEntry *p;
714
715 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
716 return -1;
717
718 sum = 0;
719 lk = xmlListFront(writer->nodes);
720 if (lk != 0) {
721 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
722 if (p != 0) {
723 switch (p->state) {
724 case XML_TEXTWRITER_PI:
725 case XML_TEXTWRITER_PI_TEXT:
726 return -1;
727 case XML_TEXTWRITER_NONE:
728 break;
729 case XML_TEXTWRITER_NAME:
730 count = xmlOutputBufferWriteString(writer->out, ">");
731 if (count < 0)
732 return -1;
733 sum += count;
Daniel Veillard2cca4462004-01-02 20:04:23 +0000734 if (writer->indent)
735 count = xmlOutputBufferWriteString (writer->out, "\n");
Daniel Veillard1d211e22003-10-20 22:32:39 +0000736 p->state = XML_TEXTWRITER_TEXT;
737 break;
738 default:
739 break;
740 }
741 }
742 }
743
744 p = (xmlTextWriterStackEntry *)
745 xmlMalloc(sizeof(xmlTextWriterStackEntry));
746 if (p == 0) {
747 xmlGenericError(xmlGenericErrorContext,
748 "xmlTextWriterStartElement : out of memory!\n");
749 return -1;
750 }
751
752 p->name = xmlStrdup(name);
753 if (p->name == 0) {
754 xmlGenericError(xmlGenericErrorContext,
755 "xmlTextWriterStartElement : out of memory!\n");
756 xmlFree(p);
757 return -1;
758 }
759 p->state = XML_TEXTWRITER_NAME;
760
761 xmlListPushFront(writer->nodes, p);
762
Daniel Veillard2cca4462004-01-02 20:04:23 +0000763 if (writer->indent) {
764 count = xmlTextWriterWriteIndent (writer);
765 sum += count;
766 }
767
Daniel Veillard1d211e22003-10-20 22:32:39 +0000768 count = xmlOutputBufferWriteString(writer->out, "<");
769 if (count < 0)
770 return -1;
771 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +0000772 count =
773 xmlOutputBufferWriteString(writer->out, (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +0000774 if (count < 0)
775 return -1;
776 sum += count;
777
778 return sum;
779}
780
781/**
782 * xmlTextWriterStartElementNS:
783 * @writer: the xmlTextWriterPtr
784 * @prefix: namespace prefix or NULL
785 * @name: element local name
786 * @namespaceURI: namespace URI or NULL
787 *
788 * Start an xml element with namespace support.
789 *
790 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
791 */
792int
793xmlTextWriterStartElementNS(xmlTextWriterPtr writer,
794 const xmlChar * prefix, const xmlChar * name,
795 const xmlChar * namespaceURI)
796{
797 int count;
798 int sum;
799 xmlChar *buf;
800
801 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
802 return -1;
803
804 buf = 0;
805 if (prefix != 0) {
806 buf = xmlStrdup(prefix);
807 buf = xmlStrcat(buf, BAD_CAST ":");
808 }
809 buf = xmlStrcat(buf, name);
810
811 sum = 0;
812 count = xmlTextWriterStartElement(writer, buf);
813 xmlFree(buf);
814 if (count < 0)
815 return -1;
816 sum += count;
817
818 if (namespaceURI != 0) {
819 buf = xmlStrdup(BAD_CAST "xmlns");
820 if (prefix != 0) {
821 buf = xmlStrcat(buf, BAD_CAST ":");
822 buf = xmlStrcat(buf, prefix);
823 }
824
825 count = xmlTextWriterWriteAttribute(writer, buf, namespaceURI);
826 xmlFree(buf);
827 if (count < 0)
828 return -1;
829 sum += count;
830 }
831
832 return sum;
833}
834
835/**
836 * xmlTextWriterEndElement:
837 * @writer: the xmlTextWriterPtr
838 *
839 * End the current xml element.
840 *
841 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
842 */
843int
844xmlTextWriterEndElement(xmlTextWriterPtr writer)
845{
846 int count;
847 int sum;
848 xmlLinkPtr lk;
849 xmlTextWriterStackEntry *p;
850
851 if (writer == NULL)
852 return -1;
853
854 lk = xmlListFront(writer->nodes);
855 if (lk == 0)
856 return -1;
857
858 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
859 if (p == 0)
860 return -1;
861
862 sum = 0;
863 switch (p->state) {
864 case XML_TEXTWRITER_ATTRIBUTE:
865 count = xmlTextWriterEndAttribute(writer);
866 if (count < 0)
867 return -1;
868 sum += count;
869 /* fallthrough */
870 case XML_TEXTWRITER_NAME:
871 count = xmlOutputBufferWriteString(writer->out, "/>");
872 if (count < 0)
873 return -1;
874 sum += count;
875 break;
876 case XML_TEXTWRITER_TEXT:
Daniel Veillard2cca4462004-01-02 20:04:23 +0000877 if ((writer->indent) && (writer->doindent)) {
878 count = xmlTextWriterWriteIndent (writer);
879 sum += count;
880 writer->doindent = 1;
881 } else writer->doindent = 1;
Daniel Veillard1d211e22003-10-20 22:32:39 +0000882 count = xmlOutputBufferWriteString(writer->out, "</");
883 if (count < 0)
884 return -1;
885 sum += count;
886 count = xmlOutputBufferWriteString(writer->out,
887 (const char *)p->name);
888 if (count < 0)
889 return -1;
890 sum += count;
891 count = xmlOutputBufferWriteString(writer->out, ">");
892 if (count < 0)
893 return -1;
894 sum += count;
895 break;
896 default:
897 return -1;
898 }
899
Daniel Veillard2cca4462004-01-02 20:04:23 +0000900 if (writer->indent) {
901 count = xmlOutputBufferWriteString (writer->out, "\n");
902 sum += count;
903 }
904
Daniel Veillard1d211e22003-10-20 22:32:39 +0000905 xmlListPopFront(writer->nodes);
906 return sum;
907}
908
909/**
910 * xmlTextWriterFullEndElement:
911 * @writer: the xmlTextWriterPtr
912 *
913 * End the current xml element. Writes an end tag even if the element is empty
914 *
915 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
916 */
917int
918xmlTextWriterFullEndElement(xmlTextWriterPtr writer)
919{
920 int count;
921 int sum;
922 xmlLinkPtr lk;
923 xmlTextWriterStackEntry *p;
924
925 if (writer == NULL)
926 return -1;
927
928 lk = xmlListFront(writer->nodes);
929 if (lk == 0)
930 return -1;
931
932 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
933 if (p == 0)
934 return -1;
935
936 sum = 0;
937 switch (p->state) {
938 case XML_TEXTWRITER_ATTRIBUTE:
939 count = xmlTextWriterEndAttribute(writer);
940 if (count < 0)
941 return -1;
942 sum += count;
943 /* fallthrough */
944 case XML_TEXTWRITER_NAME:
945 count = xmlOutputBufferWriteString(writer->out, ">");
946 if (count < 0)
947 return -1;
948 sum += count;
949 /* fallthrough */
950 case XML_TEXTWRITER_TEXT:
951 count = xmlOutputBufferWriteString(writer->out, "</");
952 if (count < 0)
953 return -1;
954 sum += count;
955 count = xmlOutputBufferWriteString(writer->out,
956 (const char *) p->name);
957 if (count < 0)
958 return -1;
959 sum += count;
960 count = xmlOutputBufferWriteString(writer->out, ">");
961 if (count < 0)
962 return -1;
963 sum += count;
964 break;
965 default:
966 return -1;
967 }
968
969 xmlListPopFront(writer->nodes);
970 return sum;
971}
972
973/**
974 * xmlTextWriterWriteFormatRaw:
975 * @writer: the xmlTextWriterPtr
976 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +0000977 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +0000978 *
979 * Write a formatted raw xml text.
980 *
981 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
982 */
983int
984xmlTextWriterWriteFormatRaw(xmlTextWriterPtr writer, const char *format,
985 ...)
986{
987 int rc;
988 va_list ap;
989
990 va_start(ap, format);
991
992 rc = xmlTextWriterWriteVFormatRaw(writer, format, ap);
993
994 va_end(ap);
995 return rc;
996}
997
998/**
999 * xmlTextWriterWriteVFormatRaw:
1000 * @writer: the xmlTextWriterPtr
1001 * @format: format string (see printf)
1002 * @argptr: pointer to the first member of the variable argument list.
1003 *
1004 * Write a formatted raw xml text.
1005 *
1006 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1007 */
1008int
1009xmlTextWriterWriteVFormatRaw(xmlTextWriterPtr writer, const char *format,
1010 va_list argptr)
1011{
1012 int rc;
1013 xmlChar *buf;
1014
1015 if (writer == NULL)
1016 return -1;
1017
1018 buf = xmlTextWriterVSprintf(format, argptr);
1019 if (buf == 0)
1020 return 0;
1021
1022 rc = xmlTextWriterWriteRaw(writer, buf);
1023
1024 xmlFree(buf);
1025 return rc;
1026}
1027
1028/**
Daniel Veillard1e906612003-12-05 14:57:46 +00001029 * xmlTextWriterWriteRawLen:
Daniel Veillard1d211e22003-10-20 22:32:39 +00001030 * @writer: the xmlTextWriterPtr
1031 * @content: text string
1032 * @len: length of the text string
1033 *
1034 * Write an xml text.
1035 * TODO: what about entities and special chars??
1036 *
1037 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1038 */
1039int
1040xmlTextWriterWriteRawLen(xmlTextWriterPtr writer, const xmlChar * content,
1041 int len)
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 0;
1054
1055 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1056 if (p == 0)
1057 return 0;
1058
1059 sum = 0;
1060 switch (p->state) {
1061 case XML_TEXTWRITER_NONE:
1062 return -1;
1063 case XML_TEXTWRITER_NAME:
1064 count = xmlOutputBufferWriteString(writer->out, ">");
1065 if (count < 0)
1066 return -1;
1067 sum += count;
1068 p->state = XML_TEXTWRITER_TEXT;
1069 break;
1070 case XML_TEXTWRITER_PI:
1071 count = xmlOutputBufferWriteString(writer->out, " ");
1072 if (count < 0)
1073 return -1;
1074 sum += count;
1075 p->state = XML_TEXTWRITER_PI_TEXT;
1076 break;
1077 case XML_TEXTWRITER_DTD:
1078 count = xmlOutputBufferWriteString(writer->out, " [");
1079 if (count < 0)
1080 return -1;
1081 sum += count;
1082 p->state = XML_TEXTWRITER_DTD_TEXT;
1083 break;
1084 default:
1085 break;
1086 }
1087
1088 count = xmlOutputBufferWrite(writer->out, len, (const char *) content);
1089 if (count < 0)
1090 return -1;
1091 sum += count;
1092
1093 return sum;
1094}
1095
1096/**
1097 * xmlTextWriterWriteRaw:
1098 * @writer: the xmlTextWriterPtr
1099 * @content: text string
1100 *
1101 * Write a raw xml text.
1102 *
1103 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1104 */
1105int
1106xmlTextWriterWriteRaw(xmlTextWriterPtr writer, const xmlChar * content)
1107{
1108 return xmlTextWriterWriteRawLen(writer, content, xmlStrlen(content));
1109}
1110
1111/**
1112 * xmlTextWriterWriteFormatString:
1113 * @writer: the xmlTextWriterPtr
1114 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001115 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001116 *
1117 * Write a formatted xml text.
1118 *
1119 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1120 */
1121int
1122xmlTextWriterWriteFormatString(xmlTextWriterPtr writer, const char *format,
1123 ...)
1124{
1125 int rc;
1126 va_list ap;
1127
1128 va_start(ap, format);
1129
1130 rc = xmlTextWriterWriteVFormatString(writer, format, ap);
1131
1132 va_end(ap);
1133 return rc;
1134}
1135
1136/**
1137 * xmlTextWriterWriteVFormatString:
1138 * @writer: the xmlTextWriterPtr
1139 * @format: format string (see printf)
1140 * @argptr: pointer to the first member of the variable argument list.
1141 *
1142 * Write a formatted xml text.
1143 *
1144 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1145 */
1146int
1147xmlTextWriterWriteVFormatString(xmlTextWriterPtr writer,
1148 const char *format, va_list argptr)
1149{
1150 int rc;
1151 xmlChar *buf;
1152
1153 if (writer == NULL)
1154 return -1;
1155
1156 buf = xmlTextWriterVSprintf(format, argptr);
1157 if (buf == 0)
1158 return 0;
1159
1160 rc = xmlTextWriterWriteString(writer, buf);
1161
1162 xmlFree(buf);
1163 return rc;
1164}
1165
1166/**
1167 * xmlTextWriterWriteString:
1168 * @writer: the xmlTextWriterPtr
1169 * @content: text string
1170 *
1171 * Write an xml text.
1172 *
1173 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1174 */
1175int
1176xmlTextWriterWriteString(xmlTextWriterPtr writer, const xmlChar * content)
1177{
1178 int count;
1179 int sum;
1180 xmlLinkPtr lk;
1181 xmlTextWriterStackEntry *p;
1182 xmlChar *buf = NULL;
1183
1184 if (writer == NULL)
1185 return -1;
1186
1187 lk = xmlListFront(writer->nodes);
1188 if (lk == 0)
1189 return -1;
1190
1191 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1192 if (p == 0)
1193 return -1;
1194
1195 sum = 0;
1196 switch (p->state) {
1197 case XML_TEXTWRITER_NONE:
1198 return -1;
1199 case XML_TEXTWRITER_NAME:
1200 count = xmlOutputBufferWriteString(writer->out, ">");
1201 if (count < 0)
1202 return -1;
1203 sum += count;
1204 p->state = XML_TEXTWRITER_TEXT;
1205 goto encode;
1206 case XML_TEXTWRITER_PI:
1207 count = xmlOutputBufferWriteString(writer->out, " ");
1208 if (count < 0)
1209 return -1;
1210 sum += count;
1211 p->state = XML_TEXTWRITER_PI_TEXT;
1212 /* fallthrough */
1213 case XML_TEXTWRITER_PI_TEXT:
1214 case XML_TEXTWRITER_TEXT:
1215 case XML_TEXTWRITER_ATTRIBUTE:
1216 encode:
Daniel Veillard5841f0e2003-11-20 11:59:09 +00001217 buf = xmlEncodeSpecialChars(NULL, content);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001218 break;
1219 case XML_TEXTWRITER_DTD:
1220 count = xmlOutputBufferWriteString(writer->out, " [");
1221 if (count < 0)
1222 return -1;
1223 sum += count;
1224 p->state = XML_TEXTWRITER_DTD_TEXT;
1225 /* fallthrough */
1226 case XML_TEXTWRITER_DTD_TEXT:
1227 case XML_TEXTWRITER_DTD_ELEM:
1228 case XML_TEXTWRITER_CDATA:
1229 buf = xmlStrdup(content);
1230 break;
1231 default:
1232 break;
1233 }
1234
Daniel Veillard751c9ec2004-01-05 13:05:58 +00001235 if (writer->indent)
1236 writer->doindent = 0;
1237
Daniel Veillard1d211e22003-10-20 22:32:39 +00001238 if (buf != 0) {
Daniel Veillard5841f0e2003-11-20 11:59:09 +00001239 count =
1240 xmlOutputBufferWriteString(writer->out, (const char *) buf);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001241 xmlFree(buf);
1242 } else
1243 count = -1;
1244 if (count < 0)
1245 return -1;
1246 sum += count;
1247
1248 return sum;
1249}
1250
1251/**
1252 * xmlOutputBufferWriteBase64:
1253 * @out: the xmlOutputBufferPtr
1254 * @data: binary data
1255 * @len: the number of bytes to encode
1256 *
1257 * Write base64 encoded data to an xmlOutputBuffer.
1258 * Adapted from John Walker's base64.c (http://www.fourmilab.ch/).
1259 *
1260 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1261 */
1262static int
1263xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len,
1264 const unsigned char *data)
1265{
1266 static unsigned char dtable[64] =
1267 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1268 int i;
1269 int linelen;
1270 int count;
1271 int sum;
1272
1273 linelen = 0;
1274 sum = 0;
1275
1276 i = 0;
1277 while (1) {
1278 unsigned char igroup[3];
1279 unsigned char ogroup[4];
1280 int c;
1281 int n;
1282
1283 igroup[0] = igroup[1] = igroup[2] = 0;
1284 for (n = 0; n < 3 && i < len; n++, i++) {
1285 c = data[i];
1286 igroup[n] = (unsigned char) c;
1287 }
1288
1289 if (n > 0) {
1290 ogroup[0] = dtable[igroup[0] >> 2];
1291 ogroup[1] = dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)];
1292 ogroup[2] =
1293 dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)];
1294 ogroup[3] = dtable[igroup[2] & 0x3F];
1295
1296 if (n < 3) {
1297 ogroup[3] = '=';
1298 if (n < 2) {
1299 ogroup[2] = '=';
1300 }
1301 }
1302
1303 if (linelen >= B64LINELEN) {
1304 count = xmlOutputBufferWrite(out, 2, B64CRLF);
1305 if (count == -1)
1306 return -1;
1307 sum += count;
1308 linelen = 0;
1309 }
1310 count = xmlOutputBufferWrite(out, 4, (const char *) ogroup);
1311 if (count == -1)
1312 return -1;
1313 sum += count;
1314
1315 linelen += 4;
1316 }
Daniel Veillard929714b2003-10-22 12:34:36 +00001317
1318 if (i >= len)
1319 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +00001320 }
1321
1322 count = xmlOutputBufferWrite(out, 2, B64CRLF);
1323 if (count == -1)
1324 return -1;
1325 sum += count;
1326
1327 return sum;
1328}
1329
1330/**
1331 * xmlTextWriterWriteBase64:
1332 * @writer: the xmlTextWriterPtr
1333 * @data: binary data
1334 * @start: the position within the data of the first byte to encode
1335 * @len: the number of bytes to encode
1336 *
1337 * Write an base64 encoded xml text.
1338 *
1339 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1340 */
1341int
1342xmlTextWriterWriteBase64(xmlTextWriterPtr writer, const char * data,
1343 int start, int len)
1344{
1345 int count;
1346 int sum;
1347 xmlLinkPtr lk;
1348 xmlTextWriterStackEntry *p;
1349
1350 if (writer == NULL)
1351 return -1;
1352
1353 lk = xmlListFront(writer->nodes);
1354 if (lk == 0)
1355 return 0;
1356
1357 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1358 if (p == 0)
1359 return 0;
1360
1361 sum = 0;
1362 switch (p->state) {
1363 case XML_TEXTWRITER_NONE:
1364 return -1;
1365 case XML_TEXTWRITER_NAME:
1366 count = xmlOutputBufferWriteString(writer->out, ">");
1367 if (count < 0)
1368 return -1;
1369 sum += count;
1370 p->state = XML_TEXTWRITER_TEXT;
1371 break;
1372 case XML_TEXTWRITER_PI:
1373 count = xmlOutputBufferWriteString(writer->out, " ");
1374 if (count < 0)
1375 return -1;
1376 sum += count;
1377 p->state = XML_TEXTWRITER_PI_TEXT;
1378 break;
1379 case XML_TEXTWRITER_DTD:
1380 count = xmlOutputBufferWriteString(writer->out, " [");
1381 if (count < 0)
1382 return -1;
1383 sum += count;
1384 p->state = XML_TEXTWRITER_DTD_TEXT;
1385 break;
1386 default:
1387 break;
1388 }
1389
1390 count =
1391 xmlOutputBufferWriteBase64(writer->out, len,
1392 (unsigned char *) data + start);
1393 if (count < 0)
1394 return -1;
1395 sum += count;
1396
1397 return sum;
1398}
1399
1400/**
1401 * xmlOutputBufferWriteBinHex:
1402 * @out: the xmlOutputBufferPtr
1403 * @data: binary data
1404 * @len: the number of bytes to encode
1405 *
1406 * Write hqx encoded data to an xmlOutputBuffer.
1407 * ::todo
1408 *
1409 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1410 */
1411static int
1412xmlOutputBufferWriteBinHex(xmlOutputBufferPtr out ATTRIBUTE_UNUSED,
1413 int len ATTRIBUTE_UNUSED,
1414 const unsigned char *data ATTRIBUTE_UNUSED)
1415{
1416 return -1;
1417}
1418
1419/**
1420 * xmlTextWriterWriteBinHex:
1421 * @writer: the xmlTextWriterPtr
1422 * @data: binary data
1423 * @start: the position within the data of the first byte to encode
1424 * @len: the number of bytes to encode
1425 *
1426 * Write a BinHex encoded xml text.
1427 *
1428 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1429 */
1430int
1431xmlTextWriterWriteBinHex(xmlTextWriterPtr writer, const char * data,
1432 int start, int len)
1433{
1434 int count;
1435 int sum;
1436 xmlLinkPtr lk;
1437 xmlTextWriterStackEntry *p;
1438
1439 if (writer == NULL)
1440 return -1;
1441
1442 lk = xmlListFront(writer->nodes);
1443 if (lk == 0)
1444 return 0;
1445
1446 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1447 if (p == 0)
1448 return 0;
1449
1450 sum = 0;
1451 switch (p->state) {
1452 case XML_TEXTWRITER_NONE:
1453 return -1;
1454 case XML_TEXTWRITER_NAME:
1455 count = xmlOutputBufferWriteString(writer->out, ">");
1456 if (count < 0)
1457 return -1;
1458 sum += count;
1459 p->state = XML_TEXTWRITER_TEXT;
1460 break;
1461 case XML_TEXTWRITER_PI:
1462 count = xmlOutputBufferWriteString(writer->out, " ");
1463 if (count < 0)
1464 return -1;
1465 sum += count;
1466 p->state = XML_TEXTWRITER_PI_TEXT;
1467 break;
1468 case XML_TEXTWRITER_DTD:
1469 count = xmlOutputBufferWriteString(writer->out, " [");
1470 if (count < 0)
1471 return -1;
1472 sum += count;
1473 p->state = XML_TEXTWRITER_DTD_TEXT;
1474 break;
1475 default:
1476 break;
1477 }
1478
1479 count =
1480 xmlOutputBufferWriteBinHex(writer->out, len,
1481 (unsigned char *) data + start);
1482 if (count < 0)
1483 return -1;
1484 sum += count;
1485
1486 return sum;
1487}
1488
1489/**
1490 * xmlTextWriterStartAttribute:
1491 * @writer: the xmlTextWriterPtr
1492 * @name: element name
1493 *
1494 * Start an xml attribute.
1495 *
1496 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1497 */
1498int
1499xmlTextWriterStartAttribute(xmlTextWriterPtr writer, const xmlChar * name)
1500{
1501 int count;
1502 int sum;
1503 xmlLinkPtr lk;
1504 xmlTextWriterStackEntry *p;
1505
1506 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1507 return -1;
1508
1509 sum = 0;
1510 lk = xmlListFront(writer->nodes);
1511 if (lk == 0)
1512 return -1;
1513
1514 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1515 if (p == 0)
1516 return -1;
1517
1518 switch (p->state) {
1519 case XML_TEXTWRITER_ATTRIBUTE:
1520 count = xmlTextWriterEndAttribute(writer);
1521 if (count < 0)
1522 return -1;
1523 sum += count;
1524 /* fallthrough */
1525 case XML_TEXTWRITER_NAME:
1526 count = xmlOutputBufferWriteString(writer->out, " ");
1527 if (count < 0)
1528 return -1;
1529 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00001530 count =
1531 xmlOutputBufferWriteString(writer->out,
1532 (const char *) name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00001533 if (count < 0)
1534 return -1;
1535 sum += count;
1536 count = xmlOutputBufferWriteString(writer->out, "=");
1537 if (count < 0)
1538 return -1;
1539 sum += count;
1540 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
1541 if (count < 0)
1542 return -1;
1543 sum += count;
1544 p->state = XML_TEXTWRITER_ATTRIBUTE;
1545 break;
1546 default:
1547 return -1;
1548 }
1549
1550 return sum;
1551}
1552
1553/**
1554 * xmlTextWriterStartAttributeNS:
1555 * @writer: the xmlTextWriterPtr
1556 * @prefix: namespace prefix or NULL
1557 * @name: element local name
1558 * @namespaceURI: namespace URI or NULL
1559 *
1560 * Start an xml attribute with namespace support.
1561 *
1562 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1563 */
1564int
1565xmlTextWriterStartAttributeNS(xmlTextWriterPtr writer,
1566 const xmlChar * prefix, const xmlChar * name,
1567 const xmlChar * namespaceURI)
1568{
1569 int count;
1570 int sum;
1571 xmlChar *buf;
1572 xmlTextWriterNsStackEntry *p;
1573
1574 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1575 return -1;
1576
1577 buf = 0;
1578 if (prefix != 0) {
1579 buf = xmlStrdup(prefix);
1580 buf = xmlStrcat(buf, BAD_CAST ":");
1581 }
1582 buf = xmlStrcat(buf, name);
1583
1584 sum = 0;
1585 count = xmlTextWriterStartAttribute(writer, buf);
1586 xmlFree(buf);
1587 if (count < 0)
1588 return -1;
1589 sum += count;
1590
1591 if (namespaceURI != 0) {
1592 buf = xmlStrdup(BAD_CAST "xmlns");
1593 if (prefix != 0) {
1594 buf = xmlStrcat(buf, BAD_CAST ":");
1595 buf = xmlStrcat(buf, prefix);
1596 }
1597
1598 p = (xmlTextWriterNsStackEntry *)
1599 xmlMalloc(sizeof(xmlTextWriterNsStackEntry));
1600 if (p == 0) {
1601 xmlGenericError(xmlGenericErrorContext,
1602 "xmlTextWriterStartAttributeNS : out of memory!\n");
1603 return -1;
1604 }
1605
1606 p->prefix = buf;
1607 p->uri = xmlStrdup(namespaceURI);
1608 if (p->uri == 0) {
1609 xmlGenericError(xmlGenericErrorContext,
1610 "xmlTextWriterStartAttributeNS : out of memory!\n");
1611 xmlFree(p);
1612 return -1;
1613 }
1614 p->elem = xmlListFront(writer->nodes);
1615
1616 xmlListPushFront(writer->nsstack, p);
1617 }
1618
1619 return sum;
1620}
1621
1622/**
1623 * xmlTextWriterEndAttribute:
1624 * @writer: the xmlTextWriterPtr
1625 *
1626 * End the current xml element.
1627 *
1628 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1629 */
1630int
1631xmlTextWriterEndAttribute(xmlTextWriterPtr writer)
1632{
1633 int count;
1634 int sum;
1635 xmlLinkPtr lk;
1636 xmlTextWriterStackEntry *p;
1637 xmlTextWriterNsStackEntry *np;
1638
1639 if (writer == NULL)
1640 return -1;
1641
1642 lk = xmlListFront(writer->nodes);
1643 if (lk == 0) {
1644 xmlListDelete(writer->nsstack);
1645 return -1;
1646 }
1647
1648 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1649 if (p == 0) {
1650 xmlListDelete(writer->nsstack);
1651 return -1;
1652 }
1653
1654 sum = 0;
1655 switch (p->state) {
1656 case XML_TEXTWRITER_ATTRIBUTE:
1657 p->state = XML_TEXTWRITER_NAME;
1658
1659 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
1660 if (count < 0) {
1661 xmlListDelete(writer->nsstack);
1662 return -1;
1663 }
1664 sum += count;
1665
1666 while (!xmlListEmpty(writer->nsstack)) {
1667 lk = xmlListFront(writer->nsstack);
1668 np = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
1669 if (np != 0) {
1670 count =
1671 xmlTextWriterWriteAttribute(writer, np->prefix,
1672 np->uri);
1673 if (count < 0) {
1674 xmlListDelete(writer->nsstack);
1675 return -1;
1676 }
1677 sum += count;
1678 }
1679
1680 xmlListPopFront(writer->nsstack);
1681 }
1682 break;
1683
1684 default:
1685 xmlListClear(writer->nsstack);
1686 return -1;
1687 }
1688
1689 return sum;
1690}
1691
1692/**
1693 * xmlTextWriterWriteFormatAttribute:
1694 * @writer: the xmlTextWriterPtr
1695 * @name: attribute name
1696 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001697 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001698 *
1699 * Write a formatted xml attribute.
1700 *
1701 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1702 */
1703int
1704xmlTextWriterWriteFormatAttribute(xmlTextWriterPtr writer,
1705 const xmlChar * name, const char *format,
1706 ...)
1707{
1708 int rc;
1709 va_list ap;
1710
1711 va_start(ap, format);
1712
1713 rc = xmlTextWriterWriteVFormatAttribute(writer, name, format, ap);
1714
1715 va_end(ap);
1716 return rc;
1717}
1718
1719/**
1720 * xmlTextWriterWriteVFormatAttribute:
1721 * @writer: the xmlTextWriterPtr
1722 * @name: attribute name
1723 * @format: format string (see printf)
1724 * @argptr: pointer to the first member of the variable argument list.
1725 *
1726 * Write a formatted xml attribute.
1727 *
1728 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1729 */
1730int
1731xmlTextWriterWriteVFormatAttribute(xmlTextWriterPtr writer,
1732 const xmlChar * name,
1733 const char *format, va_list argptr)
1734{
1735 int rc;
1736 xmlChar *buf;
1737
1738 if (writer == NULL)
1739 return -1;
1740
1741 buf = xmlTextWriterVSprintf(format, argptr);
1742 if (buf == 0)
1743 return 0;
1744
1745 rc = xmlTextWriterWriteAttribute(writer, name, buf);
1746
1747 xmlFree(buf);
1748 return rc;
1749}
1750
1751/**
1752 * xmlTextWriterWriteAttribute:
1753 * @writer: the xmlTextWriterPtr
1754 * @name: attribute name
1755 * @content: attribute content
1756 *
1757 * Write an xml attribute.
1758 *
1759 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1760 */
1761int
1762xmlTextWriterWriteAttribute(xmlTextWriterPtr writer, const xmlChar * name,
1763 const xmlChar * content)
1764{
1765 int count;
1766 int sum;
1767
1768 sum = 0;
1769 count = xmlTextWriterStartAttribute(writer, name);
1770 if (count < 0)
1771 return -1;
1772 sum += count;
1773 count = xmlTextWriterWriteString(writer, content);
1774 if (count < 0)
1775 return -1;
1776 sum += count;
1777 count = xmlTextWriterEndAttribute(writer);
1778 if (count < 0)
1779 return -1;
1780 sum += count;
1781
1782 return sum;
1783}
1784
1785/**
1786 * xmlTextWriterWriteFormatAttributeNS:
1787 * @writer: the xmlTextWriterPtr
1788 * @prefix: namespace prefix
1789 * @name: attribute local name
1790 * @namespaceURI: namespace URI
1791 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001792 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001793 *
1794 * Write a formatted xml attribute.with namespace support
1795 *
1796 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1797 */
1798int
1799xmlTextWriterWriteFormatAttributeNS(xmlTextWriterPtr writer,
1800 const xmlChar * prefix,
1801 const xmlChar * name,
1802 const xmlChar * namespaceURI,
1803 const char *format, ...)
1804{
1805 int rc;
1806 va_list ap;
1807
1808 va_start(ap, format);
1809
1810 rc = xmlTextWriterWriteVFormatAttributeNS(writer, prefix, name,
1811 namespaceURI, format, ap);
1812
1813 va_end(ap);
1814 return rc;
1815}
1816
1817/**
1818 * xmlTextWriterWriteVFormatAttributeNS:
1819 * @writer: the xmlTextWriterPtr
1820 * @prefix: namespace prefix
1821 * @name: attribute local name
1822 * @namespaceURI: namespace URI
1823 * @format: format string (see printf)
1824 * @argptr: pointer to the first member of the variable argument list.
1825 *
1826 * Write a formatted xml attribute.with namespace support
1827 *
1828 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1829 */
1830int
1831xmlTextWriterWriteVFormatAttributeNS(xmlTextWriterPtr writer,
1832 const xmlChar * prefix,
1833 const xmlChar * name,
1834 const xmlChar * namespaceURI,
1835 const char *format, va_list argptr)
1836{
1837 int rc;
1838 xmlChar *buf;
1839
1840 if (writer == NULL)
1841 return -1;
1842
1843 buf = xmlTextWriterVSprintf(format, argptr);
1844 if (buf == 0)
1845 return 0;
1846
1847 rc = xmlTextWriterWriteAttributeNS(writer, prefix, name, namespaceURI,
1848 buf);
1849
1850 xmlFree(buf);
1851 return rc;
1852}
1853
1854/**
1855 * xmlTextWriterWriteAttributeNS:
1856 * @writer: the xmlTextWriterPtr
1857 * @prefix: namespace prefix
1858 * @name: attribute local name
1859 * @namespaceURI: namespace URI
1860 * @content: attribute content
1861 *
1862 * Write an xml attribute.
1863 *
1864 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1865 */
1866int
1867xmlTextWriterWriteAttributeNS(xmlTextWriterPtr writer,
1868 const xmlChar * prefix, const xmlChar * name,
1869 const xmlChar * namespaceURI,
1870 const xmlChar * content)
1871{
1872 int count;
1873 int sum;
1874 xmlChar *buf;
1875
1876 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1877 return -1;
1878
1879 buf = 0;
1880 if (prefix != NULL) {
1881 buf = xmlStrdup(prefix);
1882 buf = xmlStrcat(buf, BAD_CAST ":");
1883 }
1884 buf = xmlStrcat(buf, name);
1885
1886 sum = 0;
1887 count = xmlTextWriterWriteAttribute(writer, buf, content);
1888 xmlFree(buf);
1889 if (count < 0)
1890 return -1;
1891 sum += count;
1892
1893 if (namespaceURI != NULL) {
1894 buf = 0;
1895 buf = xmlStrdup(BAD_CAST "xmlns");
1896 if (prefix != NULL) {
1897 buf = xmlStrcat(buf, BAD_CAST ":");
1898 buf = xmlStrcat(buf, prefix);
1899 }
1900 count = xmlTextWriterWriteAttribute(writer, buf, namespaceURI);
1901 xmlFree(buf);
1902 if (count < 0)
1903 return -1;
1904 sum += count;
1905 }
1906 return sum;
1907}
1908
1909/**
1910 * xmlTextWriterWriteFormatElement:
1911 * @writer: the xmlTextWriterPtr
1912 * @name: element name
1913 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00001914 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00001915 *
1916 * Write a formatted xml element.
1917 *
1918 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1919 */
1920int
1921xmlTextWriterWriteFormatElement(xmlTextWriterPtr writer,
1922 const xmlChar * name, const char *format,
1923 ...)
1924{
1925 int rc;
1926 va_list ap;
1927
1928 va_start(ap, format);
1929
1930 rc = xmlTextWriterWriteVFormatElement(writer, name, format, ap);
1931
1932 va_end(ap);
1933 return rc;
1934}
1935
1936/**
1937 * xmlTextWriterWriteVFormatElement:
1938 * @writer: the xmlTextWriterPtr
1939 * @name: element name
1940 * @format: format string (see printf)
1941 * @argptr: pointer to the first member of the variable argument list.
1942 *
1943 * Write a formatted xml element.
1944 *
1945 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1946 */
1947int
1948xmlTextWriterWriteVFormatElement(xmlTextWriterPtr writer,
1949 const xmlChar * name, const char *format,
1950 va_list argptr)
1951{
1952 int rc;
1953 xmlChar *buf;
1954
1955 if (writer == NULL)
1956 return -1;
1957
1958 buf = xmlTextWriterVSprintf(format, argptr);
1959 if (buf == 0)
1960 return 0;
1961
1962 rc = xmlTextWriterWriteElement(writer, name, buf);
1963
1964 xmlFree(buf);
1965 return rc;
1966}
1967
1968/**
1969 * xmlTextWriterWriteElement:
1970 * @writer: the xmlTextWriterPtr
1971 * @name: element name
1972 * @content: element content
1973 *
1974 * Write an xml element.
1975 *
1976 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1977 */
1978int
1979xmlTextWriterWriteElement(xmlTextWriterPtr writer, const xmlChar * name,
1980 const xmlChar * content)
1981{
1982 int count;
1983 int sum;
1984
1985 sum = 0;
1986 count = xmlTextWriterStartElement(writer, name);
1987 if (count == -1)
1988 return -1;
1989 sum += count;
1990 count = xmlTextWriterWriteString(writer, content);
1991 if (count == -1)
1992 return -1;
1993 sum += count;
1994 count = xmlTextWriterEndElement(writer);
1995 if (count == -1)
1996 return -1;
1997 sum += count;
1998
1999 return sum;
2000}
2001
2002/**
2003 * xmlTextWriterWriteFormatElementNS:
2004 * @writer: the xmlTextWriterPtr
2005 * @prefix: namespace prefix
2006 * @name: element local name
2007 * @namespaceURI: namespace URI
2008 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002009 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002010 *
2011 * Write a formatted xml element with namespace support.
2012 *
2013 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2014 */
2015int
2016xmlTextWriterWriteFormatElementNS(xmlTextWriterPtr writer,
2017 const xmlChar * prefix,
2018 const xmlChar * name,
2019 const xmlChar * namespaceURI,
2020 const char *format, ...)
2021{
2022 int rc;
2023 va_list ap;
2024
2025 va_start(ap, format);
2026
2027 rc = xmlTextWriterWriteVFormatElementNS(writer, prefix, name,
2028 namespaceURI, format, ap);
2029
2030 va_end(ap);
2031 return rc;
2032}
2033
2034/**
2035 * xmlTextWriterWriteVFormatElementNS:
2036 * @writer: the xmlTextWriterPtr
2037 * @prefix: namespace prefix
2038 * @name: element local name
2039 * @namespaceURI: namespace URI
2040 * @format: format string (see printf)
2041 * @argptr: pointer to the first member of the variable argument list.
2042 *
2043 * Write a formatted xml element with namespace support.
2044 *
2045 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2046 */
2047int
2048xmlTextWriterWriteVFormatElementNS(xmlTextWriterPtr writer,
2049 const xmlChar * prefix,
2050 const xmlChar * name,
2051 const xmlChar * namespaceURI,
2052 const char *format, va_list argptr)
2053{
2054 int rc;
2055 xmlChar *buf;
2056
2057 if (writer == NULL)
2058 return -1;
2059
2060 buf = xmlTextWriterVSprintf(format, argptr);
2061 if (buf == 0)
2062 return 0;
2063
2064 rc = xmlTextWriterWriteElementNS(writer, prefix, name, namespaceURI,
2065 buf);
2066
2067 xmlFree(buf);
2068 return rc;
2069}
2070
2071/**
2072 * xmlTextWriterWriteElementNS:
2073 * @writer: the xmlTextWriterPtr
2074 * @prefix: namespace prefix
2075 * @name: element local name
2076 * @namespaceURI: namespace URI
2077 * @content: element content
2078 *
2079 * Write an xml element with namespace support.
2080 *
2081 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2082 */
2083int
2084xmlTextWriterWriteElementNS(xmlTextWriterPtr writer,
2085 const xmlChar * prefix, const xmlChar * name,
2086 const xmlChar * namespaceURI,
2087 const xmlChar * content)
2088{
2089 int count;
2090 int sum;
2091
2092 if ((writer == NULL) || (name == NULL) || (*name == '\0'))
2093 return -1;
2094
2095 sum = 0;
2096 count =
2097 xmlTextWriterStartElementNS(writer, prefix, name, namespaceURI);
2098 if (count < 0)
2099 return -1;
2100 sum += count;
2101 count = xmlTextWriterWriteString(writer, content);
2102 if (count == -1)
2103 return -1;
2104 sum += count;
2105 count = xmlTextWriterEndElement(writer);
2106 if (count == -1)
2107 return -1;
2108 sum += count;
2109
2110 return sum;
2111}
2112
2113/**
2114 * xmlTextWriterStartPI:
2115 * @writer: the xmlTextWriterPtr
2116 * @target: PI target
2117 *
2118 * Start an xml PI.
2119 *
2120 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2121 */
2122int
2123xmlTextWriterStartPI(xmlTextWriterPtr writer, const xmlChar * target)
2124{
2125 int count;
2126 int sum;
2127 xmlLinkPtr lk;
2128 xmlTextWriterStackEntry *p;
2129
2130 if ((writer == NULL) || (target == NULL) || (*target == '\0'))
2131 return -1;
2132
2133 if (xmlStrcasecmp(target, (const xmlChar *) "xml") == 0) {
2134 xmlGenericError(xmlGenericErrorContext,
2135 "xmlTextWriterStartPI : target name [Xx][Mm][Ll] is reserved for xml standardization!\n");
2136 return -1;
2137 }
2138
2139 sum = 0;
2140 lk = xmlListFront(writer->nodes);
2141 if (lk != 0) {
2142 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2143 if (p != 0) {
2144 switch (p->state) {
2145 case XML_TEXTWRITER_ATTRIBUTE:
2146 count = xmlTextWriterEndAttribute(writer);
2147 if (count < 0)
2148 return -1;
2149 sum += count;
2150 /* fallthrough */
2151 case XML_TEXTWRITER_NAME:
2152 count = xmlOutputBufferWriteString(writer->out, ">");
2153 if (count < 0)
2154 return -1;
2155 sum += count;
2156 p->state = XML_TEXTWRITER_TEXT;
2157 break;
Daniel Veillard10c08c72003-12-09 15:14:26 +00002158 case XML_TEXTWRITER_NONE:
2159 case XML_TEXTWRITER_TEXT:
2160 case XML_TEXTWRITER_DTD:
2161 break;
Daniel Veillard1d211e22003-10-20 22:32:39 +00002162 case XML_TEXTWRITER_PI:
2163 case XML_TEXTWRITER_PI_TEXT:
2164 xmlGenericError(xmlGenericErrorContext,
2165 "xmlTextWriterStartPI : nested PI!\n");
2166 return -1;
2167 default:
2168 return -1;
2169 }
2170 }
2171 }
2172
2173 p = (xmlTextWriterStackEntry *)
2174 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2175 if (p == 0) {
2176 xmlGenericError(xmlGenericErrorContext,
2177 "xmlTextWriterStartPI : out of memory!\n");
2178 return -1;
2179 }
2180
2181 p->name = xmlStrdup(target);
2182 if (p->name == 0) {
2183 xmlGenericError(xmlGenericErrorContext,
2184 "xmlTextWriterStartPI : out of memory!\n");
2185 xmlFree(p);
2186 return -1;
2187 }
2188 p->state = XML_TEXTWRITER_PI;
2189
2190 xmlListPushFront(writer->nodes, p);
2191
2192 count = xmlOutputBufferWriteString(writer->out, "<?");
2193 if (count < 0)
2194 return -1;
2195 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002196 count =
2197 xmlOutputBufferWriteString(writer->out, (const char *) p->name);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002198 if (count < 0)
2199 return -1;
2200 sum += count;
2201
2202 return sum;
2203}
2204
2205/**
2206 * xmlTextWriterEndPI:
2207 * @writer: the xmlTextWriterPtr
2208 *
2209 * End the current xml PI.
2210 *
2211 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2212 */
2213int
2214xmlTextWriterEndPI(xmlTextWriterPtr writer)
2215{
2216 int count;
2217 int sum;
2218 xmlLinkPtr lk;
2219 xmlTextWriterStackEntry *p;
2220
2221 if (writer == NULL)
2222 return -1;
2223
2224 lk = xmlListFront(writer->nodes);
2225 if (lk == 0)
2226 return 0;
2227
2228 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2229 if (p == 0)
2230 return 0;
2231
2232 sum = 0;
2233 switch (p->state) {
2234 case XML_TEXTWRITER_PI:
2235 case XML_TEXTWRITER_PI_TEXT:
2236 count = xmlOutputBufferWriteString(writer->out, "?>");
2237 if (count < 0)
2238 return -1;
2239 sum += count;
2240 break;
2241 default:
2242 return -1;
2243 }
2244
2245 xmlListPopFront(writer->nodes);
2246 return sum;
2247}
2248
2249/**
2250 * xmlTextWriterWriteFormatPI:
2251 * @writer: the xmlTextWriterPtr
2252 * @target: PI target
2253 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002254 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002255 *
2256 * Write a formatted PI.
2257 *
2258 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2259 */
2260int
2261xmlTextWriterWriteFormatPI(xmlTextWriterPtr writer, const xmlChar * target,
2262 const char *format, ...)
2263{
2264 int rc;
2265 va_list ap;
2266
2267 va_start(ap, format);
2268
2269 rc = xmlTextWriterWriteVFormatPI(writer, target, format, ap);
2270
2271 va_end(ap);
2272 return rc;
2273}
2274
2275/**
2276 * xmlTextWriterWriteVFormatPI:
2277 * @writer: the xmlTextWriterPtr
2278 * @target: PI target
2279 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002280 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00002281 *
2282 * Write a formatted xml PI.
2283 *
2284 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2285 */
2286int
2287xmlTextWriterWriteVFormatPI(xmlTextWriterPtr writer,
2288 const xmlChar * target, const char *format,
2289 va_list argptr)
2290{
2291 int rc;
2292 xmlChar *buf;
2293
2294 if (writer == NULL)
2295 return -1;
2296
2297 buf = xmlTextWriterVSprintf(format, argptr);
2298 if (buf == 0)
2299 return 0;
2300
2301 rc = xmlTextWriterWritePI(writer, target, buf);
2302
2303 xmlFree(buf);
2304 return rc;
2305}
2306
2307/**
2308 * xmlTextWriterWritePI:
2309 * @writer: the xmlTextWriterPtr
2310 * @target: PI target
2311 * @content: PI content
2312 *
2313 * Write an xml PI.
2314 *
2315 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2316 */
2317int
2318xmlTextWriterWritePI(xmlTextWriterPtr writer, const xmlChar * target,
2319 const xmlChar * content)
2320{
2321 int count;
2322 int sum;
2323
2324 sum = 0;
2325 count = xmlTextWriterStartPI(writer, target);
2326 if (count == -1)
2327 return -1;
2328 sum += count;
2329 if (content != 0) {
2330 count = xmlTextWriterWriteString(writer, content);
2331 if (count == -1)
2332 return -1;
2333 sum += count;
2334 }
2335 count = xmlTextWriterEndPI(writer);
2336 if (count == -1)
2337 return -1;
2338 sum += count;
2339
2340 return sum;
2341}
2342
2343/**
2344 * xmlTextWriterStartCDATA:
2345 * @writer: the xmlTextWriterPtr
2346 *
2347 * Start an xml CDATA section.
2348 *
2349 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2350 */
2351int
2352xmlTextWriterStartCDATA(xmlTextWriterPtr writer)
2353{
2354 int count;
2355 int sum;
2356 xmlLinkPtr lk;
2357 xmlTextWriterStackEntry *p;
2358
2359 if (writer == NULL)
2360 return -1;
2361
2362 sum = 0;
2363 lk = xmlListFront(writer->nodes);
2364 if (lk != 0) {
2365 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2366 if (p != 0) {
2367 switch (p->state) {
2368 case XML_TEXTWRITER_NONE:
2369 case XML_TEXTWRITER_PI:
2370 case XML_TEXTWRITER_PI_TEXT:
2371 break;
2372 case XML_TEXTWRITER_ATTRIBUTE:
2373 count = xmlTextWriterEndAttribute(writer);
2374 if (count < 0)
2375 return -1;
2376 sum += count;
2377 /* fallthrough */
2378 case XML_TEXTWRITER_NAME:
2379 count = xmlOutputBufferWriteString(writer->out, ">");
2380 if (count < 0)
2381 return -1;
2382 sum += count;
2383 p->state = XML_TEXTWRITER_TEXT;
2384 break;
2385 case XML_TEXTWRITER_CDATA:
2386 xmlGenericError(xmlGenericErrorContext,
2387 "xmlTextWriterStartCDATA : CDATA not allowed in this context!\n");
2388 return -1;
2389 default:
2390 return -1;
2391 }
2392 }
2393 }
2394
2395 p = (xmlTextWriterStackEntry *)
2396 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2397 if (p == 0) {
2398 xmlGenericError(xmlGenericErrorContext,
2399 "xmlTextWriterStartCDATA : out of memory!\n");
2400 return -1;
2401 }
2402
2403 p->name = 0;
2404 p->state = XML_TEXTWRITER_CDATA;
2405
2406 xmlListPushFront(writer->nodes, p);
2407
2408 count = xmlOutputBufferWriteString(writer->out, "<![CDATA[");
2409 if (count < 0)
2410 return -1;
2411 sum += count;
2412
2413 return sum;
2414}
2415
2416/**
2417 * xmlTextWriterEndCDATA:
2418 * @writer: the xmlTextWriterPtr
2419 *
2420 * End an xml CDATA section.
2421 *
2422 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2423 */
2424int
2425xmlTextWriterEndCDATA(xmlTextWriterPtr writer)
2426{
2427 int count;
2428 int sum;
2429 xmlLinkPtr lk;
2430 xmlTextWriterStackEntry *p;
2431
2432 if (writer == NULL)
2433 return -1;
2434
2435 lk = xmlListFront(writer->nodes);
2436 if (lk == 0)
2437 return -1;
2438
2439 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2440 if (p == 0)
2441 return -1;
2442
2443 sum = 0;
2444 switch (p->state) {
2445 case XML_TEXTWRITER_CDATA:
2446 count = xmlOutputBufferWriteString(writer->out, "]]>");
2447 if (count < 0)
2448 return -1;
2449 sum += count;
2450 break;
2451 default:
2452 return -1;
2453 }
2454
2455 xmlListPopFront(writer->nodes);
2456 return sum;
2457}
2458
2459/**
2460 * xmlTextWriterWriteFormatCDATA:
2461 * @writer: the xmlTextWriterPtr
2462 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002463 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002464 *
2465 * Write a formatted xml CDATA.
2466 *
2467 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2468 */
2469int
2470xmlTextWriterWriteFormatCDATA(xmlTextWriterPtr writer, const char *format,
2471 ...)
2472{
2473 int rc;
2474 va_list ap;
2475
2476 va_start(ap, format);
2477
2478 rc = xmlTextWriterWriteVFormatCDATA(writer, format, ap);
2479
2480 va_end(ap);
2481 return rc;
2482}
2483
2484/**
2485 * xmlTextWriterWriteVFormatCDATA:
2486 * @writer: the xmlTextWriterPtr
2487 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002488 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00002489 *
2490 * Write a formatted xml CDATA.
2491 *
2492 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2493 */
2494int
2495xmlTextWriterWriteVFormatCDATA(xmlTextWriterPtr writer, const char *format,
2496 va_list argptr)
2497{
2498 int rc;
2499 xmlChar *buf;
2500
2501 if (writer == NULL)
2502 return -1;
2503
2504 buf = xmlTextWriterVSprintf(format, argptr);
2505 if (buf == 0)
2506 return 0;
2507
2508 rc = xmlTextWriterWriteCDATA(writer, buf);
2509
2510 xmlFree(buf);
2511 return rc;
2512}
2513
2514/**
2515 * xmlTextWriterWriteCDATA:
2516 * @writer: the xmlTextWriterPtr
2517 * @content: CDATA content
2518 *
2519 * Write an xml CDATA.
2520 *
2521 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2522 */
2523int
2524xmlTextWriterWriteCDATA(xmlTextWriterPtr writer, const xmlChar * content)
2525{
2526 int count;
2527 int sum;
2528
2529 sum = 0;
2530 count = xmlTextWriterStartCDATA(writer);
2531 if (count == -1)
2532 return -1;
2533 sum += count;
2534 if (content != 0) {
2535 count = xmlTextWriterWriteString(writer, content);
2536 if (count == -1)
2537 return -1;
2538 sum += count;
2539 }
2540 count = xmlTextWriterEndCDATA(writer);
2541 if (count == -1)
2542 return -1;
2543 sum += count;
2544
2545 return sum;
2546}
2547
2548/**
2549 * xmlTextWriterStartDTD:
2550 * @writer: the xmlTextWriterPtr
2551 * @name: the name of the DTD
2552 * @pubid: the public identifier, which is an alternative to the system identifier
2553 * @sysid: the system identifier, which is the URI of the DTD
2554 *
2555 * Start an xml DTD.
2556 *
2557 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2558 */
2559int
2560xmlTextWriterStartDTD(xmlTextWriterPtr writer,
2561 const xmlChar * name,
2562 const xmlChar * pubid, const xmlChar * sysid)
2563{
2564 int count;
2565 int sum;
2566 xmlLinkPtr lk;
2567 xmlTextWriterStackEntry *p;
2568
2569 if (writer == NULL || name == NULL || *name == '\0')
2570 return -1;
2571
2572 sum = 0;
2573 lk = xmlListFront(writer->nodes);
2574 if (lk != 0) {
2575 xmlGenericError(xmlGenericErrorContext,
2576 "xmlTextWriterStartDTD : DTD allowed only in prolog!\n");
2577 return -1;
2578 }
2579
2580 p = (xmlTextWriterStackEntry *)
2581 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2582 if (p == 0) {
2583 xmlGenericError(xmlGenericErrorContext,
2584 "xmlTextWriterStartDTD : out of memory!\n");
2585 return -1;
2586 }
2587
2588 p->name = xmlStrdup(name);
2589 if (p->name == 0) {
2590 xmlGenericError(xmlGenericErrorContext,
2591 "xmlTextWriterStartDTD : out of memory!\n");
2592 xmlFree(p);
2593 return -1;
2594 }
2595 p->state = XML_TEXTWRITER_DTD;
2596
2597 xmlListPushFront(writer->nodes, p);
2598
2599 count = xmlOutputBufferWriteString(writer->out, "<!DOCTYPE ");
2600 if (count < 0)
2601 return -1;
2602 sum += count;
2603 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
2604 if (count < 0)
2605 return -1;
2606 sum += count;
2607
2608 if (pubid != 0) {
2609 if (sysid == 0) {
2610 xmlGenericError(xmlGenericErrorContext,
2611 "xmlTextWriterStartDTD : system identifier needed!\n");
2612 return -1;
2613 }
2614
2615 count = xmlOutputBufferWriteString(writer->out, " PUBLIC \"");
2616 if (count < 0)
2617 return -1;
2618 sum += count;
2619
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002620 count =
2621 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002622 if (count < 0)
2623 return -1;
2624 sum += count;
2625
2626 count = xmlOutputBufferWriteString(writer->out, "\"");
2627 if (count < 0)
2628 return -1;
2629 sum += count;
2630 }
2631
2632 if (sysid != 0) {
2633 if (pubid == 0) {
2634 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
2635 if (count < 0)
2636 return -1;
2637 sum += count;
2638 }
2639
2640 count = xmlOutputBufferWriteString(writer->out, " \"");
2641 if (count < 0)
2642 return -1;
2643 sum += count;
2644
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002645 count =
2646 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00002647 if (count < 0)
2648 return -1;
2649 sum += count;
2650
2651 count = xmlOutputBufferWriteString(writer->out, "\"");
2652 if (count < 0)
2653 return -1;
2654 sum += count;
2655 }
2656
2657 return sum;
2658}
2659
2660/**
2661 * xmlTextWriterEndDTD:
2662 * @writer: the xmlTextWriterPtr
2663 *
2664 * End an xml DTD.
2665 *
2666 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2667 */
2668int
2669xmlTextWriterEndDTD(xmlTextWriterPtr writer)
2670{
2671 int count;
2672 int sum;
2673 xmlLinkPtr lk;
2674 xmlTextWriterStackEntry *p;
2675
2676 if (writer == NULL)
2677 return -1;
2678
2679 sum = 0;
2680 lk = xmlListFront(writer->nodes);
2681 if (lk == 0)
2682 return -1;
2683
2684 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2685 if (p == 0)
2686 return -1;
2687
2688 switch (p->state) {
2689 case XML_TEXTWRITER_DTD_TEXT:
2690 count = xmlOutputBufferWriteString(writer->out, "]");
2691 if (count < 0)
2692 return -1;
2693 sum += count;
2694 /* fallthrough */
2695 case XML_TEXTWRITER_DTD:
2696 case XML_TEXTWRITER_DTD_ELEM:
2697 case XML_TEXTWRITER_DTD_ATTL:
2698 count = xmlOutputBufferWriteString(writer->out, ">");
2699 if (count < 0)
2700 return -1;
2701 sum += count;
2702 break;
2703 default:
2704 return -1;
2705 }
2706
2707 xmlListPopFront(writer->nodes);
2708 return sum;
2709}
2710
2711/**
2712 * xmlTextWriterWriteFormatDTD:
2713 * @writer: the xmlTextWriterPtr
2714 * @name: the name of the DTD
2715 * @pubid: the public identifier, which is an alternative to the system identifier
2716 * @sysid: the system identifier, which is the URI of the DTD
2717 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002718 * @...: extra parameters for the format
Daniel Veillard1d211e22003-10-20 22:32:39 +00002719 *
2720 * Write a DTD with a formatted markup declarations part.
2721 *
2722 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2723 */
2724int
2725xmlTextWriterWriteFormatDTD(xmlTextWriterPtr writer,
2726 const xmlChar * name,
2727 const xmlChar * pubid,
2728 const xmlChar * sysid, const char *format, ...)
2729{
2730 int rc;
2731 va_list ap;
2732
2733 va_start(ap, format);
2734
2735 rc = xmlTextWriterWriteVFormatDTD(writer, name, pubid, sysid, format,
2736 ap);
2737
2738 va_end(ap);
2739 return rc;
2740}
2741
2742/**
2743 * xmlTextWriterWriteVFormatDTD:
2744 * @writer: the xmlTextWriterPtr
2745 * @name: the name of the DTD
2746 * @pubid: the public identifier, which is an alternative to the system identifier
2747 * @sysid: the system identifier, which is the URI of the DTD
2748 * @format: format string (see printf)
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002749 * @argptr: pointer to the first member of the variable argument list.
Daniel Veillard1d211e22003-10-20 22:32:39 +00002750 *
2751 * Write a DTD with a formatted markup declarations part.
2752 *
2753 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2754 */
2755int
2756xmlTextWriterWriteVFormatDTD(xmlTextWriterPtr writer,
2757 const xmlChar * name,
2758 const xmlChar * pubid,
2759 const xmlChar * sysid,
2760 const char *format, va_list argptr)
2761{
2762 int rc;
2763 xmlChar *buf;
2764
2765 if (writer == NULL)
2766 return -1;
2767
2768 buf = xmlTextWriterVSprintf(format, argptr);
2769 if (buf == 0)
2770 return 0;
2771
2772 rc = xmlTextWriterWriteDTD(writer, name, pubid, sysid, buf);
2773
2774 xmlFree(buf);
2775 return rc;
2776}
2777
2778/**
2779 * xmlTextWriterWriteDTD:
2780 * @writer: the xmlTextWriterPtr
2781 * @name: the name of the DTD
2782 * @pubid: the public identifier, which is an alternative to the system identifier
2783 * @sysid: the system identifier, which is the URI of the DTD
William M. Brackb1d53162003-11-18 06:54:40 +00002784 * @subset: string content of the DTD
Daniel Veillard1d211e22003-10-20 22:32:39 +00002785 *
2786 * Write a DTD.
2787 *
2788 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2789 */
2790int
2791xmlTextWriterWriteDTD(xmlTextWriterPtr writer,
2792 const xmlChar * name,
2793 const xmlChar * pubid,
2794 const xmlChar * sysid, const xmlChar * subset)
2795{
2796 int count;
2797 int sum;
2798
2799 sum = 0;
2800 count = xmlTextWriterStartDTD(writer, name, pubid, sysid);
2801 if (count == -1)
2802 return -1;
2803 sum += count;
2804 if (subset != 0) {
2805 count = xmlTextWriterWriteString(writer, subset);
2806 if (count == -1)
2807 return -1;
2808 sum += count;
2809 }
2810 count = xmlTextWriterEndDTD(writer);
2811 if (count == -1)
2812 return -1;
2813 sum += count;
2814
2815 return sum;
2816}
2817
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002818/**
2819 * xmlTextWriterStartDTDElement:
2820 * @writer: the xmlTextWriterPtr
2821 * @name: the name of the DTD element
2822 *
2823 * Start an xml DTD element.
2824 *
2825 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2826 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00002827int
2828xmlTextWriterStartDTDElement(xmlTextWriterPtr writer, const xmlChar * name)
2829{
2830 int count;
2831 int sum;
2832 xmlLinkPtr lk;
2833 xmlTextWriterStackEntry *p;
2834
2835 if (writer == NULL || name == NULL || *name == '\0')
2836 return -1;
2837
2838 sum = 0;
2839 lk = xmlListFront(writer->nodes);
2840 if (lk == 0) {
2841 return -1;
2842 }
2843
2844 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2845 if (p == 0)
2846 return -1;
2847
2848 switch (p->state) {
2849 case XML_TEXTWRITER_DTD:
2850 count = xmlOutputBufferWriteString(writer->out, " [");
2851 if (count < 0)
2852 return -1;
2853 sum += count;
2854 p->state = XML_TEXTWRITER_DTD_TEXT;
2855 /* fallthrough */
2856 case XML_TEXTWRITER_DTD_TEXT:
2857 break;
2858 case XML_TEXTWRITER_DTD_ELEM:
2859 count = xmlTextWriterEndDTDElement(writer);
2860 if (count < 0)
2861 return -1;
2862 sum += count;
2863 break;
2864 default:
2865 return -1;
2866 }
2867
2868 p = (xmlTextWriterStackEntry *)
2869 xmlMalloc(sizeof(xmlTextWriterStackEntry));
2870 if (p == 0) {
2871 xmlGenericError(xmlGenericErrorContext,
2872 "xmlTextWriterStartDTDElement : out of memory!\n");
2873 return -1;
2874 }
2875
2876 p->name = xmlStrdup(name);
2877 if (p->name == 0) {
2878 xmlGenericError(xmlGenericErrorContext,
2879 "xmlTextWriterStartDTDElement : out of memory!\n");
2880 xmlFree(p);
2881 return -1;
2882 }
2883 p->state = XML_TEXTWRITER_DTD_ELEM;
2884
2885 xmlListPushFront(writer->nodes, p);
2886
2887 count = xmlOutputBufferWriteString(writer->out, "<!ELEMENT ");
2888 if (count < 0)
2889 return -1;
2890 sum += count;
2891 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
2892 if (count < 0)
2893 return -1;
2894 sum += count;
2895
2896 return sum;
2897}
2898
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002899/**
2900 * xmlTextWriterWriteFormatDTDElement:
2901 * @writer: the xmlTextWriterPtr
2902 * @name: the name of the DTD element
2903 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00002904 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002905 *
2906 * Write a formatted DTD element.
2907 *
2908 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2909 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00002910int
2911xmlTextWriterWriteFormatDTDElement(xmlTextWriterPtr writer,
2912 const xmlChar * name,
2913 const char *format, ...)
2914{
2915 int rc;
2916 va_list ap;
2917
2918 va_start(ap, format);
2919
2920 rc = xmlTextWriterWriteVFormatDTDElement(writer, name, format, ap);
2921
2922 va_end(ap);
2923 return rc;
2924}
2925
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002926/**
2927 * xmlTextWriterWriteVFormatDTDElement:
2928 * @writer: the xmlTextWriterPtr
2929 * @name: the name of the DTD element
2930 * @format: format string (see printf)
2931 * @argptr: pointer to the first member of the variable argument list.
2932 *
2933 * Write a formatted DTD element.
2934 *
2935 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2936 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00002937int
2938xmlTextWriterWriteVFormatDTDElement(xmlTextWriterPtr writer,
2939 const xmlChar * name,
2940 const char *format, va_list argptr)
2941{
2942 int rc;
2943 xmlChar *buf;
2944
2945 if (writer == NULL)
2946 return -1;
2947
2948 buf = xmlTextWriterVSprintf(format, argptr);
2949 if (buf == 0)
2950 return 0;
2951
2952 rc = xmlTextWriterWriteDTDElement(writer, name, buf);
2953
2954 xmlFree(buf);
2955 return rc;
2956}
2957
Daniel Veillard5841f0e2003-11-20 11:59:09 +00002958/**
2959 * xmlTextWriterWriteDTDElement:
2960 * @writer: the xmlTextWriterPtr
2961 * @name: the name of the DTD element
2962 * @content: content of the element
2963 *
2964 * Write a DTD element.
2965 *
2966 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2967 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00002968int
2969xmlTextWriterWriteDTDElement(xmlTextWriterPtr writer,
2970 const xmlChar * name, const xmlChar * content)
2971{
2972 int count;
2973 int sum;
2974
2975 if (content == NULL)
2976 return -1;
2977
2978 sum = 0;
2979 count = xmlTextWriterStartDTDElement(writer, name);
2980 if (count == -1)
2981 return -1;
2982 sum += count;
2983
2984 count = xmlTextWriterWriteString(writer, BAD_CAST " ");
2985 if (count == -1)
2986 return -1;
2987 sum += count;
2988 count = xmlTextWriterWriteString(writer, content);
2989 if (count == -1)
2990 return -1;
2991 sum += count;
2992
2993 count = xmlTextWriterEndDTDElement(writer);
2994 if (count == -1)
2995 return -1;
2996 sum += count;
2997
2998 return sum;
2999}
3000
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003001/**
3002 * xmlTextWriterStartDTDAttlist:
3003 * @writer: the xmlTextWriterPtr
3004 * @name: the name of the DTD ATTLIST
3005 *
3006 * Start an xml DTD ATTLIST.
3007 *
3008 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3009 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003010int
3011xmlTextWriterStartDTDAttlist(xmlTextWriterPtr writer, const xmlChar * name)
3012{
3013 int count;
3014 int sum;
3015 xmlLinkPtr lk;
3016 xmlTextWriterStackEntry *p;
3017
3018 if (writer == NULL || name == NULL || *name == '\0')
3019 return -1;
3020
3021 sum = 0;
3022 lk = xmlListFront(writer->nodes);
3023 if (lk == 0) {
3024 return -1;
3025 }
3026
3027 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3028 if (p == 0)
3029 return -1;
3030
3031 switch (p->state) {
3032 case XML_TEXTWRITER_DTD:
3033 count = xmlOutputBufferWriteString(writer->out, " [");
3034 if (count < 0)
3035 return -1;
3036 sum += count;
3037 p->state = XML_TEXTWRITER_DTD_TEXT;
3038 /* fallthrough */
3039 case XML_TEXTWRITER_DTD_TEXT:
3040 break;
3041 case XML_TEXTWRITER_DTD_ELEM:
3042 case XML_TEXTWRITER_DTD_ATTL:
3043 case XML_TEXTWRITER_DTD_ENTY:
3044 count = xmlTextWriterEndDTD(writer);
3045 if (count < 0)
3046 return -1;
3047 sum += count;
3048 break;
3049 default:
3050 return -1;
3051 }
3052
3053 p = (xmlTextWriterStackEntry *)
3054 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3055 if (p == 0) {
3056 xmlGenericError(xmlGenericErrorContext,
3057 "xmlTextWriterStartDTDAttlist : out of memory!\n");
3058 return -1;
3059 }
3060
3061 p->name = xmlStrdup(name);
3062 if (p->name == 0) {
3063 xmlGenericError(xmlGenericErrorContext,
3064 "xmlTextWriterStartDTDAttlist : out of memory!\n");
3065 xmlFree(p);
3066 return -1;
3067 }
3068 p->state = XML_TEXTWRITER_DTD_ATTL;
3069
3070 xmlListPushFront(writer->nodes, p);
3071
3072 count = xmlOutputBufferWriteString(writer->out, "<!ATTLIST ");
3073 if (count < 0)
3074 return -1;
3075 sum += count;
3076 count = xmlOutputBufferWriteString(writer->out, (const char *)name);
3077 if (count < 0)
3078 return -1;
3079 sum += count;
3080
3081 return sum;
3082}
3083
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003084/**
3085 * xmlTextWriterWriteFormatDTDAttlist:
3086 * @writer: the xmlTextWriterPtr
3087 * @name: the name of the DTD ATTLIST
3088 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003089 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003090 *
3091 * Write a formatted DTD ATTLIST.
3092 *
3093 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3094 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003095int
3096xmlTextWriterWriteFormatDTDAttlist(xmlTextWriterPtr writer,
3097 const xmlChar * name,
3098 const char *format, ...)
3099{
3100 int rc;
3101 va_list ap;
3102
3103 va_start(ap, format);
3104
3105 rc = xmlTextWriterWriteVFormatDTDAttlist(writer, name, format, ap);
3106
3107 va_end(ap);
3108 return rc;
3109}
3110
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003111/**
3112 * xmlTextWriterWriteVFormatDTDAttlist:
3113 * @writer: the xmlTextWriterPtr
3114 * @name: the name of the DTD ATTLIST
3115 * @format: format string (see printf)
3116 * @argptr: pointer to the first member of the variable argument list.
3117 *
3118 * Write a formatted DTD ATTLIST.
3119 *
3120 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3121 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003122int
3123xmlTextWriterWriteVFormatDTDAttlist(xmlTextWriterPtr writer,
3124 const xmlChar * name,
3125 const char *format, va_list argptr)
3126{
3127 int rc;
3128 xmlChar *buf;
3129
3130 if (writer == NULL)
3131 return -1;
3132
3133 buf = xmlTextWriterVSprintf(format, argptr);
3134 if (buf == 0)
3135 return 0;
3136
3137 rc = xmlTextWriterWriteDTDAttlist(writer, name, buf);
3138
3139 xmlFree(buf);
3140 return rc;
3141}
3142
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003143/**
3144 * xmlTextWriterWriteDTDAttlist:
3145 * @writer: the xmlTextWriterPtr
3146 * @name: the name of the DTD ATTLIST
3147 * @content: content of the ATTLIST
3148 *
3149 * Write a DTD ATTLIST.
3150 *
3151 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3152 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003153int
3154xmlTextWriterWriteDTDAttlist(xmlTextWriterPtr writer,
3155 const xmlChar * name, const xmlChar * content)
3156{
3157 int count;
3158 int sum;
3159
3160 if (content == NULL)
3161 return -1;
3162
3163 sum = 0;
3164 count = xmlTextWriterStartDTDAttlist(writer, name);
3165 if (count == -1)
3166 return -1;
3167 sum += count;
3168
3169 count = xmlTextWriterWriteString(writer, BAD_CAST " ");
3170 if (count == -1)
3171 return -1;
3172 sum += count;
3173 count = xmlTextWriterWriteString(writer, content);
3174 if (count == -1)
3175 return -1;
3176 sum += count;
3177
3178 count = xmlTextWriterEndDTDAttlist(writer);
3179 if (count == -1)
3180 return -1;
3181 sum += count;
3182
3183 return sum;
3184}
3185
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003186/**
3187 * xmlTextWriterStartDTDEntity:
3188 * @writer: the xmlTextWriterPtr
3189 * @pe: TRUE if this is a parameter entity, FALSE if not
3190 * @name: the name of the DTD ATTLIST
3191 *
3192 * Start an xml DTD ATTLIST.
3193 *
3194 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3195 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003196int
3197xmlTextWriterStartDTDEntity(xmlTextWriterPtr writer,
3198 int pe, const xmlChar * name)
3199{
3200 int count;
3201 int sum;
3202 xmlLinkPtr lk;
3203 xmlTextWriterStackEntry *p;
3204
3205 if (writer == NULL || name == NULL || *name == '\0')
3206 return -1;
3207
3208 sum = 0;
3209 lk = xmlListFront(writer->nodes);
3210 if (lk == 0) {
3211 return -1;
3212 }
3213
3214 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3215 if (p == 0)
3216 return -1;
3217
3218 switch (p->state) {
3219 case XML_TEXTWRITER_DTD:
3220 count = xmlOutputBufferWriteString(writer->out, " [");
3221 if (count < 0)
3222 return -1;
3223 sum += count;
3224 p->state = XML_TEXTWRITER_DTD_TEXT;
3225 /* fallthrough */
3226 case XML_TEXTWRITER_DTD_TEXT:
3227 break;
3228 case XML_TEXTWRITER_DTD_ELEM:
3229 case XML_TEXTWRITER_DTD_ATTL:
3230 case XML_TEXTWRITER_DTD_ENTY:
3231 count = xmlTextWriterEndDTD(writer);
3232 if (count < 0)
3233 return -1;
3234 sum += count;
3235 break;
3236 default:
3237 return -1;
3238 }
3239
3240 p = (xmlTextWriterStackEntry *)
3241 xmlMalloc(sizeof(xmlTextWriterStackEntry));
3242 if (p == 0) {
3243 xmlGenericError(xmlGenericErrorContext,
3244 "xmlTextWriterStartDTDElement : out of memory!\n");
3245 return -1;
3246 }
3247
3248 p->name = xmlStrdup(name);
3249 if (p->name == 0) {
3250 xmlGenericError(xmlGenericErrorContext,
3251 "xmlTextWriterStartDTDElement : out of memory!\n");
3252 xmlFree(p);
3253 return -1;
3254 }
3255 p->state = XML_TEXTWRITER_DTD_ENTY;
3256
3257 xmlListPushFront(writer->nodes, p);
3258
3259 count = xmlOutputBufferWriteString(writer->out, "<!ENTITY ");
3260 if (count < 0)
3261 return -1;
3262 sum += count;
3263
3264 if (pe != 0) {
3265 count = xmlOutputBufferWriteString(writer->out, " % ");
3266 if (count < 0)
3267 return -1;
3268 sum += count;
3269 }
3270
3271 count = xmlOutputBufferWriteString(writer->out, (const char *)name);
3272 if (count < 0)
3273 return -1;
3274 sum += count;
3275
3276 return sum;
3277}
3278
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003279/**
3280 * xmlTextWriterWriteFormatDTDInternalEntity:
3281 * @writer: the xmlTextWriterPtr
3282 * @pe: TRUE if this is a parameter entity, FALSE if not
3283 * @name: the name of the DTD entity
3284 * @format: format string (see printf)
Daniel Veillard1d913862003-11-21 00:28:39 +00003285 * @...: extra parameters for the format
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003286 *
3287 * Write a formatted DTD internal entity.
3288 *
3289 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3290 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003291int
3292xmlTextWriterWriteFormatDTDInternalEntity(xmlTextWriterPtr writer,
3293 int pe,
3294 const xmlChar * name,
3295 const char *format, ...)
3296{
3297 int rc;
3298 va_list ap;
3299
3300 va_start(ap, format);
3301
3302 rc = xmlTextWriterWriteVFormatDTDInternalEntity(writer, pe, name,
3303 format, ap);
3304
3305 va_end(ap);
3306 return rc;
3307}
3308
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003309/**
3310 * xmlTextWriterWriteVFormatDTDInternalEntity:
3311 * @writer: the xmlTextWriterPtr
3312 * @pe: TRUE if this is a parameter entity, FALSE if not
3313 * @name: the name of the DTD entity
3314 * @format: format string (see printf)
3315 * @argptr: pointer to the first member of the variable argument list.
3316 *
3317 * Write a formatted DTD internal entity.
3318 *
3319 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3320 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003321int
3322xmlTextWriterWriteVFormatDTDInternalEntity(xmlTextWriterPtr writer,
3323 int pe,
3324 const xmlChar * name,
3325 const char *format,
3326 va_list argptr)
3327{
3328 int rc;
3329 xmlChar *buf;
3330
3331 if (writer == NULL)
3332 return -1;
3333
3334 buf = xmlTextWriterVSprintf(format, argptr);
3335 if (buf == 0)
3336 return 0;
3337
3338 rc = xmlTextWriterWriteDTDInternalEntity(writer, pe, name, buf);
3339
3340 xmlFree(buf);
3341 return rc;
3342}
3343
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003344/**
3345 * xmlTextWriterWriteDTDEntity:
3346 * @writer: the xmlTextWriterPtr
3347 * @pe: TRUE if this is a parameter entity, FALSE if not
3348 * @name: the name of the DTD entity
3349 * @pubid: the public identifier, which is an alternative to the system identifier
3350 * @sysid: the system identifier, which is the URI of the DTD
3351 * @ndataid: the xml notation name.
3352 * @content: content of the entity
3353 *
3354 * Write a DTD entity.
3355 *
3356 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3357 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003358int
3359xmlTextWriterWriteDTDEntity(xmlTextWriterPtr writer,
3360 int pe,
3361 const xmlChar * name,
3362 const xmlChar * pubid,
3363 const xmlChar * sysid,
3364 const xmlChar * ndataid,
3365 const xmlChar * content)
3366{
3367 if (((content == NULL) && (pubid == NULL) && (sysid == NULL))
3368 || ((content != NULL) && ((pubid != NULL) || (sysid != NULL))))
3369 return -1;
3370 if ((pe != 0) && (ndataid != NULL))
3371 return -1;
3372
3373 if (content != 0)
3374 return xmlTextWriterWriteDTDInternalEntity(writer, pe, name,
3375 content);
3376
3377 return xmlTextWriterWriteDTDExternalEntity(writer, pe, name, pubid,
3378 sysid, ndataid);
3379}
3380
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003381/**
3382 * xmlTextWriterWriteDTDInternalEntity:
3383 * @writer: the xmlTextWriterPtr
3384 * @pe: TRUE if this is a parameter entity, FALSE if not
3385 * @name: the name of the DTD entity
3386 * @content: content of the entity
3387 *
3388 * Write a DTD internal entity.
3389 *
3390 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3391 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003392int
3393xmlTextWriterWriteDTDInternalEntity(xmlTextWriterPtr writer,
3394 int pe,
3395 const xmlChar * name,
3396 const xmlChar * content)
3397{
3398 int count;
3399 int sum;
3400
3401 if ((name == NULL) || (*name == '\0') || (content == NULL))
3402 return -1;
3403
3404 sum = 0;
3405 count = xmlTextWriterStartDTDEntity(writer, pe, name);
3406 if (count == -1)
3407 return -1;
3408 sum += count;
3409
3410 count = xmlTextWriterWriteString(writer, BAD_CAST " ");
3411 if (count == -1)
3412 return -1;
3413 sum += count;
3414 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3415 if (count < 0)
3416 return -1;
3417 sum += count;
3418 count = xmlTextWriterWriteString(writer, content);
3419 if (count == -1)
3420 return -1;
3421 sum += count;
3422 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3423 if (count < 0)
3424 return -1;
3425 sum += count;
3426
3427 count = xmlTextWriterEndDTDEntity(writer);
3428 if (count == -1)
3429 return -1;
3430 sum += count;
3431
3432 return sum;
3433}
3434
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003435/**
3436 * xmlTextWriterWriteDTDExternalEntity:
3437 * @writer: the xmlTextWriterPtr
3438 * @pe: TRUE if this is a parameter entity, FALSE if not
3439 * @name: the name of the DTD entity
3440 * @pubid: the public identifier, which is an alternative to the system identifier
3441 * @sysid: the system identifier, which is the URI of the DTD
3442 * @ndataid: the xml notation name.
3443 *
3444 * Write a DTD internal entity.
3445 *
3446 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3447 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003448int
3449xmlTextWriterWriteDTDExternalEntity(xmlTextWriterPtr writer,
3450 int pe,
3451 const xmlChar * name,
3452 const xmlChar * pubid,
3453 const xmlChar * sysid,
3454 const xmlChar * ndataid)
3455{
3456 int count;
3457 int sum;
3458
3459 if ((name == NULL) || (*name == '\0')
3460 || ((pubid == NULL) && (sysid == NULL)))
3461 return -1;
3462 if ((pe != 0) && (ndataid != NULL))
3463 return -1;
3464
3465 sum = 0;
3466 count = xmlTextWriterStartDTDEntity(writer, pe, name);
3467 if (count == -1)
3468 return -1;
3469 sum += count;
3470
3471 if (pubid != 0) {
3472 if (sysid == 0) {
3473 xmlGenericError(xmlGenericErrorContext,
3474 "xmlTextWriterWriteDTDEntity : system identifier needed!\n");
3475 return -1;
3476 }
3477
3478 count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
3479 if (count < 0)
3480 return -1;
3481 sum += count;
3482
3483 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3484 if (count < 0)
3485 return -1;
3486 sum += count;
3487
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003488 count =
3489 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003490 if (count < 0)
3491 return -1;
3492 sum += count;
3493
3494 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3495 if (count < 0)
3496 return -1;
3497 sum += count;
3498 }
3499
3500 if (sysid != 0) {
3501 if (pubid == 0) {
3502 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
3503 if (count < 0)
3504 return -1;
3505 sum += count;
3506 }
3507
3508 count = xmlOutputBufferWriteString(writer->out, " ");
3509 if (count < 0)
3510 return -1;
3511 sum += count;
3512
3513 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3514 if (count < 0)
3515 return -1;
3516 sum += count;
3517
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003518 count =
3519 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003520 if (count < 0)
3521 return -1;
3522 sum += count;
3523
3524 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3525 if (count < 0)
3526 return -1;
3527 sum += count;
3528 }
3529
3530 if (ndataid != NULL) {
3531 count = xmlOutputBufferWriteString(writer->out, " NDATA ");
3532 if (count < 0)
3533 return -1;
3534 sum += count;
3535
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003536 count =
3537 xmlOutputBufferWriteString(writer->out,
3538 (const char *) ndataid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003539 if (count < 0)
3540 return -1;
3541 sum += count;
3542 }
3543
3544 count = xmlTextWriterEndDTDEntity(writer);
3545 if (count == -1)
3546 return -1;
3547 sum += count;
3548
3549 return sum;
3550}
3551
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003552/**
3553 * xmlTextWriterWriteDTDNotation:
3554 * @writer: the xmlTextWriterPtr
3555 * @name: the name of the xml notation
3556 * @pubid: the public identifier, which is an alternative to the system identifier
3557 * @sysid: the system identifier, which is the URI of the DTD
3558 *
3559 * Write a DTD entity.
3560 *
3561 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3562 */
Daniel Veillard1d211e22003-10-20 22:32:39 +00003563int
3564xmlTextWriterWriteDTDNotation(xmlTextWriterPtr writer,
3565 const xmlChar * name,
3566 const xmlChar * pubid, const xmlChar * sysid)
3567{
3568 int count;
3569 int sum;
3570 xmlLinkPtr lk;
3571 xmlTextWriterStackEntry *p;
3572
3573 if (writer == NULL || name == NULL || *name == '\0')
3574 return -1;
3575
3576 sum = 0;
3577 lk = xmlListFront(writer->nodes);
3578 if (lk == 0) {
3579 return -1;
3580 }
3581
3582 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3583 if (p == 0)
3584 return -1;
3585
3586 switch (p->state) {
3587 case XML_TEXTWRITER_DTD:
3588 count = xmlOutputBufferWriteString(writer->out, " [");
3589 if (count < 0)
3590 return -1;
3591 sum += count;
3592 p->state = XML_TEXTWRITER_DTD_TEXT;
3593 /* fallthrough */
3594 case XML_TEXTWRITER_DTD_TEXT:
3595 break;
3596 case XML_TEXTWRITER_DTD_ELEM:
3597 case XML_TEXTWRITER_DTD_ATTL:
3598 case XML_TEXTWRITER_DTD_ENTY:
3599 count = xmlTextWriterEndDTD(writer);
3600 if (count < 0)
3601 return -1;
3602 sum += count;
3603 break;
3604 default:
3605 return -1;
3606 }
3607
3608 count = xmlOutputBufferWriteString(writer->out, "<!NOTATION ");
3609 if (count < 0)
3610 return -1;
3611 sum += count;
3612 count = xmlOutputBufferWriteString(writer->out, (const char *) name);
3613 if (count < 0)
3614 return -1;
3615 sum += count;
3616
3617 if (pubid != 0) {
3618 count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
3619 if (count < 0)
3620 return -1;
3621 sum += count;
3622 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3623 if (count < 0)
3624 return -1;
3625 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003626 count =
3627 xmlOutputBufferWriteString(writer->out, (const char *) pubid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003628 if (count < 0)
3629 return -1;
3630 sum += count;
3631 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3632 if (count < 0)
3633 return -1;
3634 sum += count;
3635 }
3636
3637 if (sysid != 0) {
3638 if (pubid == 0) {
3639 count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
3640 if (count < 0)
3641 return -1;
3642 sum += count;
3643 }
3644 count = xmlOutputBufferWriteString(writer->out, " ");
3645 if (count < 0)
3646 return -1;
3647 sum += count;
3648 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3649 if (count < 0)
3650 return -1;
3651 sum += count;
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003652 count =
3653 xmlOutputBufferWriteString(writer->out, (const char *) sysid);
Daniel Veillard1d211e22003-10-20 22:32:39 +00003654 if (count < 0)
3655 return -1;
3656 sum += count;
3657 count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3658 if (count < 0)
3659 return -1;
3660 sum += count;
3661 }
3662
3663 count = xmlOutputBufferWriteString(writer->out, ">");
3664 if (count < 0)
3665 return -1;
3666 sum += count;
3667
3668 return sum;
3669}
3670
3671/**
3672 * xmlTextWriterFlush:
3673 * @writer: the xmlTextWriterPtr
3674 *
3675 * Flush the output buffer.
3676 *
3677 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3678 */
3679int
3680xmlTextWriterFlush(xmlTextWriterPtr writer)
3681{
3682 int count;
3683
3684 if (writer == NULL)
3685 return -1;
3686
3687 if (writer->out == NULL)
3688 count = 0;
3689 else
3690 count = xmlOutputBufferFlush(writer->out);
3691
3692 return count;
3693}
3694
3695/**
3696 * misc
3697 */
3698
3699/**
3700 * xmlFreeTextWriterStackEntry:
3701 * @lk: the xmlLinkPtr
3702 *
3703 * Free callback for the xmlList.
3704 */
3705static void
3706xmlFreeTextWriterStackEntry(xmlLinkPtr lk)
3707{
3708 xmlTextWriterStackEntry *p;
3709
3710 p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3711 if (p == 0)
3712 return;
3713
3714 if (p->name != 0)
3715 xmlFree(p->name);
3716 xmlFree(p);
3717}
3718
3719/**
3720 * xmlCmpTextWriterStackEntry:
3721 * @data0: the first data
3722 * @data1: the second data
3723 *
3724 * Compare callback for the xmlList.
3725 *
3726 * Returns -1, 0, 1
3727 */
3728static int
3729xmlCmpTextWriterStackEntry(const void *data0, const void *data1)
3730{
3731 xmlTextWriterStackEntry *p0;
3732 xmlTextWriterStackEntry *p1;
3733
3734 if (data0 == data1)
3735 return 0;
3736
3737 if (data0 == 0)
3738 return -1;
3739
3740 if (data1 == 0)
3741 return 1;
3742
3743 p0 = (xmlTextWriterStackEntry *) data0;
3744 p1 = (xmlTextWriterStackEntry *) data1;
3745
3746 return xmlStrcmp(p0->name, p1->name);
3747}
3748
3749/**
3750 * misc
3751 */
3752
3753/**
3754 * xmlFreeTextWriterNsStackEntry:
3755 * @lk: the xmlLinkPtr
3756 *
3757 * Free callback for the xmlList.
3758 */
3759static void
3760xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk)
3761{
3762 xmlTextWriterNsStackEntry *p;
3763
3764 p = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
3765 if (p == 0)
3766 return;
3767
3768 if (p->prefix != 0)
3769 xmlFree(p->prefix);
3770 if (p->uri != 0)
3771 xmlFree(p->uri);
3772
3773 xmlFree(p);
3774}
3775
3776/**
3777 * xmlCmpTextWriterNsStackEntry:
3778 * @data0: the first data
3779 * @data1: the second data
3780 *
3781 * Compare callback for the xmlList.
3782 *
3783 * Returns -1, 0, 1
3784 */
3785static int
3786xmlCmpTextWriterNsStackEntry(const void *data0, const void *data1)
3787{
3788 xmlTextWriterNsStackEntry *p0;
3789 xmlTextWriterNsStackEntry *p1;
3790 int rc;
3791
3792 if (data0 == data1)
3793 return 0;
3794
3795 if (data0 == 0)
3796 return -1;
3797
3798 if (data1 == 0)
3799 return 1;
3800
3801 p0 = (xmlTextWriterNsStackEntry *) data0;
3802 p1 = (xmlTextWriterNsStackEntry *) data1;
3803
3804 rc = xmlStrcmp(p0->prefix, p1->prefix);
3805
3806 if (rc == 0)
3807 rc = p0->elem == p1->elem;
3808
3809 return rc;
3810}
3811
3812/**
3813 * xmlTextWriterWriteMemCallback:
3814 * @context: the xmlBufferPtr
3815 * @str: the data to write
3816 * @len: the length of the data
3817 *
3818 * Write callback for the xmlOutputBuffer with target xmlBuffer
3819 *
3820 * Returns -1, 0, 1
3821 */
3822static int
3823xmlTextWriterWriteMemCallback(void *context, const xmlChar * str, int len)
3824{
3825 xmlBufferPtr buf = (xmlBufferPtr) context;
3826
3827 xmlBufferAdd(buf, str, len);
3828
3829 return len;
3830}
3831
3832/**
3833 * xmlTextWriterCloseMemCallback:
3834 * @context: the xmlBufferPtr
3835 *
3836 * Close callback for the xmlOutputBuffer with target xmlBuffer
3837 *
3838 * Returns -1, 0, 1
3839 */
3840static int
3841xmlTextWriterCloseMemCallback(void *context ATTRIBUTE_UNUSED)
3842{
3843 return 0;
3844}
3845
3846/**
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003847 * xmlTextWriterWriteDocCallback:
3848 * @context: the xmlBufferPtr
3849 * @str: the data to write
3850 * @len: the length of the data
3851 *
3852 * Write callback for the xmlOutputBuffer with target xmlBuffer
3853 *
3854 * Returns -1, 0, 1
3855 */
3856static int
3857xmlTextWriterWriteDocCallback(void *context, const xmlChar * str, int len)
3858{
3859 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context;
3860 int rc;
3861
Daniel Veillard1d913862003-11-21 00:28:39 +00003862 if ((rc = xmlParseChunk(ctxt, (const char *) str, len, 0)) != 0) {
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003863 xmlGenericError(xmlGenericErrorContext,
3864 "xmlTextWriterWriteDocCallback : XML error %d !\n",
3865 rc);
3866 return -1;
3867 }
3868
3869 return len;
3870}
3871
3872/**
3873 * xmlTextWriterCloseDocCallback:
3874 * @context: the xmlBufferPtr
3875 *
3876 * Close callback for the xmlOutputBuffer with target xmlBuffer
3877 *
3878 * Returns -1, 0, 1
3879 */
3880static int
3881xmlTextWriterCloseDocCallback(void *context)
3882{
3883 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context;
3884 int rc;
3885
3886 if ((rc = xmlParseChunk(ctxt, NULL, 0, 1)) != 0) {
3887 xmlGenericError(xmlGenericErrorContext,
3888 "xmlTextWriterWriteDocCallback : XML error %d !\n",
3889 rc);
3890 return -1;
3891 }
3892
3893 return 0;
3894}
3895
3896/**
Daniel Veillard1d211e22003-10-20 22:32:39 +00003897 * xmlTextWriterVSprintf:
3898 * @format: see printf
3899 * @argptr: pointer to the first member of the variable argument list.
3900 *
3901 * Utility function for formatted output
3902 *
3903 * Returns a new xmlChar buffer with the data or NULL on error. This buffer must be freed.
3904 */
3905static xmlChar *
3906xmlTextWriterVSprintf(const char *format, va_list argptr)
3907{
3908 int size;
3909 int count;
3910 xmlChar *buf;
3911
3912 size = BUFSIZ;
3913 buf = (xmlChar *) xmlMalloc(size);
3914 if (buf == NULL) {
3915 xmlGenericError(xmlGenericErrorContext,
3916 "xmlTextWriterVSprintf : out of memory!\n");
3917 return NULL;
3918 }
3919
3920 while (((count = vsnprintf((char *) buf, size, format, argptr)) < 0)
3921 || (count == size - 1) || (count == size) || (count > size)) {
3922 xmlFree(buf);
3923 size += BUFSIZ;
3924 buf = (xmlChar *) xmlMalloc(size);
3925 if (buf == NULL) {
3926 xmlGenericError(xmlGenericErrorContext,
3927 "xmlTextWriterVSprintf : out of memory!\n");
3928 return NULL;
3929 }
3930 }
3931
3932 return buf;
3933}
3934
Daniel Veillard5841f0e2003-11-20 11:59:09 +00003935/**
3936 * xmlTextWriterStartDocumentCallback:
3937 * @ctx: the user data (XML parser context)
3938 *
3939 * called at the start of document processing.
3940 */
3941static void
3942xmlTextWriterStartDocumentCallback(void *ctx)
3943{
3944 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
3945 xmlDocPtr doc;
3946
3947#ifdef DEBUG_SAX
3948 xmlGenericError(xmlGenericErrorContext, "SAX.startDocument()\n");
3949#endif
3950 if (ctxt->html) {
3951#ifdef LIBXML_HTML_ENABLED
3952 if (ctxt->myDoc == NULL)
3953 ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
3954 if (ctxt->myDoc == NULL) {
3955 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
3956 ctxt->sax->error(ctxt->userData,
3957 "SAX.startDocument(): out of memory\n");
3958 ctxt->errNo = XML_ERR_NO_MEMORY;
3959 ctxt->instate = XML_PARSER_EOF;
3960 ctxt->disableSAX = 1;
3961 return;
3962 }
3963#else
3964 xmlGenericError(xmlGenericErrorContext,
3965 "libxml2 built without HTML support\n");
3966 ctxt->errNo = XML_ERR_INTERNAL_ERROR;
3967 ctxt->instate = XML_PARSER_EOF;
3968 ctxt->disableSAX = 1;
3969 return;
3970#endif
3971 } else {
3972 doc = ctxt->myDoc;
3973 if (doc == NULL)
3974 doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
3975 if (doc != NULL) {
3976 if (doc->children == NULL) {
3977 if (ctxt->encoding != NULL)
3978 doc->encoding = xmlStrdup(ctxt->encoding);
3979 else
3980 doc->encoding = NULL;
3981 doc->standalone = ctxt->standalone;
3982 }
3983 } else {
3984 if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
3985 ctxt->sax->error(ctxt->userData,
3986 "SAX.startDocument(): out of memory\n");
3987 ctxt->errNo = XML_ERR_NO_MEMORY;
3988 ctxt->instate = XML_PARSER_EOF;
3989 ctxt->disableSAX = 1;
3990 return;
3991 }
3992 }
3993 if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) &&
3994 (ctxt->input != NULL) && (ctxt->input->filename != NULL)) {
3995 ctxt->myDoc->URL =
3996 xmlCanonicPath((const xmlChar *) ctxt->input->filename);
3997 if (ctxt->myDoc->URL == NULL)
3998 ctxt->myDoc->URL =
3999 xmlStrdup((const xmlChar *) ctxt->input->filename);
4000 }
4001}
4002
Daniel Veillard2cca4462004-01-02 20:04:23 +00004003/**
4004 * xmlTextWriterSetIndent:
4005 * @writer: the xmlTextWriterPtr
4006 * @indent: do indentation?
4007 *
4008 * Set indentation output. indent = 0 do not indentation. indent > 0 do indentation.
4009 *
4010 * Returns -1 on error or 0 otherwise.
4011 */
4012int
4013xmlTextWriterSetIndent (xmlTextWriterPtr writer, int indent)
4014{
4015 if (indent < 0)
4016 return -1;
4017
4018 writer->indent = indent;
4019 writer->doindent = 1;
4020
4021 return 0;
4022}
4023
4024/**
4025 * xmlTextWriterSetIndentString:
4026 * @writer: the xmlTextWriterPtr
4027 * @str: the xmlChar string
4028 *
4029 * Set string indentation.
4030 *
4031 * Returns -1 on error or 0 otherwise.
4032 */
4033int
4034xmlTextWriterSetIndentString (xmlTextWriterPtr writer, xmlChar *str)
4035{
4036
4037 if (!str)
4038 return -1;
4039
Daniel Veillard4773df22004-01-23 13:15:13 +00004040 if (writer->ichar != NULL)
4041 xmlFree(writer->ichar);
Daniel Veillard2cca4462004-01-02 20:04:23 +00004042 writer->ichar = xmlStrdup (str);
4043
4044 if (!writer->ichar)
4045 return -1;
4046 else
4047 return 0;
4048}
4049
4050/**
4051 * xmlTextWriterWriteIndent:
4052 * @writer: the xmlTextWriterPtr
4053 *
4054 * Write indent string.
4055 *
4056 * Returns -1 on error or the number of strings written.
4057 */
4058static int
4059xmlTextWriterWriteIndent (xmlTextWriterPtr writer)
4060{
4061 int lksize;
4062 int i;
William M. Brack5d4cba42004-01-06 15:19:12 +00004063 int ret = -1; /* just in case of an empty list */
Daniel Veillard2cca4462004-01-02 20:04:23 +00004064
4065 lksize = xmlListSize (writer->nodes);
4066 for (i = 0; i < (lksize-1); i++) {
William M. Brack5d4cba42004-01-06 15:19:12 +00004067 ret = xmlOutputBufferWriteString (writer->out,
4068 (const char *)writer->ichar);
Daniel Veillard2cca4462004-01-02 20:04:23 +00004069 if (ret == -1)
4070 break;
4071 }
4072
4073 return (ret == -1)?ret:i;
4074}
4075
Daniel Veillard1d211e22003-10-20 22:32:39 +00004076#endif