Annotation of embedaddon/libxml2/xmlwriter.c, revision 1.1.1.2
1.1 misho 1:
2: /*
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:
11: #define IN_LIBXML
12: #include "libxml.h"
13: #include <string.h>
14:
15: #include <libxml/xmlmemory.h>
16: #include <libxml/parser.h>
17: #include <libxml/uri.h>
18: #include <libxml/HTMLtree.h>
19:
20: #ifdef LIBXML_WRITER_ENABLED
21:
22: #include <libxml/xmlwriter.h>
23:
1.1.1.2 ! misho 24: #include "buf.h"
! 25: #include "enc.h"
! 26: #include "save.h"
! 27:
1.1 misho 28: #define B64LINELEN 72
29: #define B64CRLF "\r\n"
30:
31: /*
32: * The following VA_COPY was coded following an example in
33: * the Samba project. It may not be sufficient for some
34: * esoteric implementations of va_list (i.e. it may need
35: * something involving a memcpy) but (hopefully) will be
36: * sufficient for libxml2.
37: */
38: #ifndef VA_COPY
39: #ifdef HAVE_VA_COPY
40: #define VA_COPY(dest, src) va_copy(dest, src)
41: #else
42: #ifdef HAVE___VA_COPY
43: #define VA_COPY(dest,src) __va_copy(dest, src)
44: #else
45: #define VA_COPY(dest,src) (dest) = (src)
46: #endif
47: #endif
48: #endif
49:
50: /*
51: * Types are kept private
52: */
53: typedef enum {
54: XML_TEXTWRITER_NONE = 0,
55: XML_TEXTWRITER_NAME,
56: XML_TEXTWRITER_ATTRIBUTE,
57: XML_TEXTWRITER_TEXT,
58: XML_TEXTWRITER_PI,
59: XML_TEXTWRITER_PI_TEXT,
60: XML_TEXTWRITER_CDATA,
61: XML_TEXTWRITER_DTD,
62: XML_TEXTWRITER_DTD_TEXT,
63: XML_TEXTWRITER_DTD_ELEM,
64: XML_TEXTWRITER_DTD_ELEM_TEXT,
65: XML_TEXTWRITER_DTD_ATTL,
66: XML_TEXTWRITER_DTD_ATTL_TEXT,
67: XML_TEXTWRITER_DTD_ENTY, /* entity */
68: XML_TEXTWRITER_DTD_ENTY_TEXT,
69: XML_TEXTWRITER_DTD_PENT, /* parameter entity */
70: XML_TEXTWRITER_COMMENT
71: } xmlTextWriterState;
72:
73: typedef struct _xmlTextWriterStackEntry xmlTextWriterStackEntry;
74:
75: struct _xmlTextWriterStackEntry {
76: xmlChar *name;
77: xmlTextWriterState state;
78: };
79:
80: typedef struct _xmlTextWriterNsStackEntry xmlTextWriterNsStackEntry;
81: struct _xmlTextWriterNsStackEntry {
82: xmlChar *prefix;
83: xmlChar *uri;
84: xmlLinkPtr elem;
85: };
86:
87: struct _xmlTextWriter {
88: xmlOutputBufferPtr out; /* output buffer */
89: xmlListPtr nodes; /* element name stack */
90: xmlListPtr nsstack; /* name spaces stack */
91: int level;
92: int indent; /* enable indent */
93: int doindent; /* internal indent flag */
94: xmlChar *ichar; /* indent character */
95: char qchar; /* character used for quoting attribute values */
96: xmlParserCtxtPtr ctxt;
97: int no_doc_free;
98: xmlDocPtr doc;
99: };
100:
101: static void xmlFreeTextWriterStackEntry(xmlLinkPtr lk);
102: static int xmlCmpTextWriterStackEntry(const void *data0,
103: const void *data1);
104: static int xmlTextWriterOutputNSDecl(xmlTextWriterPtr writer);
105: static void xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk);
106: static int xmlCmpTextWriterNsStackEntry(const void *data0,
107: const void *data1);
108: static int xmlTextWriterWriteDocCallback(void *context,
109: const xmlChar * str, int len);
110: static int xmlTextWriterCloseDocCallback(void *context);
111:
112: static xmlChar *xmlTextWriterVSprintf(const char *format, va_list argptr);
113: static int xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len,
114: const unsigned char *data);
115: static void xmlTextWriterStartDocumentCallback(void *ctx);
116: static int xmlTextWriterWriteIndent(xmlTextWriterPtr writer);
117: static int
118: xmlTextWriterHandleStateDependencies(xmlTextWriterPtr writer,
119: xmlTextWriterStackEntry * p);
120:
121: /**
122: * xmlWriterErrMsg:
123: * @ctxt: a writer context
124: * @error: the error number
125: * @msg: the error message
126: *
127: * Handle a writer error
128: */
129: static void
130: xmlWriterErrMsg(xmlTextWriterPtr ctxt, xmlParserErrors error,
131: const char *msg)
132: {
133: if (ctxt != NULL) {
134: __xmlRaiseError(NULL, NULL, NULL, ctxt->ctxt,
135: NULL, XML_FROM_WRITER, error, XML_ERR_FATAL,
136: NULL, 0, NULL, NULL, NULL, 0, 0, "%s", msg);
137: } else {
138: __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_WRITER, error,
139: XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, 0, 0, "%s", msg);
140: }
141: }
142:
143: /**
144: * xmlWriterErrMsgInt:
145: * @ctxt: a writer context
146: * @error: the error number
147: * @msg: the error message
148: * @val: an int
149: *
150: * Handle a writer error
151: */
152: static void
153: xmlWriterErrMsgInt(xmlTextWriterPtr ctxt, xmlParserErrors error,
154: const char *msg, int val)
155: {
156: if (ctxt != NULL) {
157: __xmlRaiseError(NULL, NULL, NULL, ctxt->ctxt,
158: NULL, XML_FROM_WRITER, error, XML_ERR_FATAL,
159: NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
160: } else {
161: __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_WRITER, error,
162: XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
163: }
164: }
165:
166: /**
167: * xmlNewTextWriter:
168: * @out: an xmlOutputBufferPtr
169: *
170: * Create a new xmlNewTextWriter structure using an xmlOutputBufferPtr
171: * NOTE: the @out parameter will be deallocated when the writer is closed
172: * (if the call succeed.)
173: *
174: * Returns the new xmlTextWriterPtr or NULL in case of error
175: */
176: xmlTextWriterPtr
177: xmlNewTextWriter(xmlOutputBufferPtr out)
178: {
179: xmlTextWriterPtr ret;
180:
181: ret = (xmlTextWriterPtr) xmlMalloc(sizeof(xmlTextWriter));
182: if (ret == NULL) {
183: xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
184: "xmlNewTextWriter : out of memory!\n");
185: return NULL;
186: }
187: memset(ret, 0, (size_t) sizeof(xmlTextWriter));
188:
189: ret->nodes = xmlListCreate((xmlListDeallocator)
190: xmlFreeTextWriterStackEntry,
191: (xmlListDataCompare)
192: xmlCmpTextWriterStackEntry);
193: if (ret->nodes == NULL) {
194: xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
195: "xmlNewTextWriter : out of memory!\n");
196: xmlFree(ret);
197: return NULL;
198: }
199:
200: ret->nsstack = xmlListCreate((xmlListDeallocator)
201: xmlFreeTextWriterNsStackEntry,
202: (xmlListDataCompare)
203: xmlCmpTextWriterNsStackEntry);
204: if (ret->nsstack == NULL) {
205: xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
206: "xmlNewTextWriter : out of memory!\n");
207: xmlListDelete(ret->nodes);
208: xmlFree(ret);
209: return NULL;
210: }
211:
212: ret->out = out;
213: ret->ichar = xmlStrdup(BAD_CAST " ");
214: ret->qchar = '"';
215:
216: if (!ret->ichar) {
217: xmlListDelete(ret->nodes);
218: xmlListDelete(ret->nsstack);
219: xmlFree(ret);
220: xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
221: "xmlNewTextWriter : out of memory!\n");
222: return NULL;
223: }
224:
225: ret->doc = xmlNewDoc(NULL);
226:
227: ret->no_doc_free = 0;
228:
229: return ret;
230: }
231:
232: /**
233: * xmlNewTextWriterFilename:
234: * @uri: the URI of the resource for the output
235: * @compression: compress the output?
236: *
237: * Create a new xmlNewTextWriter structure with @uri as output
238: *
239: * Returns the new xmlTextWriterPtr or NULL in case of error
240: */
241: xmlTextWriterPtr
242: xmlNewTextWriterFilename(const char *uri, int compression)
243: {
244: xmlTextWriterPtr ret;
245: xmlOutputBufferPtr out;
246:
247: out = xmlOutputBufferCreateFilename(uri, NULL, compression);
248: if (out == NULL) {
249: xmlWriterErrMsg(NULL, XML_IO_EIO,
250: "xmlNewTextWriterFilename : cannot open uri\n");
251: return NULL;
252: }
253:
254: ret = xmlNewTextWriter(out);
255: if (ret == NULL) {
256: xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
257: "xmlNewTextWriterFilename : out of memory!\n");
258: xmlOutputBufferClose(out);
259: return NULL;
260: }
261:
262: ret->indent = 0;
263: ret->doindent = 0;
264: return ret;
265: }
266:
267: /**
268: * xmlNewTextWriterMemory:
269: * @buf: xmlBufferPtr
270: * @compression: compress the output?
271: *
272: * Create a new xmlNewTextWriter structure with @buf as output
273: * TODO: handle compression
274: *
275: * Returns the new xmlTextWriterPtr or NULL in case of error
276: */
277: xmlTextWriterPtr
278: xmlNewTextWriterMemory(xmlBufferPtr buf, int compression ATTRIBUTE_UNUSED)
279: {
280: xmlTextWriterPtr ret;
281: xmlOutputBufferPtr out;
282:
283: /*::todo handle compression */
284: out = xmlOutputBufferCreateBuffer(buf, NULL);
285:
286: if (out == NULL) {
287: xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
288: "xmlNewTextWriterMemory : out of memory!\n");
289: return NULL;
290: }
291:
292: ret = xmlNewTextWriter(out);
293: if (ret == NULL) {
294: xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
295: "xmlNewTextWriterMemory : out of memory!\n");
296: xmlOutputBufferClose(out);
297: return NULL;
298: }
299:
300: return ret;
301: }
302:
303: /**
304: * xmlNewTextWriterPushParser:
305: * @ctxt: xmlParserCtxtPtr to hold the new XML document tree
306: * @compression: compress the output?
307: *
308: * Create a new xmlNewTextWriter structure with @ctxt as output
309: * NOTE: the @ctxt context will be freed with the resulting writer
310: * (if the call succeeds).
311: * TODO: handle compression
312: *
313: * Returns the new xmlTextWriterPtr or NULL in case of error
314: */
315: xmlTextWriterPtr
316: xmlNewTextWriterPushParser(xmlParserCtxtPtr ctxt,
317: int compression ATTRIBUTE_UNUSED)
318: {
319: xmlTextWriterPtr ret;
320: xmlOutputBufferPtr out;
321:
322: if (ctxt == NULL) {
323: xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
324: "xmlNewTextWriterPushParser : invalid context!\n");
325: return NULL;
326: }
327:
328: out = xmlOutputBufferCreateIO((xmlOutputWriteCallback)
329: xmlTextWriterWriteDocCallback,
330: (xmlOutputCloseCallback)
331: xmlTextWriterCloseDocCallback,
332: (void *) ctxt, NULL);
333: if (out == NULL) {
334: xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
335: "xmlNewTextWriterPushParser : error at xmlOutputBufferCreateIO!\n");
336: return NULL;
337: }
338:
339: ret = xmlNewTextWriter(out);
340: if (ret == NULL) {
341: xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
342: "xmlNewTextWriterPushParser : error at xmlNewTextWriter!\n");
343: xmlOutputBufferClose(out);
344: return NULL;
345: }
346:
347: ret->ctxt = ctxt;
348:
349: return ret;
350: }
351:
352: /**
353: * xmlNewTextWriterDoc:
354: * @doc: address of a xmlDocPtr to hold the new XML document tree
355: * @compression: compress the output?
356: *
357: * Create a new xmlNewTextWriter structure with @*doc as output
358: *
359: * Returns the new xmlTextWriterPtr or NULL in case of error
360: */
361: xmlTextWriterPtr
362: xmlNewTextWriterDoc(xmlDocPtr * doc, int compression)
363: {
364: xmlTextWriterPtr ret;
365: xmlSAXHandler saxHandler;
366: xmlParserCtxtPtr ctxt;
367:
368: memset(&saxHandler, '\0', sizeof(saxHandler));
369: xmlSAX2InitDefaultSAXHandler(&saxHandler, 1);
370: saxHandler.startDocument = xmlTextWriterStartDocumentCallback;
371: saxHandler.startElement = xmlSAX2StartElement;
372: saxHandler.endElement = xmlSAX2EndElement;
373:
374: ctxt = xmlCreatePushParserCtxt(&saxHandler, NULL, NULL, 0, NULL);
375: if (ctxt == NULL) {
376: xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
377: "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\n");
378: return NULL;
379: }
380: /*
381: * For some reason this seems to completely break if node names
382: * are interned.
383: */
384: ctxt->dictNames = 0;
385:
386: ctxt->myDoc = xmlNewDoc(BAD_CAST XML_DEFAULT_VERSION);
387: if (ctxt->myDoc == NULL) {
388: xmlFreeParserCtxt(ctxt);
389: xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
390: "xmlNewTextWriterDoc : error at xmlNewDoc!\n");
391: return NULL;
392: }
393:
394: ret = xmlNewTextWriterPushParser(ctxt, compression);
395: if (ret == NULL) {
396: xmlFreeDoc(ctxt->myDoc);
397: xmlFreeParserCtxt(ctxt);
398: xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
399: "xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n");
400: return NULL;
401: }
402:
403: xmlSetDocCompressMode(ctxt->myDoc, compression);
404:
405: if (doc != NULL) {
406: *doc = ctxt->myDoc;
407: ret->no_doc_free = 1;
408: }
409:
410: return ret;
411: }
412:
413: /**
414: * xmlNewTextWriterTree:
415: * @doc: xmlDocPtr
416: * @node: xmlNodePtr or NULL for doc->children
417: * @compression: compress the output?
418: *
419: * Create a new xmlNewTextWriter structure with @doc as output
420: * starting at @node
421: *
422: * Returns the new xmlTextWriterPtr or NULL in case of error
423: */
424: xmlTextWriterPtr
425: xmlNewTextWriterTree(xmlDocPtr doc, xmlNodePtr node, int compression)
426: {
427: xmlTextWriterPtr ret;
428: xmlSAXHandler saxHandler;
429: xmlParserCtxtPtr ctxt;
430:
431: if (doc == NULL) {
432: xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
433: "xmlNewTextWriterTree : invalid document tree!\n");
434: return NULL;
435: }
436:
437: memset(&saxHandler, '\0', sizeof(saxHandler));
438: xmlSAX2InitDefaultSAXHandler(&saxHandler, 1);
439: saxHandler.startDocument = xmlTextWriterStartDocumentCallback;
440: saxHandler.startElement = xmlSAX2StartElement;
441: saxHandler.endElement = xmlSAX2EndElement;
442:
443: ctxt = xmlCreatePushParserCtxt(&saxHandler, NULL, NULL, 0, NULL);
444: if (ctxt == NULL) {
445: xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
446: "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\n");
447: return NULL;
448: }
449: /*
450: * For some reason this seems to completely break if node names
451: * are interned.
452: */
453: ctxt->dictNames = 0;
454:
455: ret = xmlNewTextWriterPushParser(ctxt, compression);
456: if (ret == NULL) {
457: xmlFreeParserCtxt(ctxt);
458: xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
459: "xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n");
460: return NULL;
461: }
462:
463: ctxt->myDoc = doc;
464: ctxt->node = node;
465: ret->no_doc_free = 1;
466:
467: xmlSetDocCompressMode(doc, compression);
468:
469: return ret;
470: }
471:
472: /**
473: * xmlFreeTextWriter:
474: * @writer: the xmlTextWriterPtr
475: *
476: * Deallocate all the resources associated to the writer
477: */
478: void
479: xmlFreeTextWriter(xmlTextWriterPtr writer)
480: {
481: if (writer == NULL)
482: return;
483:
484: if (writer->out != NULL)
485: xmlOutputBufferClose(writer->out);
486:
487: if (writer->nodes != NULL)
488: xmlListDelete(writer->nodes);
489:
490: if (writer->nsstack != NULL)
491: xmlListDelete(writer->nsstack);
492:
493: if (writer->ctxt != NULL) {
494: if ((writer->ctxt->myDoc != NULL) && (writer->no_doc_free == 0)) {
495: xmlFreeDoc(writer->ctxt->myDoc);
496: writer->ctxt->myDoc = NULL;
497: }
498: xmlFreeParserCtxt(writer->ctxt);
499: }
500:
501: if (writer->doc != NULL)
502: xmlFreeDoc(writer->doc);
503:
504: if (writer->ichar != NULL)
505: xmlFree(writer->ichar);
506: xmlFree(writer);
507: }
508:
509: /**
510: * xmlTextWriterStartDocument:
511: * @writer: the xmlTextWriterPtr
512: * @version: the xml version ("1.0") or NULL for default ("1.0")
513: * @encoding: the encoding or NULL for default
514: * @standalone: "yes" or "no" or NULL for default
515: *
516: * Start a new xml document
517: *
518: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
519: */
520: int
521: xmlTextWriterStartDocument(xmlTextWriterPtr writer, const char *version,
522: const char *encoding, const char *standalone)
523: {
524: int count;
525: int sum;
526: xmlLinkPtr lk;
527: xmlCharEncodingHandlerPtr encoder;
528:
529: if ((writer == NULL) || (writer->out == NULL)) {
530: xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
531: "xmlTextWriterStartDocument : invalid writer!\n");
532: return -1;
533: }
534:
535: lk = xmlListFront(writer->nodes);
536: if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) {
537: xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
538: "xmlTextWriterStartDocument : not allowed in this context!\n");
539: return -1;
540: }
541:
542: encoder = NULL;
543: if (encoding != NULL) {
544: encoder = xmlFindCharEncodingHandler(encoding);
545: if (encoder == NULL) {
546: xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
547: "xmlTextWriterStartDocument : out of memory!\n");
548: return -1;
549: }
550: }
551:
552: writer->out->encoder = encoder;
553: if (encoder != NULL) {
554: if (writer->out->conv == NULL) {
1.1.1.2 ! misho 555: writer->out->conv = xmlBufCreateSize(4000);
1.1 misho 556: }
1.1.1.2 ! misho 557: xmlCharEncOutput(writer->out, 1);
1.1 misho 558: if ((writer->doc != NULL) && (writer->doc->encoding == NULL))
559: writer->doc->encoding = xmlStrdup((xmlChar *)writer->out->encoder->name);
560: } else
561: writer->out->conv = NULL;
562:
563: sum = 0;
564: count = xmlOutputBufferWriteString(writer->out, "<?xml version=");
565: if (count < 0)
566: return -1;
567: sum += count;
568: count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
569: if (count < 0)
570: return -1;
571: sum += count;
572: if (version != 0)
573: count = xmlOutputBufferWriteString(writer->out, version);
574: else
575: count = xmlOutputBufferWriteString(writer->out, "1.0");
576: if (count < 0)
577: return -1;
578: sum += count;
579: count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
580: if (count < 0)
581: return -1;
582: sum += count;
583: if (writer->out->encoder != 0) {
584: count = xmlOutputBufferWriteString(writer->out, " encoding=");
585: if (count < 0)
586: return -1;
587: sum += count;
588: count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
589: if (count < 0)
590: return -1;
591: sum += count;
592: count =
593: xmlOutputBufferWriteString(writer->out,
594: writer->out->encoder->name);
595: if (count < 0)
596: return -1;
597: sum += count;
598: count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
599: if (count < 0)
600: return -1;
601: sum += count;
602: }
603:
604: if (standalone != 0) {
605: count = xmlOutputBufferWriteString(writer->out, " standalone=");
606: if (count < 0)
607: return -1;
608: sum += count;
609: count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
610: if (count < 0)
611: return -1;
612: sum += count;
613: count = xmlOutputBufferWriteString(writer->out, standalone);
614: if (count < 0)
615: return -1;
616: sum += count;
617: count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
618: if (count < 0)
619: return -1;
620: sum += count;
621: }
622:
623: count = xmlOutputBufferWriteString(writer->out, "?>\n");
624: if (count < 0)
625: return -1;
626: sum += count;
627:
628: return sum;
629: }
630:
631: /**
632: * xmlTextWriterEndDocument:
633: * @writer: the xmlTextWriterPtr
634: *
635: * End an xml document. All open elements are closed, and
636: * the content is flushed to the output.
637: *
638: * Returns the bytes written or -1 in case of error
639: */
640: int
641: xmlTextWriterEndDocument(xmlTextWriterPtr writer)
642: {
643: int count;
644: int sum;
645: xmlLinkPtr lk;
646: xmlTextWriterStackEntry *p;
647:
648: if (writer == NULL) {
649: xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
650: "xmlTextWriterEndDocument : invalid writer!\n");
651: return -1;
652: }
653:
654: sum = 0;
655: while ((lk = xmlListFront(writer->nodes)) != NULL) {
656: p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
657: if (p == 0)
658: break;
659: switch (p->state) {
660: case XML_TEXTWRITER_NAME:
661: case XML_TEXTWRITER_ATTRIBUTE:
662: case XML_TEXTWRITER_TEXT:
663: count = xmlTextWriterEndElement(writer);
664: if (count < 0)
665: return -1;
666: sum += count;
667: break;
668: case XML_TEXTWRITER_PI:
669: case XML_TEXTWRITER_PI_TEXT:
670: count = xmlTextWriterEndPI(writer);
671: if (count < 0)
672: return -1;
673: sum += count;
674: break;
675: case XML_TEXTWRITER_CDATA:
676: count = xmlTextWriterEndCDATA(writer);
677: if (count < 0)
678: return -1;
679: sum += count;
680: break;
681: case XML_TEXTWRITER_DTD:
682: case XML_TEXTWRITER_DTD_TEXT:
683: case XML_TEXTWRITER_DTD_ELEM:
684: case XML_TEXTWRITER_DTD_ELEM_TEXT:
685: case XML_TEXTWRITER_DTD_ATTL:
686: case XML_TEXTWRITER_DTD_ATTL_TEXT:
687: case XML_TEXTWRITER_DTD_ENTY:
688: case XML_TEXTWRITER_DTD_ENTY_TEXT:
689: case XML_TEXTWRITER_DTD_PENT:
690: count = xmlTextWriterEndDTD(writer);
691: if (count < 0)
692: return -1;
693: sum += count;
694: break;
695: case XML_TEXTWRITER_COMMENT:
696: count = xmlTextWriterEndComment(writer);
697: if (count < 0)
698: return -1;
699: sum += count;
700: break;
701: default:
702: break;
703: }
704: }
705:
706: if (!writer->indent) {
707: count = xmlOutputBufferWriteString(writer->out, "\n");
708: if (count < 0)
709: return -1;
710: sum += count;
711: }
712:
713: sum += xmlTextWriterFlush(writer);
714:
715: return sum;
716: }
717:
718: /**
719: * xmlTextWriterStartComment:
720: * @writer: the xmlTextWriterPtr
721: *
722: * Start an xml comment.
723: *
724: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
725: */
726: int
727: xmlTextWriterStartComment(xmlTextWriterPtr writer)
728: {
729: int count;
730: int sum;
731: xmlLinkPtr lk;
732: xmlTextWriterStackEntry *p;
733:
734: if (writer == NULL) {
735: xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
736: "xmlTextWriterStartComment : invalid writer!\n");
737: return -1;
738: }
739:
740: sum = 0;
741: lk = xmlListFront(writer->nodes);
742: if (lk != 0) {
743: p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
744: if (p != 0) {
745: switch (p->state) {
746: case XML_TEXTWRITER_TEXT:
747: case XML_TEXTWRITER_NONE:
748: break;
749: case XML_TEXTWRITER_NAME:
750: /* Output namespace declarations */
751: count = xmlTextWriterOutputNSDecl(writer);
752: if (count < 0)
753: return -1;
754: sum += count;
755: count = xmlOutputBufferWriteString(writer->out, ">");
756: if (count < 0)
757: return -1;
758: sum += count;
759: if (writer->indent) {
760: count =
761: xmlOutputBufferWriteString(writer->out, "\n");
762: if (count < 0)
763: return -1;
764: sum += count;
765: }
766: p->state = XML_TEXTWRITER_TEXT;
767: break;
768: default:
769: return -1;
770: }
771: }
772: }
773:
774: p = (xmlTextWriterStackEntry *)
775: xmlMalloc(sizeof(xmlTextWriterStackEntry));
776: if (p == 0) {
777: xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
778: "xmlTextWriterStartElement : out of memory!\n");
779: return -1;
780: }
781:
782: p->name = NULL;
783: p->state = XML_TEXTWRITER_COMMENT;
784:
785: xmlListPushFront(writer->nodes, p);
786:
787: if (writer->indent) {
788: count = xmlTextWriterWriteIndent(writer);
789: if (count < 0)
790: return -1;
791: sum += count;
792: }
793:
794: count = xmlOutputBufferWriteString(writer->out, "<!--");
795: if (count < 0)
796: return -1;
797: sum += count;
798:
799: return sum;
800: }
801:
802: /**
803: * xmlTextWriterEndComment:
804: * @writer: the xmlTextWriterPtr
805: *
806: * End the current xml coment.
807: *
808: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
809: */
810: int
811: xmlTextWriterEndComment(xmlTextWriterPtr writer)
812: {
813: int count;
814: int sum;
815: xmlLinkPtr lk;
816: xmlTextWriterStackEntry *p;
817:
818: if (writer == NULL) {
819: xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
820: "xmlTextWriterEndComment : invalid writer!\n");
821: return -1;
822: }
823:
824: lk = xmlListFront(writer->nodes);
825: if (lk == 0) {
826: xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
827: "xmlTextWriterEndComment : not allowed in this context!\n");
828: return -1;
829: }
830:
831: p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
832: if (p == 0)
833: return -1;
834:
835: sum = 0;
836: switch (p->state) {
837: case XML_TEXTWRITER_COMMENT:
838: count = xmlOutputBufferWriteString(writer->out, "-->");
839: if (count < 0)
840: return -1;
841: sum += count;
842: break;
843: default:
844: return -1;
845: }
846:
847: if (writer->indent) {
848: count = xmlOutputBufferWriteString(writer->out, "\n");
849: if (count < 0)
850: return -1;
851: sum += count;
852: }
853:
854: xmlListPopFront(writer->nodes);
855: return sum;
856: }
857:
858: /**
859: * xmlTextWriterWriteFormatComment:
860: * @writer: the xmlTextWriterPtr
861: * @format: format string (see printf)
862: * @...: extra parameters for the format
863: *
864: * Write an xml comment.
865: *
866: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
867: */
868: int XMLCDECL
869: xmlTextWriterWriteFormatComment(xmlTextWriterPtr writer,
870: const char *format, ...)
871: {
872: int rc;
873: va_list ap;
874:
875: va_start(ap, format);
876:
877: rc = xmlTextWriterWriteVFormatComment(writer, format, ap);
878:
879: va_end(ap);
880: return rc;
881: }
882:
883: /**
884: * xmlTextWriterWriteVFormatComment:
885: * @writer: the xmlTextWriterPtr
886: * @format: format string (see printf)
887: * @argptr: pointer to the first member of the variable argument list.
888: *
889: * Write an xml comment.
890: *
891: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
892: */
893: int
894: xmlTextWriterWriteVFormatComment(xmlTextWriterPtr writer,
895: const char *format, va_list argptr)
896: {
897: int rc;
898: xmlChar *buf;
899:
900: if (writer == NULL) {
901: xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
902: "xmlTextWriterWriteVFormatComment : invalid writer!\n");
903: return -1;
904: }
905:
906: buf = xmlTextWriterVSprintf(format, argptr);
907: if (buf == NULL)
908: return -1;
909:
910: rc = xmlTextWriterWriteComment(writer, buf);
911:
912: xmlFree(buf);
913: return rc;
914: }
915:
916: /**
917: * xmlTextWriterWriteComment:
918: * @writer: the xmlTextWriterPtr
919: * @content: comment string
920: *
921: * Write an xml comment.
922: *
923: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
924: */
925: int
926: xmlTextWriterWriteComment(xmlTextWriterPtr writer, const xmlChar * content)
927: {
928: int count;
929: int sum;
930:
931: sum = 0;
932: count = xmlTextWriterStartComment(writer);
933: if (count < 0)
934: return -1;
935: sum += count;
936: count = xmlTextWriterWriteString(writer, content);
937: if (count < 0)
938: return -1;
939: sum += count;
940: count = xmlTextWriterEndComment(writer);
941: if (count < 0)
942: return -1;
943: sum += count;
944:
945: return sum;
946: }
947:
948: /**
949: * xmlTextWriterStartElement:
950: * @writer: the xmlTextWriterPtr
951: * @name: element name
952: *
953: * Start an xml element.
954: *
955: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
956: */
957: int
958: xmlTextWriterStartElement(xmlTextWriterPtr writer, const xmlChar * name)
959: {
960: int count;
961: int sum;
962: xmlLinkPtr lk;
963: xmlTextWriterStackEntry *p;
964:
965: if ((writer == NULL) || (name == NULL) || (*name == '\0'))
966: return -1;
967:
968: sum = 0;
969: lk = xmlListFront(writer->nodes);
970: if (lk != 0) {
971: p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
972: if (p != 0) {
973: switch (p->state) {
974: case XML_TEXTWRITER_PI:
975: case XML_TEXTWRITER_PI_TEXT:
976: return -1;
977: case XML_TEXTWRITER_NONE:
978: break;
979: case XML_TEXTWRITER_ATTRIBUTE:
980: count = xmlTextWriterEndAttribute(writer);
981: if (count < 0)
982: return -1;
983: sum += count;
984: /* fallthrough */
985: case XML_TEXTWRITER_NAME:
986: /* Output namespace declarations */
987: count = xmlTextWriterOutputNSDecl(writer);
988: if (count < 0)
989: return -1;
990: sum += count;
991: count = xmlOutputBufferWriteString(writer->out, ">");
992: if (count < 0)
993: return -1;
994: sum += count;
995: if (writer->indent)
996: count =
997: xmlOutputBufferWriteString(writer->out, "\n");
998: p->state = XML_TEXTWRITER_TEXT;
999: break;
1000: default:
1001: break;
1002: }
1003: }
1004: }
1005:
1006: p = (xmlTextWriterStackEntry *)
1007: xmlMalloc(sizeof(xmlTextWriterStackEntry));
1008: if (p == 0) {
1009: xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
1010: "xmlTextWriterStartElement : out of memory!\n");
1011: return -1;
1012: }
1013:
1014: p->name = xmlStrdup(name);
1015: if (p->name == 0) {
1016: xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
1017: "xmlTextWriterStartElement : out of memory!\n");
1018: xmlFree(p);
1019: return -1;
1020: }
1021: p->state = XML_TEXTWRITER_NAME;
1022:
1023: xmlListPushFront(writer->nodes, p);
1024:
1025: if (writer->indent) {
1026: count = xmlTextWriterWriteIndent(writer);
1027: sum += count;
1028: }
1029:
1030: count = xmlOutputBufferWriteString(writer->out, "<");
1031: if (count < 0)
1032: return -1;
1033: sum += count;
1034: count =
1035: xmlOutputBufferWriteString(writer->out, (const char *) p->name);
1036: if (count < 0)
1037: return -1;
1038: sum += count;
1039:
1040: return sum;
1041: }
1042:
1043: /**
1044: * xmlTextWriterStartElementNS:
1045: * @writer: the xmlTextWriterPtr
1046: * @prefix: namespace prefix or NULL
1047: * @name: element local name
1048: * @namespaceURI: namespace URI or NULL
1049: *
1050: * Start an xml element with namespace support.
1051: *
1052: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1053: */
1054: int
1055: xmlTextWriterStartElementNS(xmlTextWriterPtr writer,
1056: const xmlChar * prefix, const xmlChar * name,
1057: const xmlChar * namespaceURI)
1058: {
1059: int count;
1060: int sum;
1061: xmlChar *buf;
1062:
1063: if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1064: return -1;
1065:
1066: buf = NULL;
1067: if (prefix != 0) {
1068: buf = xmlStrdup(prefix);
1069: buf = xmlStrcat(buf, BAD_CAST ":");
1070: }
1071: buf = xmlStrcat(buf, name);
1072:
1073: sum = 0;
1074: count = xmlTextWriterStartElement(writer, buf);
1075: xmlFree(buf);
1076: if (count < 0)
1077: return -1;
1078: sum += count;
1079:
1080: if (namespaceURI != 0) {
1.1.1.2 ! misho 1081: xmlTextWriterNsStackEntry *p = (xmlTextWriterNsStackEntry *)
1.1 misho 1082: xmlMalloc(sizeof(xmlTextWriterNsStackEntry));
1083: if (p == 0) {
1.1.1.2 ! misho 1084: xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
1.1 misho 1085: "xmlTextWriterStartElementNS : out of memory!\n");
1086: return -1;
1087: }
1088:
1089: buf = xmlStrdup(BAD_CAST "xmlns");
1090: if (prefix != 0) {
1091: buf = xmlStrcat(buf, BAD_CAST ":");
1092: buf = xmlStrcat(buf, prefix);
1093: }
1094:
1095: p->prefix = buf;
1096: p->uri = xmlStrdup(namespaceURI);
1097: if (p->uri == 0) {
1098: xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
1099: "xmlTextWriterStartElementNS : out of memory!\n");
1100: xmlFree(p);
1101: return -1;
1102: }
1103: p->elem = xmlListFront(writer->nodes);
1104:
1105: xmlListPushFront(writer->nsstack, p);
1106: }
1107:
1108: return sum;
1109: }
1110:
1111: /**
1112: * xmlTextWriterEndElement:
1113: * @writer: the xmlTextWriterPtr
1114: *
1115: * End the current xml element.
1116: *
1117: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1118: */
1119: int
1120: xmlTextWriterEndElement(xmlTextWriterPtr writer)
1121: {
1122: int count;
1123: int sum;
1124: xmlLinkPtr lk;
1125: xmlTextWriterStackEntry *p;
1126:
1127: if (writer == NULL)
1128: return -1;
1129:
1130: lk = xmlListFront(writer->nodes);
1131: if (lk == 0) {
1132: xmlListDelete(writer->nsstack);
1133: writer->nsstack = NULL;
1134: return -1;
1135: }
1136:
1137: p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1138: if (p == 0) {
1139: xmlListDelete(writer->nsstack);
1140: writer->nsstack = NULL;
1141: return -1;
1142: }
1143:
1144: sum = 0;
1145: switch (p->state) {
1146: case XML_TEXTWRITER_ATTRIBUTE:
1147: count = xmlTextWriterEndAttribute(writer);
1148: if (count < 0) {
1149: xmlListDelete(writer->nsstack);
1150: writer->nsstack = NULL;
1151: return -1;
1152: }
1153: sum += count;
1154: /* fallthrough */
1155: case XML_TEXTWRITER_NAME:
1156: /* Output namespace declarations */
1157: count = xmlTextWriterOutputNSDecl(writer);
1158: if (count < 0)
1159: return -1;
1160: sum += count;
1161:
1162: if (writer->indent) /* next element needs indent */
1163: writer->doindent = 1;
1164: count = xmlOutputBufferWriteString(writer->out, "/>");
1165: if (count < 0)
1166: return -1;
1167: sum += count;
1168: break;
1169: case XML_TEXTWRITER_TEXT:
1170: if ((writer->indent) && (writer->doindent)) {
1171: count = xmlTextWriterWriteIndent(writer);
1172: sum += count;
1173: writer->doindent = 1;
1174: } else
1175: writer->doindent = 1;
1176: count = xmlOutputBufferWriteString(writer->out, "</");
1177: if (count < 0)
1178: return -1;
1179: sum += count;
1180: count = xmlOutputBufferWriteString(writer->out,
1181: (const char *) p->name);
1182: if (count < 0)
1183: return -1;
1184: sum += count;
1185: count = xmlOutputBufferWriteString(writer->out, ">");
1186: if (count < 0)
1187: return -1;
1188: sum += count;
1189: break;
1190: default:
1191: return -1;
1192: }
1193:
1194: if (writer->indent) {
1195: count = xmlOutputBufferWriteString(writer->out, "\n");
1196: sum += count;
1197: }
1198:
1199: xmlListPopFront(writer->nodes);
1200: return sum;
1201: }
1202:
1203: /**
1204: * xmlTextWriterFullEndElement:
1205: * @writer: the xmlTextWriterPtr
1206: *
1207: * End the current xml element. Writes an end tag even if the element is empty
1208: *
1209: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1210: */
1211: int
1212: xmlTextWriterFullEndElement(xmlTextWriterPtr writer)
1213: {
1214: int count;
1215: int sum;
1216: xmlLinkPtr lk;
1217: xmlTextWriterStackEntry *p;
1218:
1219: if (writer == NULL)
1220: return -1;
1221:
1222: lk = xmlListFront(writer->nodes);
1223: if (lk == 0)
1224: return -1;
1225:
1226: p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1227: if (p == 0)
1228: return -1;
1229:
1230: sum = 0;
1231: switch (p->state) {
1232: case XML_TEXTWRITER_ATTRIBUTE:
1233: count = xmlTextWriterEndAttribute(writer);
1234: if (count < 0)
1235: return -1;
1236: sum += count;
1237: /* fallthrough */
1238: case XML_TEXTWRITER_NAME:
1239: /* Output namespace declarations */
1240: count = xmlTextWriterOutputNSDecl(writer);
1241: if (count < 0)
1242: return -1;
1243: sum += count;
1244:
1245: count = xmlOutputBufferWriteString(writer->out, ">");
1246: if (count < 0)
1247: return -1;
1248: sum += count;
1249: if (writer->indent)
1250: writer->doindent = 0;
1251: /* fallthrough */
1252: case XML_TEXTWRITER_TEXT:
1253: if ((writer->indent) && (writer->doindent)) {
1254: count = xmlTextWriterWriteIndent(writer);
1255: sum += count;
1256: writer->doindent = 1;
1257: } else
1258: writer->doindent = 1;
1259: count = xmlOutputBufferWriteString(writer->out, "</");
1260: if (count < 0)
1261: return -1;
1262: sum += count;
1263: count = xmlOutputBufferWriteString(writer->out,
1264: (const char *) p->name);
1265: if (count < 0)
1266: return -1;
1267: sum += count;
1268: count = xmlOutputBufferWriteString(writer->out, ">");
1269: if (count < 0)
1270: return -1;
1271: sum += count;
1272: break;
1273: default:
1274: return -1;
1275: }
1276:
1277: if (writer->indent) {
1278: count = xmlOutputBufferWriteString(writer->out, "\n");
1279: sum += count;
1280: }
1281:
1282: xmlListPopFront(writer->nodes);
1283: return sum;
1284: }
1285:
1286: /**
1287: * xmlTextWriterWriteFormatRaw:
1288: * @writer: the xmlTextWriterPtr
1289: * @format: format string (see printf)
1290: * @...: extra parameters for the format
1291: *
1292: * Write a formatted raw xml text.
1293: *
1294: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1295: */
1296: int XMLCDECL
1297: xmlTextWriterWriteFormatRaw(xmlTextWriterPtr writer, const char *format,
1298: ...)
1299: {
1300: int rc;
1301: va_list ap;
1302:
1303: va_start(ap, format);
1304:
1305: rc = xmlTextWriterWriteVFormatRaw(writer, format, ap);
1306:
1307: va_end(ap);
1308: return rc;
1309: }
1310:
1311: /**
1312: * xmlTextWriterWriteVFormatRaw:
1313: * @writer: the xmlTextWriterPtr
1314: * @format: format string (see printf)
1315: * @argptr: pointer to the first member of the variable argument list.
1316: *
1317: * Write a formatted raw xml text.
1318: *
1319: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1320: */
1321: int
1322: xmlTextWriterWriteVFormatRaw(xmlTextWriterPtr writer, const char *format,
1323: va_list argptr)
1324: {
1325: int rc;
1326: xmlChar *buf;
1327:
1328: if (writer == NULL)
1329: return -1;
1330:
1331: buf = xmlTextWriterVSprintf(format, argptr);
1332: if (buf == NULL)
1333: return -1;
1334:
1335: rc = xmlTextWriterWriteRaw(writer, buf);
1336:
1337: xmlFree(buf);
1338: return rc;
1339: }
1340:
1341: /**
1342: * xmlTextWriterWriteRawLen:
1343: * @writer: the xmlTextWriterPtr
1344: * @content: text string
1345: * @len: length of the text string
1346: *
1347: * Write an xml text.
1348: * TODO: what about entities and special chars??
1349: *
1350: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1351: */
1352: int
1353: xmlTextWriterWriteRawLen(xmlTextWriterPtr writer, const xmlChar * content,
1354: int len)
1355: {
1356: int count;
1357: int sum;
1358: xmlLinkPtr lk;
1359: xmlTextWriterStackEntry *p;
1360:
1361: if (writer == NULL) {
1362: xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
1363: "xmlTextWriterWriteRawLen : invalid writer!\n");
1364: return -1;
1365: }
1366:
1367: if ((content == NULL) || (len < 0)) {
1368: xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
1369: "xmlTextWriterWriteRawLen : invalid content!\n");
1370: return -1;
1371: }
1372:
1373: sum = 0;
1374: lk = xmlListFront(writer->nodes);
1375: if (lk != 0) {
1376: p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1377: count = xmlTextWriterHandleStateDependencies(writer, p);
1378: if (count < 0)
1379: return -1;
1380: sum += count;
1381: }
1382:
1383: if (writer->indent)
1384: writer->doindent = 0;
1385:
1386: if (content != NULL) {
1387: count =
1388: xmlOutputBufferWrite(writer->out, len, (const char *) content);
1389: if (count < 0)
1390: return -1;
1391: sum += count;
1392: }
1393:
1394: return sum;
1395: }
1396:
1397: /**
1398: * xmlTextWriterWriteRaw:
1399: * @writer: the xmlTextWriterPtr
1400: * @content: text string
1401: *
1402: * Write a raw xml text.
1403: *
1404: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1405: */
1406: int
1407: xmlTextWriterWriteRaw(xmlTextWriterPtr writer, const xmlChar * content)
1408: {
1409: return xmlTextWriterWriteRawLen(writer, content, xmlStrlen(content));
1410: }
1411:
1412: /**
1413: * xmlTextWriterWriteFormatString:
1414: * @writer: the xmlTextWriterPtr
1415: * @format: format string (see printf)
1416: * @...: extra parameters for the format
1417: *
1418: * Write a formatted xml text.
1419: *
1420: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1421: */
1422: int XMLCDECL
1423: xmlTextWriterWriteFormatString(xmlTextWriterPtr writer, const char *format,
1424: ...)
1425: {
1426: int rc;
1427: va_list ap;
1428:
1429: if ((writer == NULL) || (format == NULL))
1430: return -1;
1431:
1432: va_start(ap, format);
1433:
1434: rc = xmlTextWriterWriteVFormatString(writer, format, ap);
1435:
1436: va_end(ap);
1437: return rc;
1438: }
1439:
1440: /**
1441: * xmlTextWriterWriteVFormatString:
1442: * @writer: the xmlTextWriterPtr
1443: * @format: format string (see printf)
1444: * @argptr: pointer to the first member of the variable argument list.
1445: *
1446: * Write a formatted xml text.
1447: *
1448: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1449: */
1450: int
1451: xmlTextWriterWriteVFormatString(xmlTextWriterPtr writer,
1452: const char *format, va_list argptr)
1453: {
1454: int rc;
1455: xmlChar *buf;
1456:
1457: if ((writer == NULL) || (format == NULL))
1458: return -1;
1459:
1460: buf = xmlTextWriterVSprintf(format, argptr);
1461: if (buf == NULL)
1462: return -1;
1463:
1464: rc = xmlTextWriterWriteString(writer, buf);
1465:
1466: xmlFree(buf);
1467: return rc;
1468: }
1469:
1470: /**
1471: * xmlTextWriterWriteString:
1472: * @writer: the xmlTextWriterPtr
1473: * @content: text string
1474: *
1475: * Write an xml text.
1476: *
1477: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1478: */
1479: int
1480: xmlTextWriterWriteString(xmlTextWriterPtr writer, const xmlChar * content)
1481: {
1482: int count;
1483: int sum;
1484: xmlLinkPtr lk;
1485: xmlTextWriterStackEntry *p;
1486: xmlChar *buf;
1487:
1488: if ((writer == NULL) || (content == NULL))
1489: return -1;
1490:
1491: sum = 0;
1492: buf = (xmlChar *) content;
1493: lk = xmlListFront(writer->nodes);
1494: if (lk != 0) {
1495: p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1496: if (p != 0) {
1497: switch (p->state) {
1498: case XML_TEXTWRITER_NAME:
1499: case XML_TEXTWRITER_TEXT:
1500: #if 0
1501: buf = NULL;
1502: xmlOutputBufferWriteEscape(writer->out, content, NULL);
1503: #endif
1504: buf = xmlEncodeSpecialChars(NULL, content);
1505: break;
1506: case XML_TEXTWRITER_ATTRIBUTE:
1507: buf = NULL;
1.1.1.2 ! misho 1508: xmlBufAttrSerializeTxtContent(writer->out->buffer,
! 1509: writer->doc, NULL, content);
1.1 misho 1510: break;
1511: default:
1512: break;
1513: }
1514: }
1515: }
1516:
1517: if (buf != NULL) {
1518: count = xmlTextWriterWriteRaw(writer, buf);
1519:
1520: if (buf != content) /* buf was allocated by us, so free it */
1521: xmlFree(buf);
1522:
1523: if (count < 0)
1524: return -1;
1525: sum += count;
1526: }
1527:
1528: return sum;
1529: }
1530:
1531: /**
1532: * xmlOutputBufferWriteBase64:
1533: * @out: the xmlOutputBufferPtr
1534: * @data: binary data
1535: * @len: the number of bytes to encode
1536: *
1537: * Write base64 encoded data to an xmlOutputBuffer.
1538: * Adapted from John Walker's base64.c (http://www.fourmilab.ch/).
1539: *
1540: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1541: */
1542: static int
1543: xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len,
1544: const unsigned char *data)
1545: {
1546: static unsigned char dtable[64] =
1547: {'A','B','C','D','E','F','G','H','I','J','K','L','M',
1548: 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
1549: 'a','b','c','d','e','f','g','h','i','j','k','l','m',
1550: 'n','o','p','q','r','s','t','u','v','w','x','y','z',
1551: '0','1','2','3','4','5','6','7','8','9','+','/'};
1552:
1553: int i;
1554: int linelen;
1555: int count;
1556: int sum;
1557:
1558: if ((out == NULL) || (len < 0) || (data == NULL))
1559: return(-1);
1560:
1561: linelen = 0;
1562: sum = 0;
1563:
1564: i = 0;
1565: while (1) {
1566: unsigned char igroup[3];
1567: unsigned char ogroup[4];
1568: int c;
1569: int n;
1570:
1571: igroup[0] = igroup[1] = igroup[2] = 0;
1572: for (n = 0; n < 3 && i < len; n++, i++) {
1573: c = data[i];
1574: igroup[n] = (unsigned char) c;
1575: }
1576:
1577: if (n > 0) {
1578: ogroup[0] = dtable[igroup[0] >> 2];
1579: ogroup[1] = dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)];
1580: ogroup[2] =
1581: dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)];
1582: ogroup[3] = dtable[igroup[2] & 0x3F];
1583:
1584: if (n < 3) {
1585: ogroup[3] = '=';
1586: if (n < 2) {
1587: ogroup[2] = '=';
1588: }
1589: }
1590:
1591: if (linelen >= B64LINELEN) {
1592: count = xmlOutputBufferWrite(out, 2, B64CRLF);
1593: if (count == -1)
1594: return -1;
1595: sum += count;
1596: linelen = 0;
1597: }
1598: count = xmlOutputBufferWrite(out, 4, (const char *) ogroup);
1599: if (count == -1)
1600: return -1;
1601: sum += count;
1602:
1603: linelen += 4;
1604: }
1605:
1606: if (i >= len)
1607: break;
1608: }
1609:
1610: return sum;
1611: }
1612:
1613: /**
1614: * xmlTextWriterWriteBase64:
1615: * @writer: the xmlTextWriterPtr
1616: * @data: binary data
1617: * @start: the position within the data of the first byte to encode
1618: * @len: the number of bytes to encode
1619: *
1620: * Write an base64 encoded xml text.
1621: *
1622: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1623: */
1624: int
1625: xmlTextWriterWriteBase64(xmlTextWriterPtr writer, const char *data,
1626: int start, int len)
1627: {
1628: int count;
1629: int sum;
1630: xmlLinkPtr lk;
1631: xmlTextWriterStackEntry *p;
1632:
1633: if ((writer == NULL) || (data == NULL) || (start < 0) || (len < 0))
1634: return -1;
1635:
1636: sum = 0;
1637: lk = xmlListFront(writer->nodes);
1638: if (lk != 0) {
1639: p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1640: if (p != 0) {
1641: count = xmlTextWriterHandleStateDependencies(writer, p);
1642: if (count < 0)
1643: return -1;
1644: sum += count;
1645: }
1646: }
1647:
1648: if (writer->indent)
1649: writer->doindent = 0;
1650:
1651: count =
1652: xmlOutputBufferWriteBase64(writer->out, len,
1653: (unsigned char *) data + start);
1654: if (count < 0)
1655: return -1;
1656: sum += count;
1657:
1658: return sum;
1659: }
1660:
1661: /**
1662: * xmlOutputBufferWriteBinHex:
1663: * @out: the xmlOutputBufferPtr
1664: * @data: binary data
1665: * @len: the number of bytes to encode
1666: *
1667: * Write hqx encoded data to an xmlOutputBuffer.
1668: * ::todo
1669: *
1.1.1.2 ! misho 1670: * Returns the bytes written (may be 0 because of buffering)
1.1 misho 1671: * or -1 in case of error
1672: */
1673: static int
1674: xmlOutputBufferWriteBinHex(xmlOutputBufferPtr out,
1675: int len, const unsigned char *data)
1676: {
1677: int count;
1678: int sum;
1.1.1.2 ! misho 1679: static char hex[16] =
! 1680: {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
1.1 misho 1681: int i;
1682:
1683: if ((out == NULL) || (data == NULL) || (len < 0)) {
1684: return -1;
1685: }
1686:
1687: sum = 0;
1688: for (i = 0; i < len; i++) {
1689: count =
1690: xmlOutputBufferWrite(out, 1,
1691: (const char *) &hex[data[i] >> 4]);
1692: if (count == -1)
1693: return -1;
1694: sum += count;
1695: count =
1696: xmlOutputBufferWrite(out, 1,
1697: (const char *) &hex[data[i] & 0xF]);
1698: if (count == -1)
1699: return -1;
1700: sum += count;
1701: }
1702:
1703: return sum;
1704: }
1705:
1706: /**
1707: * xmlTextWriterWriteBinHex:
1708: * @writer: the xmlTextWriterPtr
1709: * @data: binary data
1710: * @start: the position within the data of the first byte to encode
1711: * @len: the number of bytes to encode
1712: *
1713: * Write a BinHex encoded xml text.
1714: *
1715: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1716: */
1717: int
1718: xmlTextWriterWriteBinHex(xmlTextWriterPtr writer, const char *data,
1719: int start, int len)
1720: {
1721: int count;
1722: int sum;
1723: xmlLinkPtr lk;
1724: xmlTextWriterStackEntry *p;
1725:
1726: if ((writer == NULL) || (data == NULL) || (start < 0) || (len < 0))
1727: return -1;
1728:
1729: sum = 0;
1730: lk = xmlListFront(writer->nodes);
1731: if (lk != 0) {
1732: p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1733: if (p != 0) {
1734: count = xmlTextWriterHandleStateDependencies(writer, p);
1735: if (count < 0)
1736: return -1;
1737: sum += count;
1738: }
1739: }
1740:
1741: if (writer->indent)
1742: writer->doindent = 0;
1743:
1744: count =
1745: xmlOutputBufferWriteBinHex(writer->out, len,
1746: (unsigned char *) data + start);
1747: if (count < 0)
1748: return -1;
1749: sum += count;
1750:
1751: return sum;
1752: }
1753:
1754: /**
1755: * xmlTextWriterStartAttribute:
1756: * @writer: the xmlTextWriterPtr
1757: * @name: element name
1758: *
1759: * Start an xml attribute.
1760: *
1761: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1762: */
1763: int
1764: xmlTextWriterStartAttribute(xmlTextWriterPtr writer, const xmlChar * name)
1765: {
1766: int count;
1767: int sum;
1768: xmlLinkPtr lk;
1769: xmlTextWriterStackEntry *p;
1770:
1771: if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1772: return -1;
1773:
1774: sum = 0;
1775: lk = xmlListFront(writer->nodes);
1776: if (lk == 0)
1777: return -1;
1778:
1779: p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1780: if (p == 0)
1781: return -1;
1782:
1783: switch (p->state) {
1784: case XML_TEXTWRITER_ATTRIBUTE:
1785: count = xmlTextWriterEndAttribute(writer);
1786: if (count < 0)
1787: return -1;
1788: sum += count;
1789: /* fallthrough */
1790: case XML_TEXTWRITER_NAME:
1791: count = xmlOutputBufferWriteString(writer->out, " ");
1792: if (count < 0)
1793: return -1;
1794: sum += count;
1795: count =
1796: xmlOutputBufferWriteString(writer->out,
1797: (const char *) name);
1798: if (count < 0)
1799: return -1;
1800: sum += count;
1801: count = xmlOutputBufferWriteString(writer->out, "=");
1802: if (count < 0)
1803: return -1;
1804: sum += count;
1805: count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
1806: if (count < 0)
1807: return -1;
1808: sum += count;
1809: p->state = XML_TEXTWRITER_ATTRIBUTE;
1810: break;
1811: default:
1812: return -1;
1813: }
1814:
1815: return sum;
1816: }
1817:
1818: /**
1819: * xmlTextWriterStartAttributeNS:
1820: * @writer: the xmlTextWriterPtr
1821: * @prefix: namespace prefix or NULL
1822: * @name: element local name
1823: * @namespaceURI: namespace URI or NULL
1824: *
1825: * Start an xml attribute with namespace support.
1826: *
1827: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1828: */
1829: int
1830: xmlTextWriterStartAttributeNS(xmlTextWriterPtr writer,
1831: const xmlChar * prefix, const xmlChar * name,
1832: const xmlChar * namespaceURI)
1833: {
1834: int count;
1835: int sum;
1836: xmlChar *buf;
1837: xmlTextWriterNsStackEntry *p;
1838:
1839: if ((writer == NULL) || (name == NULL) || (*name == '\0'))
1840: return -1;
1841:
1842: /* Handle namespace first in case of error */
1843: if (namespaceURI != 0) {
1844: xmlTextWriterNsStackEntry nsentry, *curns;
1845:
1846: buf = xmlStrdup(BAD_CAST "xmlns");
1847: if (prefix != 0) {
1848: buf = xmlStrcat(buf, BAD_CAST ":");
1849: buf = xmlStrcat(buf, prefix);
1850: }
1851:
1852: nsentry.prefix = buf;
1853: nsentry.uri = (xmlChar *)namespaceURI;
1854: nsentry.elem = xmlListFront(writer->nodes);
1855:
1.1.1.2 ! misho 1856: curns = (xmlTextWriterNsStackEntry *)xmlListSearch(writer->nsstack,
1.1 misho 1857: (void *)&nsentry);
1858: if ((curns != NULL)) {
1859: xmlFree(buf);
1860: if (xmlStrcmp(curns->uri, namespaceURI) == 0) {
1861: /* Namespace already defined on element skip */
1862: buf = NULL;
1863: } else {
1864: /* Prefix mismatch so error out */
1865: return -1;
1866: }
1867: }
1868:
1869: /* Do not add namespace decl to list - it is already there */
1870: if (buf != NULL) {
1871: p = (xmlTextWriterNsStackEntry *)
1872: xmlMalloc(sizeof(xmlTextWriterNsStackEntry));
1873: if (p == 0) {
1874: xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
1875: "xmlTextWriterStartAttributeNS : out of memory!\n");
1876: return -1;
1877: }
1878:
1879: p->prefix = buf;
1880: p->uri = xmlStrdup(namespaceURI);
1881: if (p->uri == 0) {
1882: xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
1883: "xmlTextWriterStartAttributeNS : out of memory!\n");
1884: xmlFree(p);
1885: return -1;
1886: }
1887: p->elem = xmlListFront(writer->nodes);
1888:
1889: xmlListPushFront(writer->nsstack, p);
1890: }
1891: }
1892:
1893: buf = NULL;
1894: if (prefix != 0) {
1895: buf = xmlStrdup(prefix);
1896: buf = xmlStrcat(buf, BAD_CAST ":");
1897: }
1898: buf = xmlStrcat(buf, name);
1899:
1900: sum = 0;
1901: count = xmlTextWriterStartAttribute(writer, buf);
1902: xmlFree(buf);
1903: if (count < 0)
1904: return -1;
1905: sum += count;
1906:
1907: return sum;
1908: }
1909:
1910: /**
1911: * xmlTextWriterEndAttribute:
1912: * @writer: the xmlTextWriterPtr
1913: *
1914: * End the current xml element.
1915: *
1916: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1917: */
1918: int
1919: xmlTextWriterEndAttribute(xmlTextWriterPtr writer)
1920: {
1921: int count;
1922: int sum;
1923: xmlLinkPtr lk;
1924: xmlTextWriterStackEntry *p;
1925:
1926: if (writer == NULL)
1927: return -1;
1928:
1929: lk = xmlListFront(writer->nodes);
1930: if (lk == 0) {
1931: return -1;
1932: }
1933:
1934: p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
1935: if (p == 0) {
1936: return -1;
1937: }
1938:
1939: sum = 0;
1940: switch (p->state) {
1941: case XML_TEXTWRITER_ATTRIBUTE:
1942: p->state = XML_TEXTWRITER_NAME;
1943:
1944: count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
1945: if (count < 0) {
1946: return -1;
1947: }
1948: sum += count;
1949: break;
1950: default:
1951: return -1;
1952: }
1953:
1954: return sum;
1955: }
1956:
1957: /**
1958: * xmlTextWriterWriteFormatAttribute:
1959: * @writer: the xmlTextWriterPtr
1960: * @name: attribute name
1961: * @format: format string (see printf)
1962: * @...: extra parameters for the format
1963: *
1964: * Write a formatted xml attribute.
1965: *
1966: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1967: */
1968: int XMLCDECL
1969: xmlTextWriterWriteFormatAttribute(xmlTextWriterPtr writer,
1970: const xmlChar * name, const char *format,
1971: ...)
1972: {
1973: int rc;
1974: va_list ap;
1975:
1976: va_start(ap, format);
1977:
1978: rc = xmlTextWriterWriteVFormatAttribute(writer, name, format, ap);
1979:
1980: va_end(ap);
1981: return rc;
1982: }
1983:
1984: /**
1985: * xmlTextWriterWriteVFormatAttribute:
1986: * @writer: the xmlTextWriterPtr
1987: * @name: attribute name
1988: * @format: format string (see printf)
1989: * @argptr: pointer to the first member of the variable argument list.
1990: *
1991: * Write a formatted xml attribute.
1992: *
1993: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
1994: */
1995: int
1996: xmlTextWriterWriteVFormatAttribute(xmlTextWriterPtr writer,
1997: const xmlChar * name,
1998: const char *format, va_list argptr)
1999: {
2000: int rc;
2001: xmlChar *buf;
2002:
2003: if (writer == NULL)
2004: return -1;
2005:
2006: buf = xmlTextWriterVSprintf(format, argptr);
2007: if (buf == NULL)
2008: return -1;
2009:
2010: rc = xmlTextWriterWriteAttribute(writer, name, buf);
2011:
2012: xmlFree(buf);
2013: return rc;
2014: }
2015:
2016: /**
2017: * xmlTextWriterWriteAttribute:
2018: * @writer: the xmlTextWriterPtr
2019: * @name: attribute name
2020: * @content: attribute content
2021: *
2022: * Write an xml attribute.
2023: *
2024: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2025: */
2026: int
2027: xmlTextWriterWriteAttribute(xmlTextWriterPtr writer, const xmlChar * name,
2028: const xmlChar * content)
2029: {
2030: int count;
2031: int sum;
2032:
2033: sum = 0;
2034: count = xmlTextWriterStartAttribute(writer, name);
2035: if (count < 0)
2036: return -1;
2037: sum += count;
2038: count = xmlTextWriterWriteString(writer, content);
2039: if (count < 0)
2040: return -1;
2041: sum += count;
2042: count = xmlTextWriterEndAttribute(writer);
2043: if (count < 0)
2044: return -1;
2045: sum += count;
2046:
2047: return sum;
2048: }
2049:
2050: /**
2051: * xmlTextWriterWriteFormatAttributeNS:
2052: * @writer: the xmlTextWriterPtr
2053: * @prefix: namespace prefix
2054: * @name: attribute local name
2055: * @namespaceURI: namespace URI
2056: * @format: format string (see printf)
2057: * @...: extra parameters for the format
2058: *
2059: * Write a formatted xml attribute.with namespace support
2060: *
2061: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2062: */
2063: int XMLCDECL
2064: xmlTextWriterWriteFormatAttributeNS(xmlTextWriterPtr writer,
2065: const xmlChar * prefix,
2066: const xmlChar * name,
2067: const xmlChar * namespaceURI,
2068: const char *format, ...)
2069: {
2070: int rc;
2071: va_list ap;
2072:
2073: va_start(ap, format);
2074:
2075: rc = xmlTextWriterWriteVFormatAttributeNS(writer, prefix, name,
2076: namespaceURI, format, ap);
2077:
2078: va_end(ap);
2079: return rc;
2080: }
2081:
2082: /**
2083: * xmlTextWriterWriteVFormatAttributeNS:
2084: * @writer: the xmlTextWriterPtr
2085: * @prefix: namespace prefix
2086: * @name: attribute local name
2087: * @namespaceURI: namespace URI
2088: * @format: format string (see printf)
2089: * @argptr: pointer to the first member of the variable argument list.
2090: *
2091: * Write a formatted xml attribute.with namespace support
2092: *
2093: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2094: */
2095: int
2096: xmlTextWriterWriteVFormatAttributeNS(xmlTextWriterPtr writer,
2097: const xmlChar * prefix,
2098: const xmlChar * name,
2099: const xmlChar * namespaceURI,
2100: const char *format, va_list argptr)
2101: {
2102: int rc;
2103: xmlChar *buf;
2104:
2105: if (writer == NULL)
2106: return -1;
2107:
2108: buf = xmlTextWriterVSprintf(format, argptr);
2109: if (buf == NULL)
2110: return -1;
2111:
2112: rc = xmlTextWriterWriteAttributeNS(writer, prefix, name, namespaceURI,
2113: buf);
2114:
2115: xmlFree(buf);
2116: return rc;
2117: }
2118:
2119: /**
2120: * xmlTextWriterWriteAttributeNS:
2121: * @writer: the xmlTextWriterPtr
2122: * @prefix: namespace prefix
2123: * @name: attribute local name
2124: * @namespaceURI: namespace URI
2125: * @content: attribute content
2126: *
2127: * Write an xml attribute.
2128: *
2129: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2130: */
2131: int
2132: xmlTextWriterWriteAttributeNS(xmlTextWriterPtr writer,
2133: const xmlChar * prefix, const xmlChar * name,
2134: const xmlChar * namespaceURI,
2135: const xmlChar * content)
2136: {
2137: int count;
2138: int sum;
2139:
2140: if ((writer == NULL) || (name == NULL) || (*name == '\0'))
2141: return -1;
2142:
2143: sum = 0;
2144: count = xmlTextWriterStartAttributeNS(writer, prefix, name, namespaceURI);
2145: if (count < 0)
2146: return -1;
2147: sum += count;
2148: count = xmlTextWriterWriteString(writer, content);
2149: if (count < 0)
2150: return -1;
2151: sum += count;
2152: count = xmlTextWriterEndAttribute(writer);
2153: if (count < 0)
2154: return -1;
2155: sum += count;
2156:
2157: return sum;
2158: }
2159:
2160: /**
2161: * xmlTextWriterWriteFormatElement:
2162: * @writer: the xmlTextWriterPtr
2163: * @name: element name
2164: * @format: format string (see printf)
2165: * @...: extra parameters for the format
2166: *
2167: * Write a formatted xml element.
2168: *
2169: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2170: */
2171: int XMLCDECL
2172: xmlTextWriterWriteFormatElement(xmlTextWriterPtr writer,
2173: const xmlChar * name, const char *format,
2174: ...)
2175: {
2176: int rc;
2177: va_list ap;
2178:
2179: va_start(ap, format);
2180:
2181: rc = xmlTextWriterWriteVFormatElement(writer, name, format, ap);
2182:
2183: va_end(ap);
2184: return rc;
2185: }
2186:
2187: /**
2188: * xmlTextWriterWriteVFormatElement:
2189: * @writer: the xmlTextWriterPtr
2190: * @name: element name
2191: * @format: format string (see printf)
2192: * @argptr: pointer to the first member of the variable argument list.
2193: *
2194: * Write a formatted xml element.
2195: *
2196: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2197: */
2198: int
2199: xmlTextWriterWriteVFormatElement(xmlTextWriterPtr writer,
2200: const xmlChar * name, const char *format,
2201: va_list argptr)
2202: {
2203: int rc;
2204: xmlChar *buf;
2205:
2206: if (writer == NULL)
2207: return -1;
2208:
2209: buf = xmlTextWriterVSprintf(format, argptr);
2210: if (buf == NULL)
2211: return -1;
2212:
2213: rc = xmlTextWriterWriteElement(writer, name, buf);
2214:
2215: xmlFree(buf);
2216: return rc;
2217: }
2218:
2219: /**
2220: * xmlTextWriterWriteElement:
2221: * @writer: the xmlTextWriterPtr
2222: * @name: element name
2223: * @content: element content
2224: *
2225: * Write an xml element.
2226: *
2227: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2228: */
2229: int
2230: xmlTextWriterWriteElement(xmlTextWriterPtr writer, const xmlChar * name,
2231: const xmlChar * content)
2232: {
2233: int count;
2234: int sum;
2235:
2236: sum = 0;
2237: count = xmlTextWriterStartElement(writer, name);
2238: if (count == -1)
2239: return -1;
2240: sum += count;
2241: count = xmlTextWriterWriteString(writer, content);
2242: if (count == -1)
2243: return -1;
2244: sum += count;
2245: count = xmlTextWriterEndElement(writer);
2246: if (count == -1)
2247: return -1;
2248: sum += count;
2249:
2250: return sum;
2251: }
2252:
2253: /**
2254: * xmlTextWriterWriteFormatElementNS:
2255: * @writer: the xmlTextWriterPtr
2256: * @prefix: namespace prefix
2257: * @name: element local name
2258: * @namespaceURI: namespace URI
2259: * @format: format string (see printf)
2260: * @...: extra parameters for the format
2261: *
2262: * Write a formatted xml element with namespace support.
2263: *
2264: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2265: */
2266: int XMLCDECL
2267: xmlTextWriterWriteFormatElementNS(xmlTextWriterPtr writer,
2268: const xmlChar * prefix,
2269: const xmlChar * name,
2270: const xmlChar * namespaceURI,
2271: const char *format, ...)
2272: {
2273: int rc;
2274: va_list ap;
2275:
2276: va_start(ap, format);
2277:
2278: rc = xmlTextWriterWriteVFormatElementNS(writer, prefix, name,
2279: namespaceURI, format, ap);
2280:
2281: va_end(ap);
2282: return rc;
2283: }
2284:
2285: /**
2286: * xmlTextWriterWriteVFormatElementNS:
2287: * @writer: the xmlTextWriterPtr
2288: * @prefix: namespace prefix
2289: * @name: element local name
2290: * @namespaceURI: namespace URI
2291: * @format: format string (see printf)
2292: * @argptr: pointer to the first member of the variable argument list.
2293: *
2294: * Write a formatted xml element with namespace support.
2295: *
2296: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2297: */
2298: int
2299: xmlTextWriterWriteVFormatElementNS(xmlTextWriterPtr writer,
2300: const xmlChar * prefix,
2301: const xmlChar * name,
2302: const xmlChar * namespaceURI,
2303: const char *format, va_list argptr)
2304: {
2305: int rc;
2306: xmlChar *buf;
2307:
2308: if (writer == NULL)
2309: return -1;
2310:
2311: buf = xmlTextWriterVSprintf(format, argptr);
2312: if (buf == NULL)
2313: return -1;
2314:
2315: rc = xmlTextWriterWriteElementNS(writer, prefix, name, namespaceURI,
2316: buf);
2317:
2318: xmlFree(buf);
2319: return rc;
2320: }
2321:
2322: /**
2323: * xmlTextWriterWriteElementNS:
2324: * @writer: the xmlTextWriterPtr
2325: * @prefix: namespace prefix
2326: * @name: element local name
2327: * @namespaceURI: namespace URI
2328: * @content: element content
2329: *
2330: * Write an xml element with namespace support.
2331: *
2332: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2333: */
2334: int
2335: xmlTextWriterWriteElementNS(xmlTextWriterPtr writer,
2336: const xmlChar * prefix, const xmlChar * name,
2337: const xmlChar * namespaceURI,
2338: const xmlChar * content)
2339: {
2340: int count;
2341: int sum;
2342:
2343: if ((writer == NULL) || (name == NULL) || (*name == '\0'))
2344: return -1;
2345:
2346: sum = 0;
2347: count =
2348: xmlTextWriterStartElementNS(writer, prefix, name, namespaceURI);
2349: if (count < 0)
2350: return -1;
2351: sum += count;
2352: count = xmlTextWriterWriteString(writer, content);
2353: if (count == -1)
2354: return -1;
2355: sum += count;
2356: count = xmlTextWriterEndElement(writer);
2357: if (count == -1)
2358: return -1;
2359: sum += count;
2360:
2361: return sum;
2362: }
2363:
2364: /**
2365: * xmlTextWriterStartPI:
2366: * @writer: the xmlTextWriterPtr
2367: * @target: PI target
2368: *
2369: * Start an xml PI.
2370: *
2371: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2372: */
2373: int
2374: xmlTextWriterStartPI(xmlTextWriterPtr writer, const xmlChar * target)
2375: {
2376: int count;
2377: int sum;
2378: xmlLinkPtr lk;
2379: xmlTextWriterStackEntry *p;
2380:
2381: if ((writer == NULL) || (target == NULL) || (*target == '\0'))
2382: return -1;
2383:
2384: if (xmlStrcasecmp(target, (const xmlChar *) "xml") == 0) {
2385: xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
2386: "xmlTextWriterStartPI : target name [Xx][Mm][Ll] is reserved for xml standardization!\n");
2387: return -1;
2388: }
2389:
2390: sum = 0;
2391: lk = xmlListFront(writer->nodes);
2392: if (lk != 0) {
2393: p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2394: if (p != 0) {
2395: switch (p->state) {
2396: case XML_TEXTWRITER_ATTRIBUTE:
2397: count = xmlTextWriterEndAttribute(writer);
2398: if (count < 0)
2399: return -1;
2400: sum += count;
2401: /* fallthrough */
2402: case XML_TEXTWRITER_NAME:
2403: /* Output namespace declarations */
2404: count = xmlTextWriterOutputNSDecl(writer);
2405: if (count < 0)
2406: return -1;
2407: sum += count;
2408: count = xmlOutputBufferWriteString(writer->out, ">");
2409: if (count < 0)
2410: return -1;
2411: sum += count;
2412: p->state = XML_TEXTWRITER_TEXT;
2413: break;
2414: case XML_TEXTWRITER_NONE:
2415: case XML_TEXTWRITER_TEXT:
2416: case XML_TEXTWRITER_DTD:
2417: break;
2418: case XML_TEXTWRITER_PI:
2419: case XML_TEXTWRITER_PI_TEXT:
2420: xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
2421: "xmlTextWriterStartPI : nested PI!\n");
2422: return -1;
2423: default:
2424: return -1;
2425: }
2426: }
2427: }
2428:
2429: p = (xmlTextWriterStackEntry *)
2430: xmlMalloc(sizeof(xmlTextWriterStackEntry));
2431: if (p == 0) {
2432: xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
2433: "xmlTextWriterStartPI : out of memory!\n");
2434: return -1;
2435: }
2436:
2437: p->name = xmlStrdup(target);
2438: if (p->name == 0) {
2439: xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
2440: "xmlTextWriterStartPI : out of memory!\n");
2441: xmlFree(p);
2442: return -1;
2443: }
2444: p->state = XML_TEXTWRITER_PI;
2445:
2446: xmlListPushFront(writer->nodes, p);
2447:
2448: count = xmlOutputBufferWriteString(writer->out, "<?");
2449: if (count < 0)
2450: return -1;
2451: sum += count;
2452: count =
2453: xmlOutputBufferWriteString(writer->out, (const char *) p->name);
2454: if (count < 0)
2455: return -1;
2456: sum += count;
2457:
2458: return sum;
2459: }
2460:
2461: /**
2462: * xmlTextWriterEndPI:
2463: * @writer: the xmlTextWriterPtr
2464: *
2465: * End the current xml PI.
2466: *
2467: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2468: */
2469: int
2470: xmlTextWriterEndPI(xmlTextWriterPtr writer)
2471: {
2472: int count;
2473: int sum;
2474: xmlLinkPtr lk;
2475: xmlTextWriterStackEntry *p;
2476:
2477: if (writer == NULL)
2478: return -1;
2479:
2480: lk = xmlListFront(writer->nodes);
2481: if (lk == 0)
2482: return 0;
2483:
2484: p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2485: if (p == 0)
2486: return 0;
2487:
2488: sum = 0;
2489: switch (p->state) {
2490: case XML_TEXTWRITER_PI:
2491: case XML_TEXTWRITER_PI_TEXT:
2492: count = xmlOutputBufferWriteString(writer->out, "?>");
2493: if (count < 0)
2494: return -1;
2495: sum += count;
2496: break;
2497: default:
2498: return -1;
2499: }
2500:
2501: if (writer->indent) {
2502: count = xmlOutputBufferWriteString(writer->out, "\n");
1.1.1.2 ! misho 2503: if (count < 0)
! 2504: return -1;
1.1 misho 2505: sum += count;
2506: }
2507:
2508: xmlListPopFront(writer->nodes);
2509: return sum;
2510: }
2511:
2512: /**
2513: * xmlTextWriterWriteFormatPI:
2514: * @writer: the xmlTextWriterPtr
2515: * @target: PI target
2516: * @format: format string (see printf)
2517: * @...: extra parameters for the format
2518: *
2519: * Write a formatted PI.
2520: *
2521: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2522: */
2523: int XMLCDECL
2524: xmlTextWriterWriteFormatPI(xmlTextWriterPtr writer, const xmlChar * target,
2525: const char *format, ...)
2526: {
2527: int rc;
2528: va_list ap;
2529:
2530: va_start(ap, format);
2531:
2532: rc = xmlTextWriterWriteVFormatPI(writer, target, format, ap);
2533:
2534: va_end(ap);
2535: return rc;
2536: }
2537:
2538: /**
2539: * xmlTextWriterWriteVFormatPI:
2540: * @writer: the xmlTextWriterPtr
2541: * @target: PI target
2542: * @format: format string (see printf)
2543: * @argptr: pointer to the first member of the variable argument list.
2544: *
2545: * Write a formatted xml PI.
2546: *
2547: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2548: */
2549: int
2550: xmlTextWriterWriteVFormatPI(xmlTextWriterPtr writer,
2551: const xmlChar * target, const char *format,
2552: va_list argptr)
2553: {
2554: int rc;
2555: xmlChar *buf;
2556:
2557: if (writer == NULL)
2558: return -1;
2559:
2560: buf = xmlTextWriterVSprintf(format, argptr);
2561: if (buf == NULL)
2562: return -1;
2563:
2564: rc = xmlTextWriterWritePI(writer, target, buf);
2565:
2566: xmlFree(buf);
2567: return rc;
2568: }
2569:
2570: /**
2571: * xmlTextWriterWritePI:
2572: * @writer: the xmlTextWriterPtr
2573: * @target: PI target
2574: * @content: PI content
2575: *
2576: * Write an xml PI.
2577: *
2578: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2579: */
2580: int
2581: xmlTextWriterWritePI(xmlTextWriterPtr writer, const xmlChar * target,
2582: const xmlChar * content)
2583: {
2584: int count;
2585: int sum;
2586:
2587: sum = 0;
2588: count = xmlTextWriterStartPI(writer, target);
2589: if (count == -1)
2590: return -1;
2591: sum += count;
2592: if (content != 0) {
2593: count = xmlTextWriterWriteString(writer, content);
2594: if (count == -1)
2595: return -1;
2596: sum += count;
2597: }
2598: count = xmlTextWriterEndPI(writer);
2599: if (count == -1)
2600: return -1;
2601: sum += count;
2602:
2603: return sum;
2604: }
2605:
2606: /**
2607: * xmlTextWriterStartCDATA:
2608: * @writer: the xmlTextWriterPtr
2609: *
2610: * Start an xml CDATA section.
2611: *
2612: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2613: */
2614: int
2615: xmlTextWriterStartCDATA(xmlTextWriterPtr writer)
2616: {
2617: int count;
2618: int sum;
2619: xmlLinkPtr lk;
2620: xmlTextWriterStackEntry *p;
2621:
2622: if (writer == NULL)
2623: return -1;
2624:
2625: sum = 0;
2626: lk = xmlListFront(writer->nodes);
2627: if (lk != 0) {
2628: p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2629: if (p != 0) {
2630: switch (p->state) {
2631: case XML_TEXTWRITER_NONE:
2632: case XML_TEXTWRITER_TEXT:
2633: case XML_TEXTWRITER_PI:
2634: case XML_TEXTWRITER_PI_TEXT:
2635: break;
2636: case XML_TEXTWRITER_ATTRIBUTE:
2637: count = xmlTextWriterEndAttribute(writer);
2638: if (count < 0)
2639: return -1;
2640: sum += count;
2641: /* fallthrough */
2642: case XML_TEXTWRITER_NAME:
2643: /* Output namespace declarations */
2644: count = xmlTextWriterOutputNSDecl(writer);
2645: if (count < 0)
2646: return -1;
2647: sum += count;
2648: count = xmlOutputBufferWriteString(writer->out, ">");
2649: if (count < 0)
2650: return -1;
2651: sum += count;
2652: p->state = XML_TEXTWRITER_TEXT;
2653: break;
2654: case XML_TEXTWRITER_CDATA:
2655: xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
2656: "xmlTextWriterStartCDATA : CDATA not allowed in this context!\n");
2657: return -1;
2658: default:
2659: return -1;
2660: }
2661: }
2662: }
2663:
2664: p = (xmlTextWriterStackEntry *)
2665: xmlMalloc(sizeof(xmlTextWriterStackEntry));
2666: if (p == 0) {
2667: xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
2668: "xmlTextWriterStartCDATA : out of memory!\n");
2669: return -1;
2670: }
2671:
2672: p->name = NULL;
2673: p->state = XML_TEXTWRITER_CDATA;
2674:
2675: xmlListPushFront(writer->nodes, p);
2676:
2677: count = xmlOutputBufferWriteString(writer->out, "<![CDATA[");
2678: if (count < 0)
2679: return -1;
2680: sum += count;
2681:
2682: return sum;
2683: }
2684:
2685: /**
2686: * xmlTextWriterEndCDATA:
2687: * @writer: the xmlTextWriterPtr
2688: *
2689: * End an xml CDATA section.
2690: *
2691: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2692: */
2693: int
2694: xmlTextWriterEndCDATA(xmlTextWriterPtr writer)
2695: {
2696: int count;
2697: int sum;
2698: xmlLinkPtr lk;
2699: xmlTextWriterStackEntry *p;
2700:
2701: if (writer == NULL)
2702: return -1;
2703:
2704: lk = xmlListFront(writer->nodes);
2705: if (lk == 0)
2706: return -1;
2707:
2708: p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2709: if (p == 0)
2710: return -1;
2711:
2712: sum = 0;
2713: switch (p->state) {
2714: case XML_TEXTWRITER_CDATA:
2715: count = xmlOutputBufferWriteString(writer->out, "]]>");
2716: if (count < 0)
2717: return -1;
2718: sum += count;
2719: break;
2720: default:
2721: return -1;
2722: }
2723:
2724: xmlListPopFront(writer->nodes);
2725: return sum;
2726: }
2727:
2728: /**
2729: * xmlTextWriterWriteFormatCDATA:
2730: * @writer: the xmlTextWriterPtr
2731: * @format: format string (see printf)
2732: * @...: extra parameters for the format
2733: *
2734: * Write a formatted xml CDATA.
2735: *
2736: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2737: */
2738: int XMLCDECL
2739: xmlTextWriterWriteFormatCDATA(xmlTextWriterPtr writer, const char *format,
2740: ...)
2741: {
2742: int rc;
2743: va_list ap;
2744:
2745: va_start(ap, format);
2746:
2747: rc = xmlTextWriterWriteVFormatCDATA(writer, format, ap);
2748:
2749: va_end(ap);
2750: return rc;
2751: }
2752:
2753: /**
2754: * xmlTextWriterWriteVFormatCDATA:
2755: * @writer: the xmlTextWriterPtr
2756: * @format: format string (see printf)
2757: * @argptr: pointer to the first member of the variable argument list.
2758: *
2759: * Write a formatted xml CDATA.
2760: *
2761: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2762: */
2763: int
2764: xmlTextWriterWriteVFormatCDATA(xmlTextWriterPtr writer, const char *format,
2765: va_list argptr)
2766: {
2767: int rc;
2768: xmlChar *buf;
2769:
2770: if (writer == NULL)
2771: return -1;
2772:
2773: buf = xmlTextWriterVSprintf(format, argptr);
2774: if (buf == NULL)
2775: return -1;
2776:
2777: rc = xmlTextWriterWriteCDATA(writer, buf);
2778:
2779: xmlFree(buf);
2780: return rc;
2781: }
2782:
2783: /**
2784: * xmlTextWriterWriteCDATA:
2785: * @writer: the xmlTextWriterPtr
2786: * @content: CDATA content
2787: *
2788: * Write an xml CDATA.
2789: *
2790: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2791: */
2792: int
2793: xmlTextWriterWriteCDATA(xmlTextWriterPtr writer, const xmlChar * content)
2794: {
2795: int count;
2796: int sum;
2797:
2798: sum = 0;
2799: count = xmlTextWriterStartCDATA(writer);
2800: if (count == -1)
2801: return -1;
2802: sum += count;
2803: if (content != 0) {
2804: count = xmlTextWriterWriteString(writer, content);
2805: if (count == -1)
2806: return -1;
2807: sum += count;
2808: }
2809: count = xmlTextWriterEndCDATA(writer);
2810: if (count == -1)
2811: return -1;
2812: sum += count;
2813:
2814: return sum;
2815: }
2816:
2817: /**
2818: * xmlTextWriterStartDTD:
2819: * @writer: the xmlTextWriterPtr
2820: * @name: the name of the DTD
2821: * @pubid: the public identifier, which is an alternative to the system identifier
2822: * @sysid: the system identifier, which is the URI of the DTD
2823: *
2824: * Start an xml DTD.
2825: *
2826: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2827: */
2828: int
2829: xmlTextWriterStartDTD(xmlTextWriterPtr writer,
2830: const xmlChar * name,
2831: const xmlChar * pubid, const xmlChar * sysid)
2832: {
2833: int count;
2834: int sum;
2835: xmlLinkPtr lk;
2836: xmlTextWriterStackEntry *p;
2837:
2838: if (writer == NULL || name == NULL || *name == '\0')
2839: return -1;
2840:
2841: sum = 0;
2842: lk = xmlListFront(writer->nodes);
2843: if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) {
2844: xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
2845: "xmlTextWriterStartDTD : DTD allowed only in prolog!\n");
2846: return -1;
2847: }
2848:
2849: p = (xmlTextWriterStackEntry *)
2850: xmlMalloc(sizeof(xmlTextWriterStackEntry));
2851: if (p == 0) {
2852: xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
2853: "xmlTextWriterStartDTD : out of memory!\n");
2854: return -1;
2855: }
2856:
2857: p->name = xmlStrdup(name);
2858: if (p->name == 0) {
2859: xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
2860: "xmlTextWriterStartDTD : out of memory!\n");
2861: xmlFree(p);
2862: return -1;
2863: }
2864: p->state = XML_TEXTWRITER_DTD;
2865:
2866: xmlListPushFront(writer->nodes, p);
2867:
2868: count = xmlOutputBufferWriteString(writer->out, "<!DOCTYPE ");
2869: if (count < 0)
2870: return -1;
2871: sum += count;
2872: count = xmlOutputBufferWriteString(writer->out, (const char *) name);
2873: if (count < 0)
2874: return -1;
2875: sum += count;
2876:
2877: if (pubid != 0) {
2878: if (sysid == 0) {
2879: xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
2880: "xmlTextWriterStartDTD : system identifier needed!\n");
2881: return -1;
2882: }
2883:
2884: if (writer->indent)
2885: count = xmlOutputBufferWrite(writer->out, 1, "\n");
2886: else
2887: count = xmlOutputBufferWrite(writer->out, 1, " ");
2888: if (count < 0)
2889: return -1;
2890: sum += count;
2891:
2892: count = xmlOutputBufferWriteString(writer->out, "PUBLIC ");
2893: if (count < 0)
2894: return -1;
2895: sum += count;
2896:
2897: count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
2898: if (count < 0)
2899: return -1;
2900: sum += count;
2901:
2902: count =
2903: xmlOutputBufferWriteString(writer->out, (const char *) pubid);
2904: if (count < 0)
2905: return -1;
2906: sum += count;
2907:
2908: count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
2909: if (count < 0)
2910: return -1;
2911: sum += count;
2912: }
2913:
2914: if (sysid != 0) {
2915: if (pubid == 0) {
2916: if (writer->indent)
2917: count = xmlOutputBufferWrite(writer->out, 1, "\n");
2918: else
2919: count = xmlOutputBufferWrite(writer->out, 1, " ");
2920: if (count < 0)
2921: return -1;
2922: sum += count;
2923: count = xmlOutputBufferWriteString(writer->out, "SYSTEM ");
2924: if (count < 0)
2925: return -1;
2926: sum += count;
2927: } else {
2928: if (writer->indent)
2929: count = xmlOutputBufferWriteString(writer->out, "\n ");
2930: else
2931: count = xmlOutputBufferWrite(writer->out, 1, " ");
2932: if (count < 0)
2933: return -1;
2934: sum += count;
2935: }
2936:
2937: count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
2938: if (count < 0)
2939: return -1;
2940: sum += count;
2941:
2942: count =
2943: xmlOutputBufferWriteString(writer->out, (const char *) sysid);
2944: if (count < 0)
2945: return -1;
2946: sum += count;
2947:
2948: count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
2949: if (count < 0)
2950: return -1;
2951: sum += count;
2952: }
2953:
2954: return sum;
2955: }
2956:
2957: /**
2958: * xmlTextWriterEndDTD:
2959: * @writer: the xmlTextWriterPtr
2960: *
2961: * End an xml DTD.
2962: *
2963: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
2964: */
2965: int
2966: xmlTextWriterEndDTD(xmlTextWriterPtr writer)
2967: {
2968: int loop;
2969: int count;
2970: int sum;
2971: xmlLinkPtr lk;
2972: xmlTextWriterStackEntry *p;
2973:
2974: if (writer == NULL)
2975: return -1;
2976:
2977: sum = 0;
2978: loop = 1;
2979: while (loop) {
2980: lk = xmlListFront(writer->nodes);
2981: if (lk == NULL)
2982: break;
2983: p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
2984: if (p == 0)
2985: break;
2986: switch (p->state) {
2987: case XML_TEXTWRITER_DTD_TEXT:
2988: count = xmlOutputBufferWriteString(writer->out, "]");
2989: if (count < 0)
2990: return -1;
2991: sum += count;
2992: /* fallthrough */
2993: case XML_TEXTWRITER_DTD:
2994: count = xmlOutputBufferWriteString(writer->out, ">");
2995:
2996: if (writer->indent) {
2997: if (count < 0)
2998: return -1;
2999: sum += count;
3000: count = xmlOutputBufferWriteString(writer->out, "\n");
3001: }
3002:
3003: xmlListPopFront(writer->nodes);
3004: break;
3005: case XML_TEXTWRITER_DTD_ELEM:
3006: case XML_TEXTWRITER_DTD_ELEM_TEXT:
3007: count = xmlTextWriterEndDTDElement(writer);
3008: break;
3009: case XML_TEXTWRITER_DTD_ATTL:
3010: case XML_TEXTWRITER_DTD_ATTL_TEXT:
3011: count = xmlTextWriterEndDTDAttlist(writer);
3012: break;
3013: case XML_TEXTWRITER_DTD_ENTY:
3014: case XML_TEXTWRITER_DTD_PENT:
3015: case XML_TEXTWRITER_DTD_ENTY_TEXT:
3016: count = xmlTextWriterEndDTDEntity(writer);
3017: break;
3018: case XML_TEXTWRITER_COMMENT:
3019: count = xmlTextWriterEndComment(writer);
3020: break;
3021: default:
3022: loop = 0;
3023: continue;
3024: }
3025:
3026: if (count < 0)
3027: return -1;
3028: sum += count;
3029: }
3030:
3031: return sum;
3032: }
3033:
3034: /**
3035: * xmlTextWriterWriteFormatDTD:
3036: * @writer: the xmlTextWriterPtr
3037: * @name: the name of the DTD
3038: * @pubid: the public identifier, which is an alternative to the system identifier
3039: * @sysid: the system identifier, which is the URI of the DTD
3040: * @format: format string (see printf)
3041: * @...: extra parameters for the format
3042: *
3043: * Write a DTD with a formatted markup declarations part.
3044: *
3045: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3046: */
3047: int XMLCDECL
3048: xmlTextWriterWriteFormatDTD(xmlTextWriterPtr writer,
3049: const xmlChar * name,
3050: const xmlChar * pubid,
3051: const xmlChar * sysid, const char *format, ...)
3052: {
3053: int rc;
3054: va_list ap;
3055:
3056: va_start(ap, format);
3057:
3058: rc = xmlTextWriterWriteVFormatDTD(writer, name, pubid, sysid, format,
3059: ap);
3060:
3061: va_end(ap);
3062: return rc;
3063: }
3064:
3065: /**
3066: * xmlTextWriterWriteVFormatDTD:
3067: * @writer: the xmlTextWriterPtr
3068: * @name: the name of the DTD
3069: * @pubid: the public identifier, which is an alternative to the system identifier
3070: * @sysid: the system identifier, which is the URI of the DTD
3071: * @format: format string (see printf)
3072: * @argptr: pointer to the first member of the variable argument list.
3073: *
3074: * Write a DTD with a formatted markup declarations part.
3075: *
3076: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3077: */
3078: int
3079: xmlTextWriterWriteVFormatDTD(xmlTextWriterPtr writer,
3080: const xmlChar * name,
3081: const xmlChar * pubid,
3082: const xmlChar * sysid,
3083: const char *format, va_list argptr)
3084: {
3085: int rc;
3086: xmlChar *buf;
3087:
3088: if (writer == NULL)
3089: return -1;
3090:
3091: buf = xmlTextWriterVSprintf(format, argptr);
3092: if (buf == NULL)
3093: return -1;
3094:
3095: rc = xmlTextWriterWriteDTD(writer, name, pubid, sysid, buf);
3096:
3097: xmlFree(buf);
3098: return rc;
3099: }
3100:
3101: /**
3102: * xmlTextWriterWriteDTD:
3103: * @writer: the xmlTextWriterPtr
3104: * @name: the name of the DTD
3105: * @pubid: the public identifier, which is an alternative to the system identifier
3106: * @sysid: the system identifier, which is the URI of the DTD
3107: * @subset: string content of the DTD
3108: *
3109: * Write a DTD.
3110: *
3111: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3112: */
3113: int
3114: xmlTextWriterWriteDTD(xmlTextWriterPtr writer,
3115: const xmlChar * name,
3116: const xmlChar * pubid,
3117: const xmlChar * sysid, const xmlChar * subset)
3118: {
3119: int count;
3120: int sum;
3121:
3122: sum = 0;
3123: count = xmlTextWriterStartDTD(writer, name, pubid, sysid);
3124: if (count == -1)
3125: return -1;
3126: sum += count;
3127: if (subset != 0) {
3128: count = xmlTextWriterWriteString(writer, subset);
3129: if (count == -1)
3130: return -1;
3131: sum += count;
3132: }
3133: count = xmlTextWriterEndDTD(writer);
3134: if (count == -1)
3135: return -1;
3136: sum += count;
3137:
3138: return sum;
3139: }
3140:
3141: /**
3142: * xmlTextWriterStartDTDElement:
3143: * @writer: the xmlTextWriterPtr
3144: * @name: the name of the DTD element
3145: *
3146: * Start an xml DTD element.
3147: *
3148: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3149: */
3150: int
3151: xmlTextWriterStartDTDElement(xmlTextWriterPtr writer, const xmlChar * name)
3152: {
3153: int count;
3154: int sum;
3155: xmlLinkPtr lk;
3156: xmlTextWriterStackEntry *p;
3157:
3158: if (writer == NULL || name == NULL || *name == '\0')
3159: return -1;
3160:
3161: sum = 0;
3162: lk = xmlListFront(writer->nodes);
3163: if (lk == 0) {
3164: return -1;
3165: }
3166:
3167: p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3168: if (p != 0) {
3169: switch (p->state) {
3170: case XML_TEXTWRITER_DTD:
3171: count = xmlOutputBufferWriteString(writer->out, " [");
3172: if (count < 0)
3173: return -1;
3174: sum += count;
3175: if (writer->indent) {
3176: count = xmlOutputBufferWriteString(writer->out, "\n");
3177: if (count < 0)
3178: return -1;
3179: sum += count;
3180: }
3181: p->state = XML_TEXTWRITER_DTD_TEXT;
3182: /* fallthrough */
3183: case XML_TEXTWRITER_DTD_TEXT:
3184: case XML_TEXTWRITER_NONE:
3185: break;
3186: default:
3187: return -1;
3188: }
3189: }
3190:
3191: p = (xmlTextWriterStackEntry *)
3192: xmlMalloc(sizeof(xmlTextWriterStackEntry));
3193: if (p == 0) {
3194: xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
3195: "xmlTextWriterStartDTDElement : out of memory!\n");
3196: return -1;
3197: }
3198:
3199: p->name = xmlStrdup(name);
3200: if (p->name == 0) {
3201: xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
3202: "xmlTextWriterStartDTDElement : out of memory!\n");
3203: xmlFree(p);
3204: return -1;
3205: }
3206: p->state = XML_TEXTWRITER_DTD_ELEM;
3207:
3208: xmlListPushFront(writer->nodes, p);
3209:
3210: if (writer->indent) {
3211: count = xmlTextWriterWriteIndent(writer);
3212: if (count < 0)
3213: return -1;
3214: sum += count;
3215: }
3216:
3217: count = xmlOutputBufferWriteString(writer->out, "<!ELEMENT ");
3218: if (count < 0)
3219: return -1;
3220: sum += count;
3221: count = xmlOutputBufferWriteString(writer->out, (const char *) name);
3222: if (count < 0)
3223: return -1;
3224: sum += count;
3225:
3226: return sum;
3227: }
3228:
3229: /**
3230: * xmlTextWriterEndDTDElement:
3231: * @writer: the xmlTextWriterPtr
3232: *
3233: * End an xml DTD element.
3234: *
3235: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3236: */
3237: int
3238: xmlTextWriterEndDTDElement(xmlTextWriterPtr writer)
3239: {
3240: int count;
3241: int sum;
3242: xmlLinkPtr lk;
3243: xmlTextWriterStackEntry *p;
3244:
3245: if (writer == NULL)
3246: return -1;
3247:
3248: sum = 0;
3249: lk = xmlListFront(writer->nodes);
3250: if (lk == 0)
3251: return -1;
3252:
3253: p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3254: if (p == 0)
3255: return -1;
3256:
3257: switch (p->state) {
3258: case XML_TEXTWRITER_DTD_ELEM:
3259: case XML_TEXTWRITER_DTD_ELEM_TEXT:
3260: count = xmlOutputBufferWriteString(writer->out, ">");
3261: if (count < 0)
3262: return -1;
3263: sum += count;
3264: break;
3265: default:
3266: return -1;
3267: }
3268:
3269: if (writer->indent) {
3270: count = xmlOutputBufferWriteString(writer->out, "\n");
3271: if (count < 0)
3272: return -1;
3273: sum += count;
3274: }
3275:
3276: xmlListPopFront(writer->nodes);
3277: return sum;
3278: }
3279:
3280: /**
3281: * xmlTextWriterWriteFormatDTDElement:
3282: * @writer: the xmlTextWriterPtr
3283: * @name: the name of the DTD element
3284: * @format: format string (see printf)
3285: * @...: extra parameters for the format
3286: *
3287: * Write a formatted DTD element.
3288: *
3289: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3290: */
3291: int XMLCDECL
3292: xmlTextWriterWriteFormatDTDElement(xmlTextWriterPtr writer,
3293: const xmlChar * name,
3294: const char *format, ...)
3295: {
3296: int rc;
3297: va_list ap;
3298:
3299: va_start(ap, format);
3300:
3301: rc = xmlTextWriterWriteVFormatDTDElement(writer, name, format, ap);
3302:
3303: va_end(ap);
3304: return rc;
3305: }
3306:
3307: /**
3308: * xmlTextWriterWriteVFormatDTDElement:
3309: * @writer: the xmlTextWriterPtr
3310: * @name: the name of the DTD element
3311: * @format: format string (see printf)
3312: * @argptr: pointer to the first member of the variable argument list.
3313: *
3314: * Write a formatted DTD element.
3315: *
3316: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3317: */
3318: int
3319: xmlTextWriterWriteVFormatDTDElement(xmlTextWriterPtr writer,
3320: const xmlChar * name,
3321: const char *format, va_list argptr)
3322: {
3323: int rc;
3324: xmlChar *buf;
3325:
3326: if (writer == NULL)
3327: return -1;
3328:
3329: buf = xmlTextWriterVSprintf(format, argptr);
3330: if (buf == NULL)
3331: return -1;
3332:
3333: rc = xmlTextWriterWriteDTDElement(writer, name, buf);
3334:
3335: xmlFree(buf);
3336: return rc;
3337: }
3338:
3339: /**
3340: * xmlTextWriterWriteDTDElement:
3341: * @writer: the xmlTextWriterPtr
3342: * @name: the name of the DTD element
3343: * @content: content of the element
3344: *
3345: * Write a DTD element.
3346: *
3347: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3348: */
3349: int
3350: xmlTextWriterWriteDTDElement(xmlTextWriterPtr writer,
3351: const xmlChar * name, const xmlChar * content)
3352: {
3353: int count;
3354: int sum;
3355:
3356: if (content == NULL)
3357: return -1;
3358:
3359: sum = 0;
3360: count = xmlTextWriterStartDTDElement(writer, name);
3361: if (count == -1)
3362: return -1;
3363: sum += count;
3364:
3365: count = xmlTextWriterWriteString(writer, content);
3366: if (count == -1)
3367: return -1;
3368: sum += count;
3369:
3370: count = xmlTextWriterEndDTDElement(writer);
3371: if (count == -1)
3372: return -1;
3373: sum += count;
3374:
3375: return sum;
3376: }
3377:
3378: /**
3379: * xmlTextWriterStartDTDAttlist:
3380: * @writer: the xmlTextWriterPtr
3381: * @name: the name of the DTD ATTLIST
3382: *
3383: * Start an xml DTD ATTLIST.
3384: *
3385: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3386: */
3387: int
3388: xmlTextWriterStartDTDAttlist(xmlTextWriterPtr writer, const xmlChar * name)
3389: {
3390: int count;
3391: int sum;
3392: xmlLinkPtr lk;
3393: xmlTextWriterStackEntry *p;
3394:
3395: if (writer == NULL || name == NULL || *name == '\0')
3396: return -1;
3397:
3398: sum = 0;
3399: lk = xmlListFront(writer->nodes);
3400: if (lk == 0) {
3401: return -1;
3402: }
3403:
3404: p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3405: if (p != 0) {
3406: switch (p->state) {
3407: case XML_TEXTWRITER_DTD:
3408: count = xmlOutputBufferWriteString(writer->out, " [");
3409: if (count < 0)
3410: return -1;
3411: sum += count;
3412: if (writer->indent) {
3413: count = xmlOutputBufferWriteString(writer->out, "\n");
3414: if (count < 0)
3415: return -1;
3416: sum += count;
3417: }
3418: p->state = XML_TEXTWRITER_DTD_TEXT;
3419: /* fallthrough */
3420: case XML_TEXTWRITER_DTD_TEXT:
3421: case XML_TEXTWRITER_NONE:
3422: break;
3423: default:
3424: return -1;
3425: }
3426: }
3427:
3428: p = (xmlTextWriterStackEntry *)
3429: xmlMalloc(sizeof(xmlTextWriterStackEntry));
3430: if (p == 0) {
3431: xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
3432: "xmlTextWriterStartDTDAttlist : out of memory!\n");
3433: return -1;
3434: }
3435:
3436: p->name = xmlStrdup(name);
3437: if (p->name == 0) {
3438: xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
3439: "xmlTextWriterStartDTDAttlist : out of memory!\n");
3440: xmlFree(p);
3441: return -1;
3442: }
3443: p->state = XML_TEXTWRITER_DTD_ATTL;
3444:
3445: xmlListPushFront(writer->nodes, p);
3446:
3447: if (writer->indent) {
3448: count = xmlTextWriterWriteIndent(writer);
3449: if (count < 0)
3450: return -1;
3451: sum += count;
3452: }
3453:
3454: count = xmlOutputBufferWriteString(writer->out, "<!ATTLIST ");
3455: if (count < 0)
3456: return -1;
3457: sum += count;
3458: count = xmlOutputBufferWriteString(writer->out, (const char *) name);
3459: if (count < 0)
3460: return -1;
3461: sum += count;
3462:
3463: return sum;
3464: }
3465:
3466: /**
3467: * xmlTextWriterEndDTDAttlist:
3468: * @writer: the xmlTextWriterPtr
3469: *
3470: * End an xml DTD attribute list.
3471: *
3472: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3473: */
3474: int
3475: xmlTextWriterEndDTDAttlist(xmlTextWriterPtr writer)
3476: {
3477: int count;
3478: int sum;
3479: xmlLinkPtr lk;
3480: xmlTextWriterStackEntry *p;
3481:
3482: if (writer == NULL)
3483: return -1;
3484:
3485: sum = 0;
3486: lk = xmlListFront(writer->nodes);
3487: if (lk == 0)
3488: return -1;
3489:
3490: p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3491: if (p == 0)
3492: return -1;
3493:
3494: switch (p->state) {
3495: case XML_TEXTWRITER_DTD_ATTL:
3496: case XML_TEXTWRITER_DTD_ATTL_TEXT:
3497: count = xmlOutputBufferWriteString(writer->out, ">");
3498: if (count < 0)
3499: return -1;
3500: sum += count;
3501: break;
3502: default:
3503: return -1;
3504: }
3505:
3506: if (writer->indent) {
3507: count = xmlOutputBufferWriteString(writer->out, "\n");
3508: if (count < 0)
3509: return -1;
3510: sum += count;
3511: }
3512:
3513: xmlListPopFront(writer->nodes);
3514: return sum;
3515: }
3516:
3517: /**
3518: * xmlTextWriterWriteFormatDTDAttlist:
3519: * @writer: the xmlTextWriterPtr
3520: * @name: the name of the DTD ATTLIST
3521: * @format: format string (see printf)
3522: * @...: extra parameters for the format
3523: *
3524: * Write a formatted DTD ATTLIST.
3525: *
3526: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3527: */
3528: int XMLCDECL
3529: xmlTextWriterWriteFormatDTDAttlist(xmlTextWriterPtr writer,
3530: const xmlChar * name,
3531: const char *format, ...)
3532: {
3533: int rc;
3534: va_list ap;
3535:
3536: va_start(ap, format);
3537:
3538: rc = xmlTextWriterWriteVFormatDTDAttlist(writer, name, format, ap);
3539:
3540: va_end(ap);
3541: return rc;
3542: }
3543:
3544: /**
3545: * xmlTextWriterWriteVFormatDTDAttlist:
3546: * @writer: the xmlTextWriterPtr
3547: * @name: the name of the DTD ATTLIST
3548: * @format: format string (see printf)
3549: * @argptr: pointer to the first member of the variable argument list.
3550: *
3551: * Write a formatted DTD ATTLIST.
3552: *
3553: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3554: */
3555: int
3556: xmlTextWriterWriteVFormatDTDAttlist(xmlTextWriterPtr writer,
3557: const xmlChar * name,
3558: const char *format, va_list argptr)
3559: {
3560: int rc;
3561: xmlChar *buf;
3562:
3563: if (writer == NULL)
3564: return -1;
3565:
3566: buf = xmlTextWriterVSprintf(format, argptr);
3567: if (buf == NULL)
3568: return -1;
3569:
3570: rc = xmlTextWriterWriteDTDAttlist(writer, name, buf);
3571:
3572: xmlFree(buf);
3573: return rc;
3574: }
3575:
3576: /**
3577: * xmlTextWriterWriteDTDAttlist:
3578: * @writer: the xmlTextWriterPtr
3579: * @name: the name of the DTD ATTLIST
3580: * @content: content of the ATTLIST
3581: *
3582: * Write a DTD ATTLIST.
3583: *
3584: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3585: */
3586: int
3587: xmlTextWriterWriteDTDAttlist(xmlTextWriterPtr writer,
3588: const xmlChar * name, const xmlChar * content)
3589: {
3590: int count;
3591: int sum;
3592:
3593: if (content == NULL)
3594: return -1;
3595:
3596: sum = 0;
3597: count = xmlTextWriterStartDTDAttlist(writer, name);
3598: if (count == -1)
3599: return -1;
3600: sum += count;
3601:
3602: count = xmlTextWriterWriteString(writer, content);
3603: if (count == -1)
3604: return -1;
3605: sum += count;
3606:
3607: count = xmlTextWriterEndDTDAttlist(writer);
3608: if (count == -1)
3609: return -1;
3610: sum += count;
3611:
3612: return sum;
3613: }
3614:
3615: /**
3616: * xmlTextWriterStartDTDEntity:
3617: * @writer: the xmlTextWriterPtr
3618: * @pe: TRUE if this is a parameter entity, FALSE if not
3619: * @name: the name of the DTD ATTLIST
3620: *
3621: * Start an xml DTD ATTLIST.
3622: *
3623: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3624: */
3625: int
3626: xmlTextWriterStartDTDEntity(xmlTextWriterPtr writer,
3627: int pe, const xmlChar * name)
3628: {
3629: int count;
3630: int sum;
3631: xmlLinkPtr lk;
3632: xmlTextWriterStackEntry *p;
3633:
3634: if (writer == NULL || name == NULL || *name == '\0')
3635: return -1;
3636:
3637: sum = 0;
3638: lk = xmlListFront(writer->nodes);
3639: if (lk != 0) {
3640:
3641: p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3642: if (p != 0) {
3643: switch (p->state) {
3644: case XML_TEXTWRITER_DTD:
3645: count = xmlOutputBufferWriteString(writer->out, " [");
3646: if (count < 0)
3647: return -1;
3648: sum += count;
3649: if (writer->indent) {
3650: count =
3651: xmlOutputBufferWriteString(writer->out, "\n");
3652: if (count < 0)
3653: return -1;
3654: sum += count;
3655: }
3656: p->state = XML_TEXTWRITER_DTD_TEXT;
3657: /* fallthrough */
3658: case XML_TEXTWRITER_DTD_TEXT:
3659: case XML_TEXTWRITER_NONE:
3660: break;
3661: default:
3662: return -1;
3663: }
3664: }
3665: }
3666:
3667: p = (xmlTextWriterStackEntry *)
3668: xmlMalloc(sizeof(xmlTextWriterStackEntry));
3669: if (p == 0) {
3670: xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
3671: "xmlTextWriterStartDTDElement : out of memory!\n");
3672: return -1;
3673: }
3674:
3675: p->name = xmlStrdup(name);
3676: if (p->name == 0) {
3677: xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
3678: "xmlTextWriterStartDTDElement : out of memory!\n");
3679: xmlFree(p);
3680: return -1;
3681: }
3682:
3683: if (pe != 0)
3684: p->state = XML_TEXTWRITER_DTD_PENT;
3685: else
3686: p->state = XML_TEXTWRITER_DTD_ENTY;
3687:
3688: xmlListPushFront(writer->nodes, p);
3689:
3690: if (writer->indent) {
3691: count = xmlTextWriterWriteIndent(writer);
3692: if (count < 0)
3693: return -1;
3694: sum += count;
3695: }
3696:
3697: count = xmlOutputBufferWriteString(writer->out, "<!ENTITY ");
3698: if (count < 0)
3699: return -1;
3700: sum += count;
3701:
3702: if (pe != 0) {
3703: count = xmlOutputBufferWriteString(writer->out, "% ");
3704: if (count < 0)
3705: return -1;
3706: sum += count;
3707: }
3708:
3709: count = xmlOutputBufferWriteString(writer->out, (const char *) name);
3710: if (count < 0)
3711: return -1;
3712: sum += count;
3713:
3714: return sum;
3715: }
3716:
3717: /**
3718: * xmlTextWriterEndDTDEntity:
3719: * @writer: the xmlTextWriterPtr
3720: *
3721: * End an xml DTD entity.
3722: *
3723: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3724: */
3725: int
3726: xmlTextWriterEndDTDEntity(xmlTextWriterPtr writer)
3727: {
3728: int count;
3729: int sum;
3730: xmlLinkPtr lk;
3731: xmlTextWriterStackEntry *p;
3732:
3733: if (writer == NULL)
3734: return -1;
3735:
3736: sum = 0;
3737: lk = xmlListFront(writer->nodes);
3738: if (lk == 0)
3739: return -1;
3740:
3741: p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
3742: if (p == 0)
3743: return -1;
3744:
3745: switch (p->state) {
3746: case XML_TEXTWRITER_DTD_ENTY_TEXT:
3747: count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
3748: if (count < 0)
3749: return -1;
3750: sum += count;
3751: case XML_TEXTWRITER_DTD_ENTY:
3752: case XML_TEXTWRITER_DTD_PENT:
3753: count = xmlOutputBufferWriteString(writer->out, ">");
3754: if (count < 0)
3755: return -1;
3756: sum += count;
3757: break;
3758: default:
3759: return -1;
3760: }
3761:
3762: if (writer->indent) {
3763: count = xmlOutputBufferWriteString(writer->out, "\n");
3764: if (count < 0)
3765: return -1;
3766: sum += count;
3767: }
3768:
3769: xmlListPopFront(writer->nodes);
3770: return sum;
3771: }
3772:
3773: /**
3774: * xmlTextWriterWriteFormatDTDInternalEntity:
3775: * @writer: the xmlTextWriterPtr
3776: * @pe: TRUE if this is a parameter entity, FALSE if not
3777: * @name: the name of the DTD entity
3778: * @format: format string (see printf)
3779: * @...: extra parameters for the format
3780: *
3781: * Write a formatted DTD internal entity.
3782: *
3783: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3784: */
3785: int XMLCDECL
3786: xmlTextWriterWriteFormatDTDInternalEntity(xmlTextWriterPtr writer,
3787: int pe,
3788: const xmlChar * name,
3789: const char *format, ...)
3790: {
3791: int rc;
3792: va_list ap;
3793:
3794: va_start(ap, format);
3795:
3796: rc = xmlTextWriterWriteVFormatDTDInternalEntity(writer, pe, name,
3797: format, ap);
3798:
3799: va_end(ap);
3800: return rc;
3801: }
3802:
3803: /**
3804: * xmlTextWriterWriteVFormatDTDInternalEntity:
3805: * @writer: the xmlTextWriterPtr
3806: * @pe: TRUE if this is a parameter entity, FALSE if not
3807: * @name: the name of the DTD entity
3808: * @format: format string (see printf)
3809: * @argptr: pointer to the first member of the variable argument list.
3810: *
3811: * Write a formatted DTD internal entity.
3812: *
3813: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3814: */
3815: int
3816: xmlTextWriterWriteVFormatDTDInternalEntity(xmlTextWriterPtr writer,
3817: int pe,
3818: const xmlChar * name,
3819: const char *format,
3820: va_list argptr)
3821: {
3822: int rc;
3823: xmlChar *buf;
3824:
3825: if (writer == NULL)
3826: return -1;
3827:
3828: buf = xmlTextWriterVSprintf(format, argptr);
3829: if (buf == NULL)
3830: return -1;
3831:
3832: rc = xmlTextWriterWriteDTDInternalEntity(writer, pe, name, buf);
3833:
3834: xmlFree(buf);
3835: return rc;
3836: }
3837:
3838: /**
3839: * xmlTextWriterWriteDTDEntity:
3840: * @writer: the xmlTextWriterPtr
3841: * @pe: TRUE if this is a parameter entity, FALSE if not
3842: * @name: the name of the DTD entity
3843: * @pubid: the public identifier, which is an alternative to the system identifier
3844: * @sysid: the system identifier, which is the URI of the DTD
3845: * @ndataid: the xml notation name.
3846: * @content: content of the entity
3847: *
3848: * Write a DTD entity.
3849: *
3850: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3851: */
3852: int
3853: xmlTextWriterWriteDTDEntity(xmlTextWriterPtr writer,
3854: int pe,
3855: const xmlChar * name,
3856: const xmlChar * pubid,
3857: const xmlChar * sysid,
3858: const xmlChar * ndataid,
3859: const xmlChar * content)
3860: {
3861: if ((content == NULL) && (pubid == NULL) && (sysid == NULL))
3862: return -1;
3863: if ((pe != 0) && (ndataid != NULL))
3864: return -1;
3865:
3866: if ((pubid == NULL) && (sysid == NULL))
3867: return xmlTextWriterWriteDTDInternalEntity(writer, pe, name,
3868: content);
3869:
3870: return xmlTextWriterWriteDTDExternalEntity(writer, pe, name, pubid,
3871: sysid, ndataid);
3872: }
3873:
3874: /**
3875: * xmlTextWriterWriteDTDInternalEntity:
3876: * @writer: the xmlTextWriterPtr
3877: * @pe: TRUE if this is a parameter entity, FALSE if not
3878: * @name: the name of the DTD entity
3879: * @content: content of the entity
3880: *
3881: * Write a DTD internal entity.
3882: *
3883: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3884: */
3885: int
3886: xmlTextWriterWriteDTDInternalEntity(xmlTextWriterPtr writer,
3887: int pe,
3888: const xmlChar * name,
3889: const xmlChar * content)
3890: {
3891: int count;
3892: int sum;
3893:
3894: if ((name == NULL) || (*name == '\0') || (content == NULL))
3895: return -1;
3896:
3897: sum = 0;
3898: count = xmlTextWriterStartDTDEntity(writer, pe, name);
3899: if (count == -1)
3900: return -1;
3901: sum += count;
3902:
3903: count = xmlTextWriterWriteString(writer, content);
3904: if (count == -1)
3905: return -1;
3906: sum += count;
3907:
3908: count = xmlTextWriterEndDTDEntity(writer);
3909: if (count == -1)
3910: return -1;
3911: sum += count;
3912:
3913: return sum;
3914: }
3915:
3916: /**
3917: * xmlTextWriterWriteDTDExternalEntity:
3918: * @writer: the xmlTextWriterPtr
3919: * @pe: TRUE if this is a parameter entity, FALSE if not
3920: * @name: the name of the DTD entity
3921: * @pubid: the public identifier, which is an alternative to the system identifier
3922: * @sysid: the system identifier, which is the URI of the DTD
3923: * @ndataid: the xml notation name.
3924: *
3925: * Write a DTD external entity. The entity must have been started with xmlTextWriterStartDTDEntity
3926: *
3927: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3928: */
3929: int
3930: xmlTextWriterWriteDTDExternalEntity(xmlTextWriterPtr writer,
3931: int pe,
3932: const xmlChar * name,
3933: const xmlChar * pubid,
3934: const xmlChar * sysid,
3935: const xmlChar * ndataid)
3936: {
3937: int count;
3938: int sum;
3939:
3940: if (((pubid == NULL) && (sysid == NULL)))
3941: return -1;
3942: if ((pe != 0) && (ndataid != NULL))
3943: return -1;
3944:
3945: sum = 0;
3946: count = xmlTextWriterStartDTDEntity(writer, pe, name);
3947: if (count == -1)
3948: return -1;
3949: sum += count;
3950:
3951: count =
3952: xmlTextWriterWriteDTDExternalEntityContents(writer, pubid, sysid,
3953: ndataid);
3954: if (count < 0)
3955: return -1;
3956: sum += count;
3957:
3958: count = xmlTextWriterEndDTDEntity(writer);
3959: if (count == -1)
3960: return -1;
3961: sum += count;
3962:
3963: return sum;
3964: }
3965:
3966: /**
3967: * xmlTextWriterWriteDTDExternalEntityContents:
3968: * @writer: the xmlTextWriterPtr
3969: * @pubid: the public identifier, which is an alternative to the system identifier
3970: * @sysid: the system identifier, which is the URI of the DTD
3971: * @ndataid: the xml notation name.
3972: *
3973: * Write the contents of a DTD external entity.
3974: *
3975: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
3976: */
3977: int
3978: xmlTextWriterWriteDTDExternalEntityContents(xmlTextWriterPtr writer,
3979: const xmlChar * pubid,
3980: const xmlChar * sysid,
3981: const xmlChar * ndataid)
3982: {
3983: int count;
3984: int sum;
3985: xmlLinkPtr lk;
3986: xmlTextWriterStackEntry *p;
3987:
3988: if (writer == NULL) {
3989: xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
3990: "xmlTextWriterWriteDTDExternalEntityContents: xmlTextWriterPtr invalid!\n");
3991: return -1;
3992: }
3993:
3994: sum = 0;
3995: lk = xmlListFront(writer->nodes);
3996: if (lk == 0) {
3997: xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
3998: "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n");
3999: return -1;
4000: }
4001:
4002: p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
4003: if (p == 0)
4004: return -1;
4005:
4006: switch (p->state) {
4007: case XML_TEXTWRITER_DTD_ENTY:
4008: break;
4009: case XML_TEXTWRITER_DTD_PENT:
4010: if (ndataid != NULL) {
4011: xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
4012: "xmlTextWriterWriteDTDExternalEntityContents: notation not allowed with parameter entities!\n");
4013: return -1;
4014: }
4015: break;
4016: default:
4017: xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
4018: "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n");
4019: return -1;
4020: }
4021:
4022: if (pubid != 0) {
4023: if (sysid == 0) {
4024: xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
4025: "xmlTextWriterWriteDTDExternalEntityContents: system identifier needed!\n");
4026: return -1;
4027: }
4028:
4029: count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
4030: if (count < 0)
4031: return -1;
4032: sum += count;
4033:
4034: count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4035: if (count < 0)
4036: return -1;
4037: sum += count;
4038:
4039: count =
4040: xmlOutputBufferWriteString(writer->out, (const char *) pubid);
4041: if (count < 0)
4042: return -1;
4043: sum += count;
4044:
4045: count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4046: if (count < 0)
4047: return -1;
4048: sum += count;
4049: }
4050:
4051: if (sysid != 0) {
4052: if (pubid == 0) {
4053: count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
4054: if (count < 0)
4055: return -1;
4056: sum += count;
4057: }
4058:
4059: count = xmlOutputBufferWriteString(writer->out, " ");
4060: if (count < 0)
4061: return -1;
4062: sum += count;
4063:
4064: count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4065: if (count < 0)
4066: return -1;
4067: sum += count;
4068:
4069: count =
4070: xmlOutputBufferWriteString(writer->out, (const char *) sysid);
4071: if (count < 0)
4072: return -1;
4073: sum += count;
4074:
4075: count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4076: if (count < 0)
4077: return -1;
4078: sum += count;
4079: }
4080:
4081: if (ndataid != NULL) {
4082: count = xmlOutputBufferWriteString(writer->out, " NDATA ");
4083: if (count < 0)
4084: return -1;
4085: sum += count;
4086:
4087: count =
4088: xmlOutputBufferWriteString(writer->out,
4089: (const char *) ndataid);
4090: if (count < 0)
4091: return -1;
4092: sum += count;
4093: }
4094:
4095: return sum;
4096: }
4097:
4098: /**
4099: * xmlTextWriterWriteDTDNotation:
4100: * @writer: the xmlTextWriterPtr
4101: * @name: the name of the xml notation
4102: * @pubid: the public identifier, which is an alternative to the system identifier
4103: * @sysid: the system identifier, which is the URI of the DTD
4104: *
4105: * Write a DTD entity.
4106: *
4107: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
4108: */
4109: int
4110: xmlTextWriterWriteDTDNotation(xmlTextWriterPtr writer,
4111: const xmlChar * name,
4112: const xmlChar * pubid, const xmlChar * sysid)
4113: {
4114: int count;
4115: int sum;
4116: xmlLinkPtr lk;
4117: xmlTextWriterStackEntry *p;
4118:
4119: if (writer == NULL || name == NULL || *name == '\0')
4120: return -1;
4121:
4122: sum = 0;
4123: lk = xmlListFront(writer->nodes);
4124: if (lk == 0) {
4125: return -1;
4126: }
4127:
4128: p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
4129: if (p != 0) {
4130: switch (p->state) {
4131: case XML_TEXTWRITER_DTD:
4132: count = xmlOutputBufferWriteString(writer->out, " [");
4133: if (count < 0)
4134: return -1;
4135: sum += count;
4136: if (writer->indent) {
4137: count = xmlOutputBufferWriteString(writer->out, "\n");
4138: if (count < 0)
4139: return -1;
4140: sum += count;
4141: }
4142: p->state = XML_TEXTWRITER_DTD_TEXT;
4143: /* fallthrough */
4144: case XML_TEXTWRITER_DTD_TEXT:
4145: break;
4146: default:
4147: return -1;
4148: }
4149: }
4150:
4151: if (writer->indent) {
4152: count = xmlTextWriterWriteIndent(writer);
4153: if (count < 0)
4154: return -1;
4155: sum += count;
4156: }
4157:
4158: count = xmlOutputBufferWriteString(writer->out, "<!NOTATION ");
4159: if (count < 0)
4160: return -1;
4161: sum += count;
4162: count = xmlOutputBufferWriteString(writer->out, (const char *) name);
4163: if (count < 0)
4164: return -1;
4165: sum += count;
4166:
4167: if (pubid != 0) {
4168: count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
4169: if (count < 0)
4170: return -1;
4171: sum += count;
4172: count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4173: if (count < 0)
4174: return -1;
4175: sum += count;
4176: count =
4177: xmlOutputBufferWriteString(writer->out, (const char *) pubid);
4178: if (count < 0)
4179: return -1;
4180: sum += count;
4181: count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4182: if (count < 0)
4183: return -1;
4184: sum += count;
4185: }
4186:
4187: if (sysid != 0) {
4188: if (pubid == 0) {
4189: count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
4190: if (count < 0)
4191: return -1;
4192: sum += count;
4193: }
4194: count = xmlOutputBufferWriteString(writer->out, " ");
4195: if (count < 0)
4196: return -1;
4197: sum += count;
4198: count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4199: if (count < 0)
4200: return -1;
4201: sum += count;
4202: count =
4203: xmlOutputBufferWriteString(writer->out, (const char *) sysid);
4204: if (count < 0)
4205: return -1;
4206: sum += count;
4207: count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
4208: if (count < 0)
4209: return -1;
4210: sum += count;
4211: }
4212:
4213: count = xmlOutputBufferWriteString(writer->out, ">");
4214: if (count < 0)
4215: return -1;
4216: sum += count;
4217:
4218: return sum;
4219: }
4220:
4221: /**
4222: * xmlTextWriterFlush:
4223: * @writer: the xmlTextWriterPtr
4224: *
4225: * Flush the output buffer.
4226: *
4227: * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
4228: */
4229: int
4230: xmlTextWriterFlush(xmlTextWriterPtr writer)
4231: {
4232: int count;
4233:
4234: if (writer == NULL)
4235: return -1;
4236:
4237: if (writer->out == NULL)
4238: count = 0;
4239: else
4240: count = xmlOutputBufferFlush(writer->out);
4241:
4242: return count;
4243: }
4244:
4245: /**
4246: * misc
4247: */
4248:
4249: /**
4250: * xmlFreeTextWriterStackEntry:
4251: * @lk: the xmlLinkPtr
4252: *
4253: * Free callback for the xmlList.
4254: */
4255: static void
4256: xmlFreeTextWriterStackEntry(xmlLinkPtr lk)
4257: {
4258: xmlTextWriterStackEntry *p;
4259:
4260: p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
4261: if (p == 0)
4262: return;
4263:
4264: if (p->name != 0)
4265: xmlFree(p->name);
4266: xmlFree(p);
4267: }
4268:
4269: /**
4270: * xmlCmpTextWriterStackEntry:
4271: * @data0: the first data
4272: * @data1: the second data
4273: *
4274: * Compare callback for the xmlList.
4275: *
4276: * Returns -1, 0, 1
4277: */
4278: static int
4279: xmlCmpTextWriterStackEntry(const void *data0, const void *data1)
4280: {
4281: xmlTextWriterStackEntry *p0;
4282: xmlTextWriterStackEntry *p1;
4283:
4284: if (data0 == data1)
4285: return 0;
4286:
4287: if (data0 == 0)
4288: return -1;
4289:
4290: if (data1 == 0)
4291: return 1;
4292:
4293: p0 = (xmlTextWriterStackEntry *) data0;
4294: p1 = (xmlTextWriterStackEntry *) data1;
4295:
4296: return xmlStrcmp(p0->name, p1->name);
4297: }
4298:
4299: /**
4300: * misc
4301: */
4302:
4303: /**
4304: * xmlTextWriterOutputNSDecl:
4305: * @writer: the xmlTextWriterPtr
4306: *
4307: * Output the current namespace declarations.
4308: */
4309: static int
4310: xmlTextWriterOutputNSDecl(xmlTextWriterPtr writer)
4311: {
4312: xmlLinkPtr lk;
4313: xmlTextWriterNsStackEntry *np;
4314: int count;
4315: int sum;
4316:
4317: sum = 0;
4318: while (!xmlListEmpty(writer->nsstack)) {
4319: xmlChar *namespaceURI = NULL;
4320: xmlChar *prefix = NULL;
4321:
4322: lk = xmlListFront(writer->nsstack);
4323: np = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
4324:
4325: if (np != 0) {
4326: namespaceURI = xmlStrdup(np->uri);
4327: prefix = xmlStrdup(np->prefix);
4328: }
4329:
4330: xmlListPopFront(writer->nsstack);
4331:
4332: if (np != 0) {
4333: count = xmlTextWriterWriteAttribute(writer, prefix, namespaceURI);
4334: xmlFree(namespaceURI);
4335: xmlFree(prefix);
4336:
4337: if (count < 0) {
4338: xmlListDelete(writer->nsstack);
4339: writer->nsstack = NULL;
4340: return -1;
4341: }
4342: sum += count;
4343: }
4344: }
4345: return sum;
4346: }
4347:
4348: /**
4349: * xmlFreeTextWriterNsStackEntry:
4350: * @lk: the xmlLinkPtr
4351: *
4352: * Free callback for the xmlList.
4353: */
4354: static void
4355: xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk)
4356: {
4357: xmlTextWriterNsStackEntry *p;
4358:
4359: p = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
4360: if (p == 0)
4361: return;
4362:
4363: if (p->prefix != 0)
4364: xmlFree(p->prefix);
4365: if (p->uri != 0)
4366: xmlFree(p->uri);
4367:
4368: xmlFree(p);
4369: }
4370:
4371: /**
4372: * xmlCmpTextWriterNsStackEntry:
4373: * @data0: the first data
4374: * @data1: the second data
4375: *
4376: * Compare callback for the xmlList.
4377: *
4378: * Returns -1, 0, 1
4379: */
4380: static int
4381: xmlCmpTextWriterNsStackEntry(const void *data0, const void *data1)
4382: {
4383: xmlTextWriterNsStackEntry *p0;
4384: xmlTextWriterNsStackEntry *p1;
4385: int rc;
4386:
4387: if (data0 == data1)
4388: return 0;
4389:
4390: if (data0 == 0)
4391: return -1;
4392:
4393: if (data1 == 0)
4394: return 1;
4395:
4396: p0 = (xmlTextWriterNsStackEntry *) data0;
4397: p1 = (xmlTextWriterNsStackEntry *) data1;
4398:
4399: rc = xmlStrcmp(p0->prefix, p1->prefix);
4400:
4401: if ((rc != 0) || (p0->elem != p1->elem))
4402: rc = -1;
4403:
4404: return rc;
4405: }
4406:
4407: /**
4408: * xmlTextWriterWriteDocCallback:
4409: * @context: the xmlBufferPtr
4410: * @str: the data to write
4411: * @len: the length of the data
4412: *
4413: * Write callback for the xmlOutputBuffer with target xmlBuffer
4414: *
4415: * Returns -1, 0, 1
4416: */
4417: static int
4418: xmlTextWriterWriteDocCallback(void *context, const xmlChar * str, int len)
4419: {
4420: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context;
4421: int rc;
4422:
4423: if ((rc = xmlParseChunk(ctxt, (const char *) str, len, 0)) != 0) {
4424: xmlWriterErrMsgInt(NULL, XML_ERR_INTERNAL_ERROR,
4425: "xmlTextWriterWriteDocCallback : XML error %d !\n",
4426: rc);
4427: return -1;
4428: }
4429:
4430: return len;
4431: }
4432:
4433: /**
4434: * xmlTextWriterCloseDocCallback:
4435: * @context: the xmlBufferPtr
4436: *
4437: * Close callback for the xmlOutputBuffer with target xmlBuffer
4438: *
4439: * Returns -1, 0, 1
4440: */
4441: static int
4442: xmlTextWriterCloseDocCallback(void *context)
4443: {
4444: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context;
4445: int rc;
4446:
4447: if ((rc = xmlParseChunk(ctxt, NULL, 0, 1)) != 0) {
4448: xmlWriterErrMsgInt(NULL, XML_ERR_INTERNAL_ERROR,
4449: "xmlTextWriterWriteDocCallback : XML error %d !\n",
4450: rc);
4451: return -1;
4452: }
4453:
4454: return 0;
4455: }
4456:
4457: /**
4458: * xmlTextWriterVSprintf:
4459: * @format: see printf
4460: * @argptr: pointer to the first member of the variable argument list.
4461: *
4462: * Utility function for formatted output
4463: *
4464: * Returns a new xmlChar buffer with the data or NULL on error. This buffer must be freed.
4465: */
4466: static xmlChar *
4467: xmlTextWriterVSprintf(const char *format, va_list argptr)
4468: {
4469: int size;
4470: int count;
4471: xmlChar *buf;
4472: va_list locarg;
4473:
4474: size = BUFSIZ;
4475: buf = (xmlChar *) xmlMalloc(size);
4476: if (buf == NULL) {
4477: xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
4478: "xmlTextWriterVSprintf : out of memory!\n");
4479: return NULL;
4480: }
4481:
4482: VA_COPY(locarg, argptr);
4483: while (((count = vsnprintf((char *) buf, size, format, locarg)) < 0)
4484: || (count == size - 1) || (count == size) || (count > size)) {
4485: va_end(locarg);
4486: xmlFree(buf);
4487: size += BUFSIZ;
4488: buf = (xmlChar *) xmlMalloc(size);
4489: if (buf == NULL) {
4490: xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
4491: "xmlTextWriterVSprintf : out of memory!\n");
4492: return NULL;
4493: }
4494: VA_COPY(locarg, argptr);
4495: }
4496: va_end(locarg);
4497:
4498: return buf;
4499: }
4500:
4501: /**
4502: * xmlTextWriterStartDocumentCallback:
4503: * @ctx: the user data (XML parser context)
4504: *
4505: * called at the start of document processing.
4506: */
4507: static void
4508: xmlTextWriterStartDocumentCallback(void *ctx)
4509: {
4510: xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
4511: xmlDocPtr doc;
4512:
4513: if (ctxt->html) {
4514: #ifdef LIBXML_HTML_ENABLED
4515: if (ctxt->myDoc == NULL)
4516: ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
4517: if (ctxt->myDoc == NULL) {
4518: if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
4519: ctxt->sax->error(ctxt->userData,
4520: "SAX.startDocument(): out of memory\n");
4521: ctxt->errNo = XML_ERR_NO_MEMORY;
4522: ctxt->instate = XML_PARSER_EOF;
4523: ctxt->disableSAX = 1;
4524: return;
4525: }
4526: #else
4527: xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
4528: "libxml2 built without HTML support\n");
4529: ctxt->errNo = XML_ERR_INTERNAL_ERROR;
4530: ctxt->instate = XML_PARSER_EOF;
4531: ctxt->disableSAX = 1;
4532: return;
4533: #endif
4534: } else {
4535: doc = ctxt->myDoc;
4536: if (doc == NULL)
4537: doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
4538: if (doc != NULL) {
4539: if (doc->children == NULL) {
4540: if (ctxt->encoding != NULL)
4541: doc->encoding = xmlStrdup(ctxt->encoding);
4542: else
4543: doc->encoding = NULL;
4544: doc->standalone = ctxt->standalone;
4545: }
4546: } else {
4547: if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
4548: ctxt->sax->error(ctxt->userData,
4549: "SAX.startDocument(): out of memory\n");
4550: ctxt->errNo = XML_ERR_NO_MEMORY;
4551: ctxt->instate = XML_PARSER_EOF;
4552: ctxt->disableSAX = 1;
4553: return;
4554: }
4555: }
4556: if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) &&
4557: (ctxt->input != NULL) && (ctxt->input->filename != NULL)) {
4558: ctxt->myDoc->URL =
4559: xmlCanonicPath((const xmlChar *) ctxt->input->filename);
4560: if (ctxt->myDoc->URL == NULL)
4561: ctxt->myDoc->URL =
4562: xmlStrdup((const xmlChar *) ctxt->input->filename);
4563: }
4564: }
4565:
4566: /**
4567: * xmlTextWriterSetIndent:
4568: * @writer: the xmlTextWriterPtr
4569: * @indent: do indentation?
4570: *
4571: * Set indentation output. indent = 0 do not indentation. indent > 0 do indentation.
4572: *
4573: * Returns -1 on error or 0 otherwise.
4574: */
4575: int
4576: xmlTextWriterSetIndent(xmlTextWriterPtr writer, int indent)
4577: {
4578: if ((writer == NULL) || (indent < 0))
4579: return -1;
4580:
4581: writer->indent = indent;
4582: writer->doindent = 1;
4583:
4584: return 0;
4585: }
4586:
4587: /**
4588: * xmlTextWriterSetIndentString:
4589: * @writer: the xmlTextWriterPtr
4590: * @str: the xmlChar string
4591: *
4592: * Set string indentation.
4593: *
4594: * Returns -1 on error or 0 otherwise.
4595: */
4596: int
4597: xmlTextWriterSetIndentString(xmlTextWriterPtr writer, const xmlChar * str)
4598: {
4599: if ((writer == NULL) || (!str))
4600: return -1;
4601:
4602: if (writer->ichar != NULL)
4603: xmlFree(writer->ichar);
4604: writer->ichar = xmlStrdup(str);
4605:
4606: if (!writer->ichar)
4607: return -1;
4608: else
4609: return 0;
4610: }
4611:
4612: /**
1.1.1.2 ! misho 4613: * xmlTextWriterSetQuoteChar:
! 4614: * @writer: the xmlTextWriterPtr
! 4615: * @quotechar: the quote character
! 4616: *
! 4617: * Set the character used for quoting attributes.
! 4618: *
! 4619: * Returns -1 on error or 0 otherwise.
! 4620: */
! 4621: int
! 4622: xmlTextWriterSetQuoteChar(xmlTextWriterPtr writer, xmlChar quotechar)
! 4623: {
! 4624: if ((writer == NULL) || ((quotechar != '\'') && (quotechar != '"')))
! 4625: return -1;
! 4626:
! 4627: writer->qchar = quotechar;
! 4628:
! 4629: return 0;
! 4630: }
! 4631:
! 4632: /**
1.1 misho 4633: * xmlTextWriterWriteIndent:
4634: * @writer: the xmlTextWriterPtr
4635: *
4636: * Write indent string.
4637: *
4638: * Returns -1 on error or the number of strings written.
4639: */
4640: static int
4641: xmlTextWriterWriteIndent(xmlTextWriterPtr writer)
4642: {
4643: int lksize;
4644: int i;
4645: int ret;
4646:
4647: lksize = xmlListSize(writer->nodes);
4648: if (lksize < 1)
4649: return (-1); /* list is empty */
4650: for (i = 0; i < (lksize - 1); i++) {
4651: ret = xmlOutputBufferWriteString(writer->out,
4652: (const char *) writer->ichar);
4653: if (ret == -1)
4654: return (-1);
4655: }
4656:
4657: return (lksize - 1);
4658: }
4659:
4660: /**
4661: * xmlTextWriterHandleStateDependencies:
4662: * @writer: the xmlTextWriterPtr
4663: * @p: the xmlTextWriterStackEntry
4664: *
4665: * Write state dependent strings.
4666: *
4667: * Returns -1 on error or the number of characters written.
4668: */
4669: static int
4670: xmlTextWriterHandleStateDependencies(xmlTextWriterPtr writer,
4671: xmlTextWriterStackEntry * p)
4672: {
4673: int count;
4674: int sum;
4675: char extra[3];
4676:
4677: if (writer == NULL)
4678: return -1;
4679:
4680: if (p == NULL)
4681: return 0;
4682:
4683: sum = 0;
4684: extra[0] = extra[1] = extra[2] = '\0';
4685: if (p != 0) {
4686: sum = 0;
4687: switch (p->state) {
4688: case XML_TEXTWRITER_NAME:
4689: /* Output namespace declarations */
4690: count = xmlTextWriterOutputNSDecl(writer);
4691: if (count < 0)
4692: return -1;
4693: sum += count;
4694: extra[0] = '>';
4695: p->state = XML_TEXTWRITER_TEXT;
4696: break;
4697: case XML_TEXTWRITER_PI:
4698: extra[0] = ' ';
4699: p->state = XML_TEXTWRITER_PI_TEXT;
4700: break;
4701: case XML_TEXTWRITER_DTD:
4702: extra[0] = ' ';
4703: extra[1] = '[';
4704: p->state = XML_TEXTWRITER_DTD_TEXT;
4705: break;
4706: case XML_TEXTWRITER_DTD_ELEM:
4707: extra[0] = ' ';
4708: p->state = XML_TEXTWRITER_DTD_ELEM_TEXT;
4709: break;
4710: case XML_TEXTWRITER_DTD_ATTL:
4711: extra[0] = ' ';
4712: p->state = XML_TEXTWRITER_DTD_ATTL_TEXT;
4713: break;
4714: case XML_TEXTWRITER_DTD_ENTY:
4715: case XML_TEXTWRITER_DTD_PENT:
4716: extra[0] = ' ';
4717: extra[1] = writer->qchar;
4718: p->state = XML_TEXTWRITER_DTD_ENTY_TEXT;
4719: break;
4720: default:
4721: break;
4722: }
4723: }
4724:
4725: if (*extra != '\0') {
4726: count = xmlOutputBufferWriteString(writer->out, extra);
4727: if (count < 0)
4728: return -1;
4729: sum += count;
4730: }
4731:
4732: return sum;
4733: }
4734:
4735: #define bottom_xmlwriter
4736: #include "elfgcchack.h"
4737: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>