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