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