| /* | |
| * xmlwriter.c: XML text writer implementation | |
| * | |
| * For license and disclaimer see the license and disclaimer of | |
| * libxml2. | |
| * | |
| * alfred@mickautsch.de | |
| */ | |
| #define IN_LIBXML | |
| #include "libxml.h" | |
| #include <string.h> | |
| #include <libxml/xmlmemory.h> | |
| #include <libxml/parser.h> | |
| #include <libxml/uri.h> | |
| #include <libxml/HTMLtree.h> | |
| #ifdef LIBXML_WRITER_ENABLED | |
| #include <libxml/xmlwriter.h> | |
| #include "buf.h" | |
| #include "enc.h" | |
| #include "save.h" | |
| #define B64LINELEN 72 | |
| #define B64CRLF "\r\n" | |
| /* | |
| * The following VA_COPY was coded following an example in | |
| * the Samba project. It may not be sufficient for some | |
| * esoteric implementations of va_list but (hopefully) will | |
| * be sufficient for libxml2. | |
| */ | |
| #ifndef VA_COPY | |
| #ifdef HAVE_VA_COPY | |
| #define VA_COPY(dest, src) va_copy(dest, src) | |
| #else | |
| #ifdef HAVE___VA_COPY | |
| #define VA_COPY(dest,src) __va_copy(dest, src) | |
| #else | |
| #ifndef VA_LIST_IS_ARRAY | |
| #define VA_COPY(dest,src) (dest) = (src) | |
| #else | |
| #include <string.h> | |
| #define VA_COPY(dest,src) memcpy((char *)(dest),(char *)(src),sizeof(va_list)) | |
| #endif | |
| #endif | |
| #endif | |
| #endif | |
| /* | |
| * Types are kept private | |
| */ | |
| typedef enum { | |
| XML_TEXTWRITER_NONE = 0, | |
| XML_TEXTWRITER_NAME, | |
| XML_TEXTWRITER_ATTRIBUTE, | |
| XML_TEXTWRITER_TEXT, | |
| XML_TEXTWRITER_PI, | |
| XML_TEXTWRITER_PI_TEXT, | |
| XML_TEXTWRITER_CDATA, | |
| XML_TEXTWRITER_DTD, | |
| XML_TEXTWRITER_DTD_TEXT, | |
| XML_TEXTWRITER_DTD_ELEM, | |
| XML_TEXTWRITER_DTD_ELEM_TEXT, | |
| XML_TEXTWRITER_DTD_ATTL, | |
| XML_TEXTWRITER_DTD_ATTL_TEXT, | |
| XML_TEXTWRITER_DTD_ENTY, /* entity */ | |
| XML_TEXTWRITER_DTD_ENTY_TEXT, | |
| XML_TEXTWRITER_DTD_PENT, /* parameter entity */ | |
| XML_TEXTWRITER_COMMENT | |
| } xmlTextWriterState; | |
| typedef struct _xmlTextWriterStackEntry xmlTextWriterStackEntry; | |
| struct _xmlTextWriterStackEntry { | |
| xmlChar *name; | |
| xmlTextWriterState state; | |
| }; | |
| typedef struct _xmlTextWriterNsStackEntry xmlTextWriterNsStackEntry; | |
| struct _xmlTextWriterNsStackEntry { | |
| xmlChar *prefix; | |
| xmlChar *uri; | |
| xmlLinkPtr elem; | |
| }; | |
| struct _xmlTextWriter { | |
| xmlOutputBufferPtr out; /* output buffer */ | |
| xmlListPtr nodes; /* element name stack */ | |
| xmlListPtr nsstack; /* name spaces stack */ | |
| int level; | |
| int indent; /* enable indent */ | |
| int doindent; /* internal indent flag */ | |
| xmlChar *ichar; /* indent character */ | |
| char qchar; /* character used for quoting attribute values */ | |
| xmlParserCtxtPtr ctxt; | |
| int no_doc_free; | |
| xmlDocPtr doc; | |
| }; | |
| static void xmlFreeTextWriterStackEntry(xmlLinkPtr lk); | |
| static int xmlCmpTextWriterStackEntry(const void *data0, | |
| const void *data1); | |
| static int xmlTextWriterOutputNSDecl(xmlTextWriterPtr writer); | |
| static void xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk); | |
| static int xmlCmpTextWriterNsStackEntry(const void *data0, | |
| const void *data1); | |
| static int xmlTextWriterWriteDocCallback(void *context, | |
| const xmlChar * str, int len); | |
| static int xmlTextWriterCloseDocCallback(void *context); | |
| static xmlChar *xmlTextWriterVSprintf(const char *format, va_list argptr) LIBXML_ATTR_FORMAT(1,0); | |
| static int xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len, | |
| const unsigned char *data); | |
| static void xmlTextWriterStartDocumentCallback(void *ctx); | |
| static int xmlTextWriterWriteIndent(xmlTextWriterPtr writer); | |
| static int | |
| xmlTextWriterHandleStateDependencies(xmlTextWriterPtr writer, | |
| xmlTextWriterStackEntry * p); | |
| /** | |
| * xmlWriterErrMsg: | |
| * @ctxt: a writer context | |
| * @error: the error number | |
| * @msg: the error message | |
| * | |
| * Handle a writer error | |
| */ | |
| static void | |
| xmlWriterErrMsg(xmlTextWriterPtr ctxt, xmlParserErrors error, | |
| const char *msg) | |
| { | |
| if (ctxt != NULL) { | |
| __xmlRaiseError(NULL, NULL, NULL, ctxt->ctxt, | |
| NULL, XML_FROM_WRITER, error, XML_ERR_FATAL, | |
| NULL, 0, NULL, NULL, NULL, 0, 0, "%s", msg); | |
| } else { | |
| __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_WRITER, error, | |
| XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, 0, 0, "%s", msg); | |
| } | |
| } | |
| /** | |
| * xmlWriterErrMsgInt: | |
| * @ctxt: a writer context | |
| * @error: the error number | |
| * @msg: the error message | |
| * @val: an int | |
| * | |
| * Handle a writer error | |
| */ | |
| static void LIBXML_ATTR_FORMAT(3,0) | |
| xmlWriterErrMsgInt(xmlTextWriterPtr ctxt, xmlParserErrors error, | |
| const char *msg, int val) | |
| { | |
| if (ctxt != NULL) { | |
| __xmlRaiseError(NULL, NULL, NULL, ctxt->ctxt, | |
| NULL, XML_FROM_WRITER, error, XML_ERR_FATAL, | |
| NULL, 0, NULL, NULL, NULL, val, 0, msg, val); | |
| } else { | |
| __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_WRITER, error, | |
| XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, val, 0, msg, val); | |
| } | |
| } | |
| /** | |
| * xmlNewTextWriter: | |
| * @out: an xmlOutputBufferPtr | |
| * | |
| * Create a new xmlNewTextWriter structure using an xmlOutputBufferPtr | |
| * NOTE: the @out parameter will be deallocated when the writer is closed | |
| * (if the call succeed.) | |
| * | |
| * Returns the new xmlTextWriterPtr or NULL in case of error | |
| */ | |
| xmlTextWriterPtr | |
| xmlNewTextWriter(xmlOutputBufferPtr out) | |
| { | |
| xmlTextWriterPtr ret; | |
| ret = (xmlTextWriterPtr) xmlMalloc(sizeof(xmlTextWriter)); | |
| if (ret == NULL) { | |
| xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY, | |
| "xmlNewTextWriter : out of memory!\n"); | |
| return NULL; | |
| } | |
| memset(ret, 0, (size_t) sizeof(xmlTextWriter)); | |
| ret->nodes = xmlListCreate((xmlListDeallocator) | |
| xmlFreeTextWriterStackEntry, | |
| (xmlListDataCompare) | |
| xmlCmpTextWriterStackEntry); | |
| if (ret->nodes == NULL) { | |
| xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY, | |
| "xmlNewTextWriter : out of memory!\n"); | |
| xmlFree(ret); | |
| return NULL; | |
| } | |
| ret->nsstack = xmlListCreate((xmlListDeallocator) | |
| xmlFreeTextWriterNsStackEntry, | |
| (xmlListDataCompare) | |
| xmlCmpTextWriterNsStackEntry); | |
| if (ret->nsstack == NULL) { | |
| xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY, | |
| "xmlNewTextWriter : out of memory!\n"); | |
| xmlListDelete(ret->nodes); | |
| xmlFree(ret); | |
| return NULL; | |
| } | |
| ret->out = out; | |
| ret->ichar = xmlStrdup(BAD_CAST " "); | |
| ret->qchar = '"'; | |
| if (!ret->ichar) { | |
| xmlListDelete(ret->nodes); | |
| xmlListDelete(ret->nsstack); | |
| xmlFree(ret); | |
| xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY, | |
| "xmlNewTextWriter : out of memory!\n"); | |
| return NULL; | |
| } | |
| ret->doc = xmlNewDoc(NULL); | |
| ret->no_doc_free = 0; | |
| return ret; | |
| } | |
| /** | |
| * xmlNewTextWriterFilename: | |
| * @uri: the URI of the resource for the output | |
| * @compression: compress the output? | |
| * | |
| * Create a new xmlNewTextWriter structure with @uri as output | |
| * | |
| * Returns the new xmlTextWriterPtr or NULL in case of error | |
| */ | |
| xmlTextWriterPtr | |
| xmlNewTextWriterFilename(const char *uri, int compression) | |
| { | |
| xmlTextWriterPtr ret; | |
| xmlOutputBufferPtr out; | |
| out = xmlOutputBufferCreateFilename(uri, NULL, compression); | |
| if (out == NULL) { | |
| xmlWriterErrMsg(NULL, XML_IO_EIO, | |
| "xmlNewTextWriterFilename : cannot open uri\n"); | |
| return NULL; | |
| } | |
| ret = xmlNewTextWriter(out); | |
| if (ret == NULL) { | |
| xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY, | |
| "xmlNewTextWriterFilename : out of memory!\n"); | |
| xmlOutputBufferClose(out); | |
| return NULL; | |
| } | |
| ret->indent = 0; | |
| ret->doindent = 0; | |
| return ret; | |
| } | |
| /** | |
| * xmlNewTextWriterMemory: | |
| * @buf: xmlBufferPtr | |
| * @compression: compress the output? | |
| * | |
| * Create a new xmlNewTextWriter structure with @buf as output | |
| * TODO: handle compression | |
| * | |
| * Returns the new xmlTextWriterPtr or NULL in case of error | |
| */ | |
| xmlTextWriterPtr | |
| xmlNewTextWriterMemory(xmlBufferPtr buf, int compression ATTRIBUTE_UNUSED) | |
| { | |
| xmlTextWriterPtr ret; | |
| xmlOutputBufferPtr out; | |
| /*::todo handle compression */ | |
| out = xmlOutputBufferCreateBuffer(buf, NULL); | |
| if (out == NULL) { | |
| xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY, | |
| "xmlNewTextWriterMemory : out of memory!\n"); | |
| return NULL; | |
| } | |
| ret = xmlNewTextWriter(out); | |
| if (ret == NULL) { | |
| xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY, | |
| "xmlNewTextWriterMemory : out of memory!\n"); | |
| xmlOutputBufferClose(out); | |
| return NULL; | |
| } | |
| return ret; | |
| } | |
| /** | |
| * xmlNewTextWriterPushParser: | |
| * @ctxt: xmlParserCtxtPtr to hold the new XML document tree | |
| * @compression: compress the output? | |
| * | |
| * Create a new xmlNewTextWriter structure with @ctxt as output | |
| * NOTE: the @ctxt context will be freed with the resulting writer | |
| * (if the call succeeds). | |
| * TODO: handle compression | |
| * | |
| * Returns the new xmlTextWriterPtr or NULL in case of error | |
| */ | |
| xmlTextWriterPtr | |
| xmlNewTextWriterPushParser(xmlParserCtxtPtr ctxt, | |
| int compression ATTRIBUTE_UNUSED) | |
| { | |
| xmlTextWriterPtr ret; | |
| xmlOutputBufferPtr out; | |
| if (ctxt == NULL) { | |
| xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR, | |
| "xmlNewTextWriterPushParser : invalid context!\n"); | |
| return NULL; | |
| } | |
| out = xmlOutputBufferCreateIO((xmlOutputWriteCallback) | |
| xmlTextWriterWriteDocCallback, | |
| (xmlOutputCloseCallback) | |
| xmlTextWriterCloseDocCallback, | |
| (void *) ctxt, NULL); | |
| if (out == NULL) { | |
| xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR, | |
| "xmlNewTextWriterPushParser : error at xmlOutputBufferCreateIO!\n"); | |
| return NULL; | |
| } | |
| ret = xmlNewTextWriter(out); | |
| if (ret == NULL) { | |
| xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR, | |
| "xmlNewTextWriterPushParser : error at xmlNewTextWriter!\n"); | |
| xmlOutputBufferClose(out); | |
| return NULL; | |
| } | |
| ret->ctxt = ctxt; | |
| return ret; | |
| } | |
| /** | |
| * xmlNewTextWriterDoc: | |
| * @doc: address of a xmlDocPtr to hold the new XML document tree | |
| * @compression: compress the output? | |
| * | |
| * Create a new xmlNewTextWriter structure with @*doc as output | |
| * | |
| * Returns the new xmlTextWriterPtr or NULL in case of error | |
| */ | |
| xmlTextWriterPtr | |
| xmlNewTextWriterDoc(xmlDocPtr * doc, int compression) | |
| { | |
| xmlTextWriterPtr ret; | |
| xmlSAXHandler saxHandler; | |
| xmlParserCtxtPtr ctxt; | |
| memset(&saxHandler, '\0', sizeof(saxHandler)); | |
| xmlSAX2InitDefaultSAXHandler(&saxHandler, 1); | |
| saxHandler.startDocument = xmlTextWriterStartDocumentCallback; | |
| saxHandler.startElement = xmlSAX2StartElement; | |
| saxHandler.endElement = xmlSAX2EndElement; | |
| ctxt = xmlCreatePushParserCtxt(&saxHandler, NULL, NULL, 0, NULL); | |
| if (ctxt == NULL) { | |
| xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR, | |
| "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\n"); | |
| return NULL; | |
| } | |
| /* | |
| * For some reason this seems to completely break if node names | |
| * are interned. | |
| */ | |
| ctxt->dictNames = 0; | |
| ctxt->myDoc = xmlNewDoc(BAD_CAST XML_DEFAULT_VERSION); | |
| if (ctxt->myDoc == NULL) { | |
| xmlFreeParserCtxt(ctxt); | |
| xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR, | |
| "xmlNewTextWriterDoc : error at xmlNewDoc!\n"); | |
| return NULL; | |
| } | |
| ret = xmlNewTextWriterPushParser(ctxt, compression); | |
| if (ret == NULL) { | |
| xmlFreeDoc(ctxt->myDoc); | |
| xmlFreeParserCtxt(ctxt); | |
| xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR, | |
| "xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n"); | |
| return NULL; | |
| } | |
| xmlSetDocCompressMode(ctxt->myDoc, compression); | |
| if (doc != NULL) { | |
| *doc = ctxt->myDoc; | |
| ret->no_doc_free = 1; | |
| } | |
| return ret; | |
| } | |
| /** | |
| * xmlNewTextWriterTree: | |
| * @doc: xmlDocPtr | |
| * @node: xmlNodePtr or NULL for doc->children | |
| * @compression: compress the output? | |
| * | |
| * Create a new xmlNewTextWriter structure with @doc as output | |
| * starting at @node | |
| * | |
| * Returns the new xmlTextWriterPtr or NULL in case of error | |
| */ | |
| xmlTextWriterPtr | |
| xmlNewTextWriterTree(xmlDocPtr doc, xmlNodePtr node, int compression) | |
| { | |
| xmlTextWriterPtr ret; | |
| xmlSAXHandler saxHandler; | |
| xmlParserCtxtPtr ctxt; | |
| if (doc == NULL) { | |
| xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR, | |
| "xmlNewTextWriterTree : invalid document tree!\n"); | |
| return NULL; | |
| } | |
| memset(&saxHandler, '\0', sizeof(saxHandler)); | |
| xmlSAX2InitDefaultSAXHandler(&saxHandler, 1); | |
| saxHandler.startDocument = xmlTextWriterStartDocumentCallback; | |
| saxHandler.startElement = xmlSAX2StartElement; | |
| saxHandler.endElement = xmlSAX2EndElement; | |
| ctxt = xmlCreatePushParserCtxt(&saxHandler, NULL, NULL, 0, NULL); | |
| if (ctxt == NULL) { | |
| xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR, | |
| "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\n"); | |
| return NULL; | |
| } | |
| /* | |
| * For some reason this seems to completely break if node names | |
| * are interned. | |
| */ | |
| ctxt->dictNames = 0; | |
| ret = xmlNewTextWriterPushParser(ctxt, compression); | |
| if (ret == NULL) { | |
| xmlFreeParserCtxt(ctxt); | |
| xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR, | |
| "xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n"); | |
| return NULL; | |
| } | |
| ctxt->myDoc = doc; | |
| ctxt->node = node; | |
| ret->no_doc_free = 1; | |
| xmlSetDocCompressMode(doc, compression); | |
| return ret; | |
| } | |
| /** | |
| * xmlFreeTextWriter: | |
| * @writer: the xmlTextWriterPtr | |
| * | |
| * Deallocate all the resources associated to the writer | |
| */ | |
| void | |
| xmlFreeTextWriter(xmlTextWriterPtr writer) | |
| { | |
| if (writer == NULL) | |
| return; | |
| if (writer->out != NULL) | |
| xmlOutputBufferClose(writer->out); | |
| if (writer->nodes != NULL) | |
| xmlListDelete(writer->nodes); | |
| if (writer->nsstack != NULL) | |
| xmlListDelete(writer->nsstack); | |
| if (writer->ctxt != NULL) { | |
| if ((writer->ctxt->myDoc != NULL) && (writer->no_doc_free == 0)) { | |
| xmlFreeDoc(writer->ctxt->myDoc); | |
| writer->ctxt->myDoc = NULL; | |
| } | |
| xmlFreeParserCtxt(writer->ctxt); | |
| } | |
| if (writer->doc != NULL) | |
| xmlFreeDoc(writer->doc); | |
| if (writer->ichar != NULL) | |
| xmlFree(writer->ichar); | |
| xmlFree(writer); | |
| } | |
| /** | |
| * xmlTextWriterStartDocument: | |
| * @writer: the xmlTextWriterPtr | |
| * @version: the xml version ("1.0") or NULL for default ("1.0") | |
| * @encoding: the encoding or NULL for default | |
| * @standalone: "yes" or "no" or NULL for default | |
| * | |
| * Start a new xml document | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterStartDocument(xmlTextWriterPtr writer, const char *version, | |
| const char *encoding, const char *standalone) | |
| { | |
| int count; | |
| int sum; | |
| xmlLinkPtr lk; | |
| xmlCharEncodingHandlerPtr encoder; | |
| if ((writer == NULL) || (writer->out == NULL)) { | |
| xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, | |
| "xmlTextWriterStartDocument : invalid writer!\n"); | |
| return -1; | |
| } | |
| lk = xmlListFront(writer->nodes); | |
| if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) { | |
| xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, | |
| "xmlTextWriterStartDocument : not allowed in this context!\n"); | |
| return -1; | |
| } | |
| encoder = NULL; | |
| if (encoding != NULL) { | |
| encoder = xmlFindCharEncodingHandler(encoding); | |
| if (encoder == NULL) { | |
| xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, | |
| "xmlTextWriterStartDocument : out of memory!\n"); | |
| return -1; | |
| } | |
| } | |
| writer->out->encoder = encoder; | |
| if (encoder != NULL) { | |
| if (writer->out->conv == NULL) { | |
| writer->out->conv = xmlBufCreateSize(4000); | |
| } | |
| xmlCharEncOutput(writer->out, 1); | |
| if ((writer->doc != NULL) && (writer->doc->encoding == NULL)) | |
| writer->doc->encoding = xmlStrdup((xmlChar *)writer->out->encoder->name); | |
| } else | |
| writer->out->conv = NULL; | |
| sum = 0; | |
| count = xmlOutputBufferWriteString(writer->out, "<?xml version="); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| if (version != 0) | |
| count = xmlOutputBufferWriteString(writer->out, version); | |
| else | |
| count = xmlOutputBufferWriteString(writer->out, "1.0"); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| if (writer->out->encoder != 0) { | |
| count = xmlOutputBufferWriteString(writer->out, " encoding="); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = | |
| xmlOutputBufferWriteString(writer->out, | |
| writer->out->encoder->name); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| } | |
| if (standalone != 0) { | |
| count = xmlOutputBufferWriteString(writer->out, " standalone="); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlOutputBufferWriteString(writer->out, standalone); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| } | |
| count = xmlOutputBufferWriteString(writer->out, "?>\n"); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| return sum; | |
| } | |
| /** | |
| * xmlTextWriterEndDocument: | |
| * @writer: the xmlTextWriterPtr | |
| * | |
| * End an xml document. All open elements are closed, and | |
| * the content is flushed to the output. | |
| * | |
| * Returns the bytes written or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterEndDocument(xmlTextWriterPtr writer) | |
| { | |
| int count; | |
| int sum; | |
| xmlLinkPtr lk; | |
| xmlTextWriterStackEntry *p; | |
| if (writer == NULL) { | |
| xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, | |
| "xmlTextWriterEndDocument : invalid writer!\n"); | |
| return -1; | |
| } | |
| sum = 0; | |
| while ((lk = xmlListFront(writer->nodes)) != NULL) { | |
| p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); | |
| if (p == 0) | |
| break; | |
| switch (p->state) { | |
| case XML_TEXTWRITER_NAME: | |
| case XML_TEXTWRITER_ATTRIBUTE: | |
| case XML_TEXTWRITER_TEXT: | |
| count = xmlTextWriterEndElement(writer); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| break; | |
| case XML_TEXTWRITER_PI: | |
| case XML_TEXTWRITER_PI_TEXT: | |
| count = xmlTextWriterEndPI(writer); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| break; | |
| case XML_TEXTWRITER_CDATA: | |
| count = xmlTextWriterEndCDATA(writer); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| break; | |
| case XML_TEXTWRITER_DTD: | |
| case XML_TEXTWRITER_DTD_TEXT: | |
| case XML_TEXTWRITER_DTD_ELEM: | |
| case XML_TEXTWRITER_DTD_ELEM_TEXT: | |
| case XML_TEXTWRITER_DTD_ATTL: | |
| case XML_TEXTWRITER_DTD_ATTL_TEXT: | |
| case XML_TEXTWRITER_DTD_ENTY: | |
| case XML_TEXTWRITER_DTD_ENTY_TEXT: | |
| case XML_TEXTWRITER_DTD_PENT: | |
| count = xmlTextWriterEndDTD(writer); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| break; | |
| case XML_TEXTWRITER_COMMENT: | |
| count = xmlTextWriterEndComment(writer); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| break; | |
| default: | |
| break; | |
| } | |
| } | |
| if (!writer->indent) { | |
| count = xmlOutputBufferWriteString(writer->out, "\n"); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| } | |
| sum += xmlTextWriterFlush(writer); | |
| return sum; | |
| } | |
| /** | |
| * xmlTextWriterStartComment: | |
| * @writer: the xmlTextWriterPtr | |
| * | |
| * Start an xml comment. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterStartComment(xmlTextWriterPtr writer) | |
| { | |
| int count; | |
| int sum; | |
| xmlLinkPtr lk; | |
| xmlTextWriterStackEntry *p; | |
| if (writer == NULL) { | |
| xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, | |
| "xmlTextWriterStartComment : invalid writer!\n"); | |
| return -1; | |
| } | |
| sum = 0; | |
| lk = xmlListFront(writer->nodes); | |
| if (lk != 0) { | |
| p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); | |
| if (p != 0) { | |
| switch (p->state) { | |
| case XML_TEXTWRITER_TEXT: | |
| case XML_TEXTWRITER_NONE: | |
| break; | |
| case XML_TEXTWRITER_NAME: | |
| /* Output namespace declarations */ | |
| count = xmlTextWriterOutputNSDecl(writer); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlOutputBufferWriteString(writer->out, ">"); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| if (writer->indent) { | |
| count = | |
| xmlOutputBufferWriteString(writer->out, "\n"); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| } | |
| p->state = XML_TEXTWRITER_TEXT; | |
| break; | |
| default: | |
| return -1; | |
| } | |
| } | |
| } | |
| p = (xmlTextWriterStackEntry *) | |
| xmlMalloc(sizeof(xmlTextWriterStackEntry)); | |
| if (p == 0) { | |
| xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, | |
| "xmlTextWriterStartElement : out of memory!\n"); | |
| return -1; | |
| } | |
| p->name = NULL; | |
| p->state = XML_TEXTWRITER_COMMENT; | |
| xmlListPushFront(writer->nodes, p); | |
| if (writer->indent) { | |
| count = xmlTextWriterWriteIndent(writer); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| } | |
| count = xmlOutputBufferWriteString(writer->out, "<!--"); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| return sum; | |
| } | |
| /** | |
| * xmlTextWriterEndComment: | |
| * @writer: the xmlTextWriterPtr | |
| * | |
| * End the current xml coment. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterEndComment(xmlTextWriterPtr writer) | |
| { | |
| int count; | |
| int sum; | |
| xmlLinkPtr lk; | |
| xmlTextWriterStackEntry *p; | |
| if (writer == NULL) { | |
| xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, | |
| "xmlTextWriterEndComment : invalid writer!\n"); | |
| return -1; | |
| } | |
| lk = xmlListFront(writer->nodes); | |
| if (lk == 0) { | |
| xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, | |
| "xmlTextWriterEndComment : not allowed in this context!\n"); | |
| return -1; | |
| } | |
| p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); | |
| if (p == 0) | |
| return -1; | |
| sum = 0; | |
| switch (p->state) { | |
| case XML_TEXTWRITER_COMMENT: | |
| count = xmlOutputBufferWriteString(writer->out, "-->"); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| break; | |
| default: | |
| return -1; | |
| } | |
| if (writer->indent) { | |
| count = xmlOutputBufferWriteString(writer->out, "\n"); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| } | |
| xmlListPopFront(writer->nodes); | |
| return sum; | |
| } | |
| /** | |
| * xmlTextWriterWriteFormatComment: | |
| * @writer: the xmlTextWriterPtr | |
| * @format: format string (see printf) | |
| * @...: extra parameters for the format | |
| * | |
| * Write an xml comment. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int XMLCDECL | |
| xmlTextWriterWriteFormatComment(xmlTextWriterPtr writer, | |
| const char *format, ...) | |
| { | |
| int rc; | |
| va_list ap; | |
| va_start(ap, format); | |
| rc = xmlTextWriterWriteVFormatComment(writer, format, ap); | |
| va_end(ap); | |
| return rc; | |
| } | |
| /** | |
| * xmlTextWriterWriteVFormatComment: | |
| * @writer: the xmlTextWriterPtr | |
| * @format: format string (see printf) | |
| * @argptr: pointer to the first member of the variable argument list. | |
| * | |
| * Write an xml comment. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterWriteVFormatComment(xmlTextWriterPtr writer, | |
| const char *format, va_list argptr) | |
| { | |
| int rc; | |
| xmlChar *buf; | |
| if (writer == NULL) { | |
| xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, | |
| "xmlTextWriterWriteVFormatComment : invalid writer!\n"); | |
| return -1; | |
| } | |
| buf = xmlTextWriterVSprintf(format, argptr); | |
| if (buf == NULL) | |
| return -1; | |
| rc = xmlTextWriterWriteComment(writer, buf); | |
| xmlFree(buf); | |
| return rc; | |
| } | |
| /** | |
| * xmlTextWriterWriteComment: | |
| * @writer: the xmlTextWriterPtr | |
| * @content: comment string | |
| * | |
| * Write an xml comment. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterWriteComment(xmlTextWriterPtr writer, const xmlChar * content) | |
| { | |
| int count; | |
| int sum; | |
| sum = 0; | |
| count = xmlTextWriterStartComment(writer); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlTextWriterWriteString(writer, content); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlTextWriterEndComment(writer); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| return sum; | |
| } | |
| /** | |
| * xmlTextWriterStartElement: | |
| * @writer: the xmlTextWriterPtr | |
| * @name: element name | |
| * | |
| * Start an xml element. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterStartElement(xmlTextWriterPtr writer, const xmlChar * name) | |
| { | |
| int count; | |
| int sum; | |
| xmlLinkPtr lk; | |
| xmlTextWriterStackEntry *p; | |
| if ((writer == NULL) || (name == NULL) || (*name == '\0')) | |
| return -1; | |
| sum = 0; | |
| lk = xmlListFront(writer->nodes); | |
| if (lk != 0) { | |
| p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); | |
| if (p != 0) { | |
| switch (p->state) { | |
| case XML_TEXTWRITER_PI: | |
| case XML_TEXTWRITER_PI_TEXT: | |
| return -1; | |
| case XML_TEXTWRITER_NONE: | |
| break; | |
| case XML_TEXTWRITER_ATTRIBUTE: | |
| count = xmlTextWriterEndAttribute(writer); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| /* fallthrough */ | |
| case XML_TEXTWRITER_NAME: | |
| /* Output namespace declarations */ | |
| count = xmlTextWriterOutputNSDecl(writer); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlOutputBufferWriteString(writer->out, ">"); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| if (writer->indent) | |
| count = | |
| xmlOutputBufferWriteString(writer->out, "\n"); | |
| p->state = XML_TEXTWRITER_TEXT; | |
| break; | |
| default: | |
| break; | |
| } | |
| } | |
| } | |
| p = (xmlTextWriterStackEntry *) | |
| xmlMalloc(sizeof(xmlTextWriterStackEntry)); | |
| if (p == 0) { | |
| xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, | |
| "xmlTextWriterStartElement : out of memory!\n"); | |
| return -1; | |
| } | |
| p->name = xmlStrdup(name); | |
| if (p->name == 0) { | |
| xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, | |
| "xmlTextWriterStartElement : out of memory!\n"); | |
| xmlFree(p); | |
| return -1; | |
| } | |
| p->state = XML_TEXTWRITER_NAME; | |
| xmlListPushFront(writer->nodes, p); | |
| if (writer->indent) { | |
| count = xmlTextWriterWriteIndent(writer); | |
| sum += count; | |
| } | |
| count = xmlOutputBufferWriteString(writer->out, "<"); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = | |
| xmlOutputBufferWriteString(writer->out, (const char *) p->name); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| return sum; | |
| } | |
| /** | |
| * xmlTextWriterStartElementNS: | |
| * @writer: the xmlTextWriterPtr | |
| * @prefix: namespace prefix or NULL | |
| * @name: element local name | |
| * @namespaceURI: namespace URI or NULL | |
| * | |
| * Start an xml element with namespace support. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterStartElementNS(xmlTextWriterPtr writer, | |
| const xmlChar * prefix, const xmlChar * name, | |
| const xmlChar * namespaceURI) | |
| { | |
| int count; | |
| int sum; | |
| xmlChar *buf; | |
| if ((writer == NULL) || (name == NULL) || (*name == '\0')) | |
| return -1; | |
| buf = NULL; | |
| if (prefix != 0) { | |
| buf = xmlStrdup(prefix); | |
| buf = xmlStrcat(buf, BAD_CAST ":"); | |
| } | |
| buf = xmlStrcat(buf, name); | |
| sum = 0; | |
| count = xmlTextWriterStartElement(writer, buf); | |
| xmlFree(buf); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| if (namespaceURI != 0) { | |
| xmlTextWriterNsStackEntry *p = (xmlTextWriterNsStackEntry *) | |
| xmlMalloc(sizeof(xmlTextWriterNsStackEntry)); | |
| if (p == 0) { | |
| xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, | |
| "xmlTextWriterStartElementNS : out of memory!\n"); | |
| return -1; | |
| } | |
| buf = xmlStrdup(BAD_CAST "xmlns"); | |
| if (prefix != 0) { | |
| buf = xmlStrcat(buf, BAD_CAST ":"); | |
| buf = xmlStrcat(buf, prefix); | |
| } | |
| p->prefix = buf; | |
| p->uri = xmlStrdup(namespaceURI); | |
| if (p->uri == 0) { | |
| xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, | |
| "xmlTextWriterStartElementNS : out of memory!\n"); | |
| xmlFree(p); | |
| return -1; | |
| } | |
| p->elem = xmlListFront(writer->nodes); | |
| xmlListPushFront(writer->nsstack, p); | |
| } | |
| return sum; | |
| } | |
| /** | |
| * xmlTextWriterEndElement: | |
| * @writer: the xmlTextWriterPtr | |
| * | |
| * End the current xml element. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterEndElement(xmlTextWriterPtr writer) | |
| { | |
| int count; | |
| int sum; | |
| xmlLinkPtr lk; | |
| xmlTextWriterStackEntry *p; | |
| if (writer == NULL) | |
| return -1; | |
| lk = xmlListFront(writer->nodes); | |
| if (lk == 0) { | |
| xmlListDelete(writer->nsstack); | |
| writer->nsstack = NULL; | |
| return -1; | |
| } | |
| p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); | |
| if (p == 0) { | |
| xmlListDelete(writer->nsstack); | |
| writer->nsstack = NULL; | |
| return -1; | |
| } | |
| sum = 0; | |
| switch (p->state) { | |
| case XML_TEXTWRITER_ATTRIBUTE: | |
| count = xmlTextWriterEndAttribute(writer); | |
| if (count < 0) { | |
| xmlListDelete(writer->nsstack); | |
| writer->nsstack = NULL; | |
| return -1; | |
| } | |
| sum += count; | |
| /* fallthrough */ | |
| case XML_TEXTWRITER_NAME: | |
| /* Output namespace declarations */ | |
| count = xmlTextWriterOutputNSDecl(writer); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| if (writer->indent) /* next element needs indent */ | |
| writer->doindent = 1; | |
| count = xmlOutputBufferWriteString(writer->out, "/>"); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| break; | |
| case XML_TEXTWRITER_TEXT: | |
| if ((writer->indent) && (writer->doindent)) { | |
| count = xmlTextWriterWriteIndent(writer); | |
| sum += count; | |
| writer->doindent = 1; | |
| } else | |
| writer->doindent = 1; | |
| count = xmlOutputBufferWriteString(writer->out, "</"); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlOutputBufferWriteString(writer->out, | |
| (const char *) p->name); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlOutputBufferWriteString(writer->out, ">"); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| break; | |
| default: | |
| return -1; | |
| } | |
| if (writer->indent) { | |
| count = xmlOutputBufferWriteString(writer->out, "\n"); | |
| sum += count; | |
| } | |
| xmlListPopFront(writer->nodes); | |
| return sum; | |
| } | |
| /** | |
| * xmlTextWriterFullEndElement: | |
| * @writer: the xmlTextWriterPtr | |
| * | |
| * End the current xml element. Writes an end tag even if the element is empty | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterFullEndElement(xmlTextWriterPtr writer) | |
| { | |
| int count; | |
| int sum; | |
| xmlLinkPtr lk; | |
| xmlTextWriterStackEntry *p; | |
| if (writer == NULL) | |
| return -1; | |
| lk = xmlListFront(writer->nodes); | |
| if (lk == 0) | |
| return -1; | |
| p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); | |
| if (p == 0) | |
| return -1; | |
| sum = 0; | |
| switch (p->state) { | |
| case XML_TEXTWRITER_ATTRIBUTE: | |
| count = xmlTextWriterEndAttribute(writer); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| /* fallthrough */ | |
| case XML_TEXTWRITER_NAME: | |
| /* Output namespace declarations */ | |
| count = xmlTextWriterOutputNSDecl(writer); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlOutputBufferWriteString(writer->out, ">"); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| if (writer->indent) | |
| writer->doindent = 0; | |
| /* fallthrough */ | |
| case XML_TEXTWRITER_TEXT: | |
| if ((writer->indent) && (writer->doindent)) { | |
| count = xmlTextWriterWriteIndent(writer); | |
| sum += count; | |
| writer->doindent = 1; | |
| } else | |
| writer->doindent = 1; | |
| count = xmlOutputBufferWriteString(writer->out, "</"); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlOutputBufferWriteString(writer->out, | |
| (const char *) p->name); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlOutputBufferWriteString(writer->out, ">"); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| break; | |
| default: | |
| return -1; | |
| } | |
| if (writer->indent) { | |
| count = xmlOutputBufferWriteString(writer->out, "\n"); | |
| sum += count; | |
| } | |
| xmlListPopFront(writer->nodes); | |
| return sum; | |
| } | |
| /** | |
| * xmlTextWriterWriteFormatRaw: | |
| * @writer: the xmlTextWriterPtr | |
| * @format: format string (see printf) | |
| * @...: extra parameters for the format | |
| * | |
| * Write a formatted raw xml text. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int XMLCDECL | |
| xmlTextWriterWriteFormatRaw(xmlTextWriterPtr writer, const char *format, | |
| ...) | |
| { | |
| int rc; | |
| va_list ap; | |
| va_start(ap, format); | |
| rc = xmlTextWriterWriteVFormatRaw(writer, format, ap); | |
| va_end(ap); | |
| return rc; | |
| } | |
| /** | |
| * xmlTextWriterWriteVFormatRaw: | |
| * @writer: the xmlTextWriterPtr | |
| * @format: format string (see printf) | |
| * @argptr: pointer to the first member of the variable argument list. | |
| * | |
| * Write a formatted raw xml text. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterWriteVFormatRaw(xmlTextWriterPtr writer, const char *format, | |
| va_list argptr) | |
| { | |
| int rc; | |
| xmlChar *buf; | |
| if (writer == NULL) | |
| return -1; | |
| buf = xmlTextWriterVSprintf(format, argptr); | |
| if (buf == NULL) | |
| return -1; | |
| rc = xmlTextWriterWriteRaw(writer, buf); | |
| xmlFree(buf); | |
| return rc; | |
| } | |
| /** | |
| * xmlTextWriterWriteRawLen: | |
| * @writer: the xmlTextWriterPtr | |
| * @content: text string | |
| * @len: length of the text string | |
| * | |
| * Write an xml text. | |
| * TODO: what about entities and special chars?? | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterWriteRawLen(xmlTextWriterPtr writer, const xmlChar * content, | |
| int len) | |
| { | |
| int count; | |
| int sum; | |
| xmlLinkPtr lk; | |
| xmlTextWriterStackEntry *p; | |
| if (writer == NULL) { | |
| xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, | |
| "xmlTextWriterWriteRawLen : invalid writer!\n"); | |
| return -1; | |
| } | |
| if ((content == NULL) || (len < 0)) { | |
| xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, | |
| "xmlTextWriterWriteRawLen : invalid content!\n"); | |
| return -1; | |
| } | |
| sum = 0; | |
| lk = xmlListFront(writer->nodes); | |
| if (lk != 0) { | |
| p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); | |
| count = xmlTextWriterHandleStateDependencies(writer, p); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| } | |
| if (writer->indent) | |
| writer->doindent = 0; | |
| if (content != NULL) { | |
| count = | |
| xmlOutputBufferWrite(writer->out, len, (const char *) content); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| } | |
| return sum; | |
| } | |
| /** | |
| * xmlTextWriterWriteRaw: | |
| * @writer: the xmlTextWriterPtr | |
| * @content: text string | |
| * | |
| * Write a raw xml text. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterWriteRaw(xmlTextWriterPtr writer, const xmlChar * content) | |
| { | |
| return xmlTextWriterWriteRawLen(writer, content, xmlStrlen(content)); | |
| } | |
| /** | |
| * xmlTextWriterWriteFormatString: | |
| * @writer: the xmlTextWriterPtr | |
| * @format: format string (see printf) | |
| * @...: extra parameters for the format | |
| * | |
| * Write a formatted xml text. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int XMLCDECL | |
| xmlTextWriterWriteFormatString(xmlTextWriterPtr writer, const char *format, | |
| ...) | |
| { | |
| int rc; | |
| va_list ap; | |
| if ((writer == NULL) || (format == NULL)) | |
| return -1; | |
| va_start(ap, format); | |
| rc = xmlTextWriterWriteVFormatString(writer, format, ap); | |
| va_end(ap); | |
| return rc; | |
| } | |
| /** | |
| * xmlTextWriterWriteVFormatString: | |
| * @writer: the xmlTextWriterPtr | |
| * @format: format string (see printf) | |
| * @argptr: pointer to the first member of the variable argument list. | |
| * | |
| * Write a formatted xml text. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterWriteVFormatString(xmlTextWriterPtr writer, | |
| const char *format, va_list argptr) | |
| { | |
| int rc; | |
| xmlChar *buf; | |
| if ((writer == NULL) || (format == NULL)) | |
| return -1; | |
| buf = xmlTextWriterVSprintf(format, argptr); | |
| if (buf == NULL) | |
| return -1; | |
| rc = xmlTextWriterWriteString(writer, buf); | |
| xmlFree(buf); | |
| return rc; | |
| } | |
| /** | |
| * xmlTextWriterWriteString: | |
| * @writer: the xmlTextWriterPtr | |
| * @content: text string | |
| * | |
| * Write an xml text. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterWriteString(xmlTextWriterPtr writer, const xmlChar * content) | |
| { | |
| int count; | |
| int sum; | |
| xmlLinkPtr lk; | |
| xmlTextWriterStackEntry *p; | |
| xmlChar *buf; | |
| if ((writer == NULL) || (content == NULL)) | |
| return -1; | |
| sum = 0; | |
| buf = (xmlChar *) content; | |
| lk = xmlListFront(writer->nodes); | |
| if (lk != 0) { | |
| p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); | |
| if (p != 0) { | |
| switch (p->state) { | |
| case XML_TEXTWRITER_NAME: | |
| case XML_TEXTWRITER_TEXT: | |
| #if 0 | |
| buf = NULL; | |
| xmlOutputBufferWriteEscape(writer->out, content, NULL); | |
| #endif | |
| buf = xmlEncodeSpecialChars(NULL, content); | |
| break; | |
| case XML_TEXTWRITER_ATTRIBUTE: | |
| buf = NULL; | |
| xmlBufAttrSerializeTxtContent(writer->out->buffer, | |
| writer->doc, NULL, content); | |
| break; | |
| default: | |
| break; | |
| } | |
| } | |
| } | |
| if (buf != NULL) { | |
| count = xmlTextWriterWriteRaw(writer, buf); | |
| if (buf != content) /* buf was allocated by us, so free it */ | |
| xmlFree(buf); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| } | |
| return sum; | |
| } | |
| /** | |
| * xmlOutputBufferWriteBase64: | |
| * @out: the xmlOutputBufferPtr | |
| * @data: binary data | |
| * @len: the number of bytes to encode | |
| * | |
| * Write base64 encoded data to an xmlOutputBuffer. | |
| * Adapted from John Walker's base64.c (http://www.fourmilab.ch/). | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| static int | |
| xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len, | |
| const unsigned char *data) | |
| { | |
| static unsigned char dtable[64] = | |
| {'A','B','C','D','E','F','G','H','I','J','K','L','M', | |
| 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z', | |
| 'a','b','c','d','e','f','g','h','i','j','k','l','m', | |
| 'n','o','p','q','r','s','t','u','v','w','x','y','z', | |
| '0','1','2','3','4','5','6','7','8','9','+','/'}; | |
| int i; | |
| int linelen; | |
| int count; | |
| int sum; | |
| if ((out == NULL) || (len < 0) || (data == NULL)) | |
| return(-1); | |
| linelen = 0; | |
| sum = 0; | |
| i = 0; | |
| while (1) { | |
| unsigned char igroup[3]; | |
| unsigned char ogroup[4]; | |
| int c; | |
| int n; | |
| igroup[0] = igroup[1] = igroup[2] = 0; | |
| for (n = 0; n < 3 && i < len; n++, i++) { | |
| c = data[i]; | |
| igroup[n] = (unsigned char) c; | |
| } | |
| if (n > 0) { | |
| ogroup[0] = dtable[igroup[0] >> 2]; | |
| ogroup[1] = dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)]; | |
| ogroup[2] = | |
| dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)]; | |
| ogroup[3] = dtable[igroup[2] & 0x3F]; | |
| if (n < 3) { | |
| ogroup[3] = '='; | |
| if (n < 2) { | |
| ogroup[2] = '='; | |
| } | |
| } | |
| if (linelen >= B64LINELEN) { | |
| count = xmlOutputBufferWrite(out, 2, B64CRLF); | |
| if (count == -1) | |
| return -1; | |
| sum += count; | |
| linelen = 0; | |
| } | |
| count = xmlOutputBufferWrite(out, 4, (const char *) ogroup); | |
| if (count == -1) | |
| return -1; | |
| sum += count; | |
| linelen += 4; | |
| } | |
| if (i >= len) | |
| break; | |
| } | |
| return sum; | |
| } | |
| /** | |
| * xmlTextWriterWriteBase64: | |
| * @writer: the xmlTextWriterPtr | |
| * @data: binary data | |
| * @start: the position within the data of the first byte to encode | |
| * @len: the number of bytes to encode | |
| * | |
| * Write an base64 encoded xml text. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterWriteBase64(xmlTextWriterPtr writer, const char *data, | |
| int start, int len) | |
| { | |
| int count; | |
| int sum; | |
| xmlLinkPtr lk; | |
| xmlTextWriterStackEntry *p; | |
| if ((writer == NULL) || (data == NULL) || (start < 0) || (len < 0)) | |
| return -1; | |
| sum = 0; | |
| lk = xmlListFront(writer->nodes); | |
| if (lk != 0) { | |
| p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); | |
| if (p != 0) { | |
| count = xmlTextWriterHandleStateDependencies(writer, p); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| } | |
| } | |
| if (writer->indent) | |
| writer->doindent = 0; | |
| count = | |
| xmlOutputBufferWriteBase64(writer->out, len, | |
| (unsigned char *) data + start); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| return sum; | |
| } | |
| /** | |
| * xmlOutputBufferWriteBinHex: | |
| * @out: the xmlOutputBufferPtr | |
| * @data: binary data | |
| * @len: the number of bytes to encode | |
| * | |
| * Write hqx encoded data to an xmlOutputBuffer. | |
| * ::todo | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) | |
| * or -1 in case of error | |
| */ | |
| static int | |
| xmlOutputBufferWriteBinHex(xmlOutputBufferPtr out, | |
| int len, const unsigned char *data) | |
| { | |
| int count; | |
| int sum; | |
| static char hex[16] = | |
| {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; | |
| int i; | |
| if ((out == NULL) || (data == NULL) || (len < 0)) { | |
| return -1; | |
| } | |
| sum = 0; | |
| for (i = 0; i < len; i++) { | |
| count = | |
| xmlOutputBufferWrite(out, 1, | |
| (const char *) &hex[data[i] >> 4]); | |
| if (count == -1) | |
| return -1; | |
| sum += count; | |
| count = | |
| xmlOutputBufferWrite(out, 1, | |
| (const char *) &hex[data[i] & 0xF]); | |
| if (count == -1) | |
| return -1; | |
| sum += count; | |
| } | |
| return sum; | |
| } | |
| /** | |
| * xmlTextWriterWriteBinHex: | |
| * @writer: the xmlTextWriterPtr | |
| * @data: binary data | |
| * @start: the position within the data of the first byte to encode | |
| * @len: the number of bytes to encode | |
| * | |
| * Write a BinHex encoded xml text. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterWriteBinHex(xmlTextWriterPtr writer, const char *data, | |
| int start, int len) | |
| { | |
| int count; | |
| int sum; | |
| xmlLinkPtr lk; | |
| xmlTextWriterStackEntry *p; | |
| if ((writer == NULL) || (data == NULL) || (start < 0) || (len < 0)) | |
| return -1; | |
| sum = 0; | |
| lk = xmlListFront(writer->nodes); | |
| if (lk != 0) { | |
| p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); | |
| if (p != 0) { | |
| count = xmlTextWriterHandleStateDependencies(writer, p); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| } | |
| } | |
| if (writer->indent) | |
| writer->doindent = 0; | |
| count = | |
| xmlOutputBufferWriteBinHex(writer->out, len, | |
| (unsigned char *) data + start); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| return sum; | |
| } | |
| /** | |
| * xmlTextWriterStartAttribute: | |
| * @writer: the xmlTextWriterPtr | |
| * @name: element name | |
| * | |
| * Start an xml attribute. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterStartAttribute(xmlTextWriterPtr writer, const xmlChar * name) | |
| { | |
| int count; | |
| int sum; | |
| xmlLinkPtr lk; | |
| xmlTextWriterStackEntry *p; | |
| if ((writer == NULL) || (name == NULL) || (*name == '\0')) | |
| return -1; | |
| sum = 0; | |
| lk = xmlListFront(writer->nodes); | |
| if (lk == 0) | |
| return -1; | |
| p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); | |
| if (p == 0) | |
| return -1; | |
| switch (p->state) { | |
| case XML_TEXTWRITER_ATTRIBUTE: | |
| count = xmlTextWriterEndAttribute(writer); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| /* fallthrough */ | |
| case XML_TEXTWRITER_NAME: | |
| count = xmlOutputBufferWriteString(writer->out, " "); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = | |
| xmlOutputBufferWriteString(writer->out, | |
| (const char *) name); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlOutputBufferWriteString(writer->out, "="); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| p->state = XML_TEXTWRITER_ATTRIBUTE; | |
| break; | |
| default: | |
| return -1; | |
| } | |
| return sum; | |
| } | |
| /** | |
| * xmlTextWriterStartAttributeNS: | |
| * @writer: the xmlTextWriterPtr | |
| * @prefix: namespace prefix or NULL | |
| * @name: element local name | |
| * @namespaceURI: namespace URI or NULL | |
| * | |
| * Start an xml attribute with namespace support. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterStartAttributeNS(xmlTextWriterPtr writer, | |
| const xmlChar * prefix, const xmlChar * name, | |
| const xmlChar * namespaceURI) | |
| { | |
| int count; | |
| int sum; | |
| xmlChar *buf; | |
| xmlTextWriterNsStackEntry *p; | |
| if ((writer == NULL) || (name == NULL) || (*name == '\0')) | |
| return -1; | |
| /* Handle namespace first in case of error */ | |
| if (namespaceURI != 0) { | |
| xmlTextWriterNsStackEntry nsentry, *curns; | |
| buf = xmlStrdup(BAD_CAST "xmlns"); | |
| if (prefix != 0) { | |
| buf = xmlStrcat(buf, BAD_CAST ":"); | |
| buf = xmlStrcat(buf, prefix); | |
| } | |
| nsentry.prefix = buf; | |
| nsentry.uri = (xmlChar *)namespaceURI; | |
| nsentry.elem = xmlListFront(writer->nodes); | |
| curns = (xmlTextWriterNsStackEntry *)xmlListSearch(writer->nsstack, | |
| (void *)&nsentry); | |
| if ((curns != NULL)) { | |
| xmlFree(buf); | |
| if (xmlStrcmp(curns->uri, namespaceURI) == 0) { | |
| /* Namespace already defined on element skip */ | |
| buf = NULL; | |
| } else { | |
| /* Prefix mismatch so error out */ | |
| return -1; | |
| } | |
| } | |
| /* Do not add namespace decl to list - it is already there */ | |
| if (buf != NULL) { | |
| p = (xmlTextWriterNsStackEntry *) | |
| xmlMalloc(sizeof(xmlTextWriterNsStackEntry)); | |
| if (p == 0) { | |
| xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, | |
| "xmlTextWriterStartAttributeNS : out of memory!\n"); | |
| return -1; | |
| } | |
| p->prefix = buf; | |
| p->uri = xmlStrdup(namespaceURI); | |
| if (p->uri == 0) { | |
| xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, | |
| "xmlTextWriterStartAttributeNS : out of memory!\n"); | |
| xmlFree(p); | |
| return -1; | |
| } | |
| p->elem = xmlListFront(writer->nodes); | |
| xmlListPushFront(writer->nsstack, p); | |
| } | |
| } | |
| buf = NULL; | |
| if (prefix != 0) { | |
| buf = xmlStrdup(prefix); | |
| buf = xmlStrcat(buf, BAD_CAST ":"); | |
| } | |
| buf = xmlStrcat(buf, name); | |
| sum = 0; | |
| count = xmlTextWriterStartAttribute(writer, buf); | |
| xmlFree(buf); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| return sum; | |
| } | |
| /** | |
| * xmlTextWriterEndAttribute: | |
| * @writer: the xmlTextWriterPtr | |
| * | |
| * End the current xml element. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterEndAttribute(xmlTextWriterPtr writer) | |
| { | |
| int count; | |
| int sum; | |
| xmlLinkPtr lk; | |
| xmlTextWriterStackEntry *p; | |
| if (writer == NULL) | |
| return -1; | |
| lk = xmlListFront(writer->nodes); | |
| if (lk == 0) { | |
| return -1; | |
| } | |
| p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); | |
| if (p == 0) { | |
| return -1; | |
| } | |
| sum = 0; | |
| switch (p->state) { | |
| case XML_TEXTWRITER_ATTRIBUTE: | |
| p->state = XML_TEXTWRITER_NAME; | |
| count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); | |
| if (count < 0) { | |
| return -1; | |
| } | |
| sum += count; | |
| break; | |
| default: | |
| return -1; | |
| } | |
| return sum; | |
| } | |
| /** | |
| * xmlTextWriterWriteFormatAttribute: | |
| * @writer: the xmlTextWriterPtr | |
| * @name: attribute name | |
| * @format: format string (see printf) | |
| * @...: extra parameters for the format | |
| * | |
| * Write a formatted xml attribute. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int XMLCDECL | |
| xmlTextWriterWriteFormatAttribute(xmlTextWriterPtr writer, | |
| const xmlChar * name, const char *format, | |
| ...) | |
| { | |
| int rc; | |
| va_list ap; | |
| va_start(ap, format); | |
| rc = xmlTextWriterWriteVFormatAttribute(writer, name, format, ap); | |
| va_end(ap); | |
| return rc; | |
| } | |
| /** | |
| * xmlTextWriterWriteVFormatAttribute: | |
| * @writer: the xmlTextWriterPtr | |
| * @name: attribute name | |
| * @format: format string (see printf) | |
| * @argptr: pointer to the first member of the variable argument list. | |
| * | |
| * Write a formatted xml attribute. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterWriteVFormatAttribute(xmlTextWriterPtr writer, | |
| const xmlChar * name, | |
| const char *format, va_list argptr) | |
| { | |
| int rc; | |
| xmlChar *buf; | |
| if (writer == NULL) | |
| return -1; | |
| buf = xmlTextWriterVSprintf(format, argptr); | |
| if (buf == NULL) | |
| return -1; | |
| rc = xmlTextWriterWriteAttribute(writer, name, buf); | |
| xmlFree(buf); | |
| return rc; | |
| } | |
| /** | |
| * xmlTextWriterWriteAttribute: | |
| * @writer: the xmlTextWriterPtr | |
| * @name: attribute name | |
| * @content: attribute content | |
| * | |
| * Write an xml attribute. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterWriteAttribute(xmlTextWriterPtr writer, const xmlChar * name, | |
| const xmlChar * content) | |
| { | |
| int count; | |
| int sum; | |
| sum = 0; | |
| count = xmlTextWriterStartAttribute(writer, name); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlTextWriterWriteString(writer, content); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlTextWriterEndAttribute(writer); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| return sum; | |
| } | |
| /** | |
| * xmlTextWriterWriteFormatAttributeNS: | |
| * @writer: the xmlTextWriterPtr | |
| * @prefix: namespace prefix | |
| * @name: attribute local name | |
| * @namespaceURI: namespace URI | |
| * @format: format string (see printf) | |
| * @...: extra parameters for the format | |
| * | |
| * Write a formatted xml attribute.with namespace support | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int XMLCDECL | |
| xmlTextWriterWriteFormatAttributeNS(xmlTextWriterPtr writer, | |
| const xmlChar * prefix, | |
| const xmlChar * name, | |
| const xmlChar * namespaceURI, | |
| const char *format, ...) | |
| { | |
| int rc; | |
| va_list ap; | |
| va_start(ap, format); | |
| rc = xmlTextWriterWriteVFormatAttributeNS(writer, prefix, name, | |
| namespaceURI, format, ap); | |
| va_end(ap); | |
| return rc; | |
| } | |
| /** | |
| * xmlTextWriterWriteVFormatAttributeNS: | |
| * @writer: the xmlTextWriterPtr | |
| * @prefix: namespace prefix | |
| * @name: attribute local name | |
| * @namespaceURI: namespace URI | |
| * @format: format string (see printf) | |
| * @argptr: pointer to the first member of the variable argument list. | |
| * | |
| * Write a formatted xml attribute.with namespace support | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterWriteVFormatAttributeNS(xmlTextWriterPtr writer, | |
| const xmlChar * prefix, | |
| const xmlChar * name, | |
| const xmlChar * namespaceURI, | |
| const char *format, va_list argptr) | |
| { | |
| int rc; | |
| xmlChar *buf; | |
| if (writer == NULL) | |
| return -1; | |
| buf = xmlTextWriterVSprintf(format, argptr); | |
| if (buf == NULL) | |
| return -1; | |
| rc = xmlTextWriterWriteAttributeNS(writer, prefix, name, namespaceURI, | |
| buf); | |
| xmlFree(buf); | |
| return rc; | |
| } | |
| /** | |
| * xmlTextWriterWriteAttributeNS: | |
| * @writer: the xmlTextWriterPtr | |
| * @prefix: namespace prefix | |
| * @name: attribute local name | |
| * @namespaceURI: namespace URI | |
| * @content: attribute content | |
| * | |
| * Write an xml attribute. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterWriteAttributeNS(xmlTextWriterPtr writer, | |
| const xmlChar * prefix, const xmlChar * name, | |
| const xmlChar * namespaceURI, | |
| const xmlChar * content) | |
| { | |
| int count; | |
| int sum; | |
| if ((writer == NULL) || (name == NULL) || (*name == '\0')) | |
| return -1; | |
| sum = 0; | |
| count = xmlTextWriterStartAttributeNS(writer, prefix, name, namespaceURI); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlTextWriterWriteString(writer, content); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlTextWriterEndAttribute(writer); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| return sum; | |
| } | |
| /** | |
| * xmlTextWriterWriteFormatElement: | |
| * @writer: the xmlTextWriterPtr | |
| * @name: element name | |
| * @format: format string (see printf) | |
| * @...: extra parameters for the format | |
| * | |
| * Write a formatted xml element. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int XMLCDECL | |
| xmlTextWriterWriteFormatElement(xmlTextWriterPtr writer, | |
| const xmlChar * name, const char *format, | |
| ...) | |
| { | |
| int rc; | |
| va_list ap; | |
| va_start(ap, format); | |
| rc = xmlTextWriterWriteVFormatElement(writer, name, format, ap); | |
| va_end(ap); | |
| return rc; | |
| } | |
| /** | |
| * xmlTextWriterWriteVFormatElement: | |
| * @writer: the xmlTextWriterPtr | |
| * @name: element name | |
| * @format: format string (see printf) | |
| * @argptr: pointer to the first member of the variable argument list. | |
| * | |
| * Write a formatted xml element. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterWriteVFormatElement(xmlTextWriterPtr writer, | |
| const xmlChar * name, const char *format, | |
| va_list argptr) | |
| { | |
| int rc; | |
| xmlChar *buf; | |
| if (writer == NULL) | |
| return -1; | |
| buf = xmlTextWriterVSprintf(format, argptr); | |
| if (buf == NULL) | |
| return -1; | |
| rc = xmlTextWriterWriteElement(writer, name, buf); | |
| xmlFree(buf); | |
| return rc; | |
| } | |
| /** | |
| * xmlTextWriterWriteElement: | |
| * @writer: the xmlTextWriterPtr | |
| * @name: element name | |
| * @content: element content | |
| * | |
| * Write an xml element. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterWriteElement(xmlTextWriterPtr writer, const xmlChar * name, | |
| const xmlChar * content) | |
| { | |
| int count; | |
| int sum; | |
| sum = 0; | |
| count = xmlTextWriterStartElement(writer, name); | |
| if (count == -1) | |
| return -1; | |
| sum += count; | |
| if (content != NULL) { | |
| count = xmlTextWriterWriteString(writer, content); | |
| if (count == -1) | |
| return -1; | |
| sum += count; | |
| } | |
| count = xmlTextWriterEndElement(writer); | |
| if (count == -1) | |
| return -1; | |
| sum += count; | |
| return sum; | |
| } | |
| /** | |
| * xmlTextWriterWriteFormatElementNS: | |
| * @writer: the xmlTextWriterPtr | |
| * @prefix: namespace prefix | |
| * @name: element local name | |
| * @namespaceURI: namespace URI | |
| * @format: format string (see printf) | |
| * @...: extra parameters for the format | |
| * | |
| * Write a formatted xml element with namespace support. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int XMLCDECL | |
| xmlTextWriterWriteFormatElementNS(xmlTextWriterPtr writer, | |
| const xmlChar * prefix, | |
| const xmlChar * name, | |
| const xmlChar * namespaceURI, | |
| const char *format, ...) | |
| { | |
| int rc; | |
| va_list ap; | |
| va_start(ap, format); | |
| rc = xmlTextWriterWriteVFormatElementNS(writer, prefix, name, | |
| namespaceURI, format, ap); | |
| va_end(ap); | |
| return rc; | |
| } | |
| /** | |
| * xmlTextWriterWriteVFormatElementNS: | |
| * @writer: the xmlTextWriterPtr | |
| * @prefix: namespace prefix | |
| * @name: element local name | |
| * @namespaceURI: namespace URI | |
| * @format: format string (see printf) | |
| * @argptr: pointer to the first member of the variable argument list. | |
| * | |
| * Write a formatted xml element with namespace support. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterWriteVFormatElementNS(xmlTextWriterPtr writer, | |
| const xmlChar * prefix, | |
| const xmlChar * name, | |
| const xmlChar * namespaceURI, | |
| const char *format, va_list argptr) | |
| { | |
| int rc; | |
| xmlChar *buf; | |
| if (writer == NULL) | |
| return -1; | |
| buf = xmlTextWriterVSprintf(format, argptr); | |
| if (buf == NULL) | |
| return -1; | |
| rc = xmlTextWriterWriteElementNS(writer, prefix, name, namespaceURI, | |
| buf); | |
| xmlFree(buf); | |
| return rc; | |
| } | |
| /** | |
| * xmlTextWriterWriteElementNS: | |
| * @writer: the xmlTextWriterPtr | |
| * @prefix: namespace prefix | |
| * @name: element local name | |
| * @namespaceURI: namespace URI | |
| * @content: element content | |
| * | |
| * Write an xml element with namespace support. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterWriteElementNS(xmlTextWriterPtr writer, | |
| const xmlChar * prefix, const xmlChar * name, | |
| const xmlChar * namespaceURI, | |
| const xmlChar * content) | |
| { | |
| int count; | |
| int sum; | |
| if ((writer == NULL) || (name == NULL) || (*name == '\0')) | |
| return -1; | |
| sum = 0; | |
| count = | |
| xmlTextWriterStartElementNS(writer, prefix, name, namespaceURI); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlTextWriterWriteString(writer, content); | |
| if (count == -1) | |
| return -1; | |
| sum += count; | |
| count = xmlTextWriterEndElement(writer); | |
| if (count == -1) | |
| return -1; | |
| sum += count; | |
| return sum; | |
| } | |
| /** | |
| * xmlTextWriterStartPI: | |
| * @writer: the xmlTextWriterPtr | |
| * @target: PI target | |
| * | |
| * Start an xml PI. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterStartPI(xmlTextWriterPtr writer, const xmlChar * target) | |
| { | |
| int count; | |
| int sum; | |
| xmlLinkPtr lk; | |
| xmlTextWriterStackEntry *p; | |
| if ((writer == NULL) || (target == NULL) || (*target == '\0')) | |
| return -1; | |
| if (xmlStrcasecmp(target, (const xmlChar *) "xml") == 0) { | |
| xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, | |
| "xmlTextWriterStartPI : target name [Xx][Mm][Ll] is reserved for xml standardization!\n"); | |
| return -1; | |
| } | |
| sum = 0; | |
| lk = xmlListFront(writer->nodes); | |
| if (lk != 0) { | |
| p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); | |
| if (p != 0) { | |
| switch (p->state) { | |
| case XML_TEXTWRITER_ATTRIBUTE: | |
| count = xmlTextWriterEndAttribute(writer); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| /* fallthrough */ | |
| case XML_TEXTWRITER_NAME: | |
| /* Output namespace declarations */ | |
| count = xmlTextWriterOutputNSDecl(writer); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlOutputBufferWriteString(writer->out, ">"); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| p->state = XML_TEXTWRITER_TEXT; | |
| break; | |
| case XML_TEXTWRITER_NONE: | |
| case XML_TEXTWRITER_TEXT: | |
| case XML_TEXTWRITER_DTD: | |
| break; | |
| case XML_TEXTWRITER_PI: | |
| case XML_TEXTWRITER_PI_TEXT: | |
| xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, | |
| "xmlTextWriterStartPI : nested PI!\n"); | |
| return -1; | |
| default: | |
| return -1; | |
| } | |
| } | |
| } | |
| p = (xmlTextWriterStackEntry *) | |
| xmlMalloc(sizeof(xmlTextWriterStackEntry)); | |
| if (p == 0) { | |
| xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, | |
| "xmlTextWriterStartPI : out of memory!\n"); | |
| return -1; | |
| } | |
| p->name = xmlStrdup(target); | |
| if (p->name == 0) { | |
| xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, | |
| "xmlTextWriterStartPI : out of memory!\n"); | |
| xmlFree(p); | |
| return -1; | |
| } | |
| p->state = XML_TEXTWRITER_PI; | |
| xmlListPushFront(writer->nodes, p); | |
| count = xmlOutputBufferWriteString(writer->out, "<?"); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = | |
| xmlOutputBufferWriteString(writer->out, (const char *) p->name); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| return sum; | |
| } | |
| /** | |
| * xmlTextWriterEndPI: | |
| * @writer: the xmlTextWriterPtr | |
| * | |
| * End the current xml PI. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterEndPI(xmlTextWriterPtr writer) | |
| { | |
| int count; | |
| int sum; | |
| xmlLinkPtr lk; | |
| xmlTextWriterStackEntry *p; | |
| if (writer == NULL) | |
| return -1; | |
| lk = xmlListFront(writer->nodes); | |
| if (lk == 0) | |
| return 0; | |
| p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); | |
| if (p == 0) | |
| return 0; | |
| sum = 0; | |
| switch (p->state) { | |
| case XML_TEXTWRITER_PI: | |
| case XML_TEXTWRITER_PI_TEXT: | |
| count = xmlOutputBufferWriteString(writer->out, "?>"); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| break; | |
| default: | |
| return -1; | |
| } | |
| if (writer->indent) { | |
| count = xmlOutputBufferWriteString(writer->out, "\n"); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| } | |
| xmlListPopFront(writer->nodes); | |
| return sum; | |
| } | |
| /** | |
| * xmlTextWriterWriteFormatPI: | |
| * @writer: the xmlTextWriterPtr | |
| * @target: PI target | |
| * @format: format string (see printf) | |
| * @...: extra parameters for the format | |
| * | |
| * Write a formatted PI. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int XMLCDECL | |
| xmlTextWriterWriteFormatPI(xmlTextWriterPtr writer, const xmlChar * target, | |
| const char *format, ...) | |
| { | |
| int rc; | |
| va_list ap; | |
| va_start(ap, format); | |
| rc = xmlTextWriterWriteVFormatPI(writer, target, format, ap); | |
| va_end(ap); | |
| return rc; | |
| } | |
| /** | |
| * xmlTextWriterWriteVFormatPI: | |
| * @writer: the xmlTextWriterPtr | |
| * @target: PI target | |
| * @format: format string (see printf) | |
| * @argptr: pointer to the first member of the variable argument list. | |
| * | |
| * Write a formatted xml PI. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterWriteVFormatPI(xmlTextWriterPtr writer, | |
| const xmlChar * target, const char *format, | |
| va_list argptr) | |
| { | |
| int rc; | |
| xmlChar *buf; | |
| if (writer == NULL) | |
| return -1; | |
| buf = xmlTextWriterVSprintf(format, argptr); | |
| if (buf == NULL) | |
| return -1; | |
| rc = xmlTextWriterWritePI(writer, target, buf); | |
| xmlFree(buf); | |
| return rc; | |
| } | |
| /** | |
| * xmlTextWriterWritePI: | |
| * @writer: the xmlTextWriterPtr | |
| * @target: PI target | |
| * @content: PI content | |
| * | |
| * Write an xml PI. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterWritePI(xmlTextWriterPtr writer, const xmlChar * target, | |
| const xmlChar * content) | |
| { | |
| int count; | |
| int sum; | |
| sum = 0; | |
| count = xmlTextWriterStartPI(writer, target); | |
| if (count == -1) | |
| return -1; | |
| sum += count; | |
| if (content != 0) { | |
| count = xmlTextWriterWriteString(writer, content); | |
| if (count == -1) | |
| return -1; | |
| sum += count; | |
| } | |
| count = xmlTextWriterEndPI(writer); | |
| if (count == -1) | |
| return -1; | |
| sum += count; | |
| return sum; | |
| } | |
| /** | |
| * xmlTextWriterStartCDATA: | |
| * @writer: the xmlTextWriterPtr | |
| * | |
| * Start an xml CDATA section. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterStartCDATA(xmlTextWriterPtr writer) | |
| { | |
| int count; | |
| int sum; | |
| xmlLinkPtr lk; | |
| xmlTextWriterStackEntry *p; | |
| if (writer == NULL) | |
| return -1; | |
| sum = 0; | |
| lk = xmlListFront(writer->nodes); | |
| if (lk != 0) { | |
| p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); | |
| if (p != 0) { | |
| switch (p->state) { | |
| case XML_TEXTWRITER_NONE: | |
| case XML_TEXTWRITER_TEXT: | |
| case XML_TEXTWRITER_PI: | |
| case XML_TEXTWRITER_PI_TEXT: | |
| break; | |
| case XML_TEXTWRITER_ATTRIBUTE: | |
| count = xmlTextWriterEndAttribute(writer); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| /* fallthrough */ | |
| case XML_TEXTWRITER_NAME: | |
| /* Output namespace declarations */ | |
| count = xmlTextWriterOutputNSDecl(writer); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlOutputBufferWriteString(writer->out, ">"); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| p->state = XML_TEXTWRITER_TEXT; | |
| break; | |
| case XML_TEXTWRITER_CDATA: | |
| xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, | |
| "xmlTextWriterStartCDATA : CDATA not allowed in this context!\n"); | |
| return -1; | |
| default: | |
| return -1; | |
| } | |
| } | |
| } | |
| p = (xmlTextWriterStackEntry *) | |
| xmlMalloc(sizeof(xmlTextWriterStackEntry)); | |
| if (p == 0) { | |
| xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, | |
| "xmlTextWriterStartCDATA : out of memory!\n"); | |
| return -1; | |
| } | |
| p->name = NULL; | |
| p->state = XML_TEXTWRITER_CDATA; | |
| xmlListPushFront(writer->nodes, p); | |
| count = xmlOutputBufferWriteString(writer->out, "<![CDATA["); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| return sum; | |
| } | |
| /** | |
| * xmlTextWriterEndCDATA: | |
| * @writer: the xmlTextWriterPtr | |
| * | |
| * End an xml CDATA section. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterEndCDATA(xmlTextWriterPtr writer) | |
| { | |
| int count; | |
| int sum; | |
| xmlLinkPtr lk; | |
| xmlTextWriterStackEntry *p; | |
| if (writer == NULL) | |
| return -1; | |
| lk = xmlListFront(writer->nodes); | |
| if (lk == 0) | |
| return -1; | |
| p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); | |
| if (p == 0) | |
| return -1; | |
| sum = 0; | |
| switch (p->state) { | |
| case XML_TEXTWRITER_CDATA: | |
| count = xmlOutputBufferWriteString(writer->out, "]]>"); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| break; | |
| default: | |
| return -1; | |
| } | |
| xmlListPopFront(writer->nodes); | |
| return sum; | |
| } | |
| /** | |
| * xmlTextWriterWriteFormatCDATA: | |
| * @writer: the xmlTextWriterPtr | |
| * @format: format string (see printf) | |
| * @...: extra parameters for the format | |
| * | |
| * Write a formatted xml CDATA. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int XMLCDECL | |
| xmlTextWriterWriteFormatCDATA(xmlTextWriterPtr writer, const char *format, | |
| ...) | |
| { | |
| int rc; | |
| va_list ap; | |
| va_start(ap, format); | |
| rc = xmlTextWriterWriteVFormatCDATA(writer, format, ap); | |
| va_end(ap); | |
| return rc; | |
| } | |
| /** | |
| * xmlTextWriterWriteVFormatCDATA: | |
| * @writer: the xmlTextWriterPtr | |
| * @format: format string (see printf) | |
| * @argptr: pointer to the first member of the variable argument list. | |
| * | |
| * Write a formatted xml CDATA. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterWriteVFormatCDATA(xmlTextWriterPtr writer, const char *format, | |
| va_list argptr) | |
| { | |
| int rc; | |
| xmlChar *buf; | |
| if (writer == NULL) | |
| return -1; | |
| buf = xmlTextWriterVSprintf(format, argptr); | |
| if (buf == NULL) | |
| return -1; | |
| rc = xmlTextWriterWriteCDATA(writer, buf); | |
| xmlFree(buf); | |
| return rc; | |
| } | |
| /** | |
| * xmlTextWriterWriteCDATA: | |
| * @writer: the xmlTextWriterPtr | |
| * @content: CDATA content | |
| * | |
| * Write an xml CDATA. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterWriteCDATA(xmlTextWriterPtr writer, const xmlChar * content) | |
| { | |
| int count; | |
| int sum; | |
| sum = 0; | |
| count = xmlTextWriterStartCDATA(writer); | |
| if (count == -1) | |
| return -1; | |
| sum += count; | |
| if (content != 0) { | |
| count = xmlTextWriterWriteString(writer, content); | |
| if (count == -1) | |
| return -1; | |
| sum += count; | |
| } | |
| count = xmlTextWriterEndCDATA(writer); | |
| if (count == -1) | |
| return -1; | |
| sum += count; | |
| return sum; | |
| } | |
| /** | |
| * xmlTextWriterStartDTD: | |
| * @writer: the xmlTextWriterPtr | |
| * @name: the name of the DTD | |
| * @pubid: the public identifier, which is an alternative to the system identifier | |
| * @sysid: the system identifier, which is the URI of the DTD | |
| * | |
| * Start an xml DTD. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterStartDTD(xmlTextWriterPtr writer, | |
| const xmlChar * name, | |
| const xmlChar * pubid, const xmlChar * sysid) | |
| { | |
| int count; | |
| int sum; | |
| xmlLinkPtr lk; | |
| xmlTextWriterStackEntry *p; | |
| if (writer == NULL || name == NULL || *name == '\0') | |
| return -1; | |
| sum = 0; | |
| lk = xmlListFront(writer->nodes); | |
| if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) { | |
| xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, | |
| "xmlTextWriterStartDTD : DTD allowed only in prolog!\n"); | |
| return -1; | |
| } | |
| p = (xmlTextWriterStackEntry *) | |
| xmlMalloc(sizeof(xmlTextWriterStackEntry)); | |
| if (p == 0) { | |
| xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, | |
| "xmlTextWriterStartDTD : out of memory!\n"); | |
| return -1; | |
| } | |
| p->name = xmlStrdup(name); | |
| if (p->name == 0) { | |
| xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, | |
| "xmlTextWriterStartDTD : out of memory!\n"); | |
| xmlFree(p); | |
| return -1; | |
| } | |
| p->state = XML_TEXTWRITER_DTD; | |
| xmlListPushFront(writer->nodes, p); | |
| count = xmlOutputBufferWriteString(writer->out, "<!DOCTYPE "); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlOutputBufferWriteString(writer->out, (const char *) name); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| if (pubid != 0) { | |
| if (sysid == 0) { | |
| xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, | |
| "xmlTextWriterStartDTD : system identifier needed!\n"); | |
| return -1; | |
| } | |
| if (writer->indent) | |
| count = xmlOutputBufferWrite(writer->out, 1, "\n"); | |
| else | |
| count = xmlOutputBufferWrite(writer->out, 1, " "); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlOutputBufferWriteString(writer->out, "PUBLIC "); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = | |
| xmlOutputBufferWriteString(writer->out, (const char *) pubid); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| } | |
| if (sysid != 0) { | |
| if (pubid == 0) { | |
| if (writer->indent) | |
| count = xmlOutputBufferWrite(writer->out, 1, "\n"); | |
| else | |
| count = xmlOutputBufferWrite(writer->out, 1, " "); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlOutputBufferWriteString(writer->out, "SYSTEM "); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| } else { | |
| if (writer->indent) | |
| count = xmlOutputBufferWriteString(writer->out, "\n "); | |
| else | |
| count = xmlOutputBufferWrite(writer->out, 1, " "); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| } | |
| count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = | |
| xmlOutputBufferWriteString(writer->out, (const char *) sysid); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| } | |
| return sum; | |
| } | |
| /** | |
| * xmlTextWriterEndDTD: | |
| * @writer: the xmlTextWriterPtr | |
| * | |
| * End an xml DTD. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterEndDTD(xmlTextWriterPtr writer) | |
| { | |
| int loop; | |
| int count; | |
| int sum; | |
| xmlLinkPtr lk; | |
| xmlTextWriterStackEntry *p; | |
| if (writer == NULL) | |
| return -1; | |
| sum = 0; | |
| loop = 1; | |
| while (loop) { | |
| lk = xmlListFront(writer->nodes); | |
| if (lk == NULL) | |
| break; | |
| p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); | |
| if (p == 0) | |
| break; | |
| switch (p->state) { | |
| case XML_TEXTWRITER_DTD_TEXT: | |
| count = xmlOutputBufferWriteString(writer->out, "]"); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| /* fallthrough */ | |
| case XML_TEXTWRITER_DTD: | |
| count = xmlOutputBufferWriteString(writer->out, ">"); | |
| if (writer->indent) { | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlOutputBufferWriteString(writer->out, "\n"); | |
| } | |
| xmlListPopFront(writer->nodes); | |
| break; | |
| case XML_TEXTWRITER_DTD_ELEM: | |
| case XML_TEXTWRITER_DTD_ELEM_TEXT: | |
| count = xmlTextWriterEndDTDElement(writer); | |
| break; | |
| case XML_TEXTWRITER_DTD_ATTL: | |
| case XML_TEXTWRITER_DTD_ATTL_TEXT: | |
| count = xmlTextWriterEndDTDAttlist(writer); | |
| break; | |
| case XML_TEXTWRITER_DTD_ENTY: | |
| case XML_TEXTWRITER_DTD_PENT: | |
| case XML_TEXTWRITER_DTD_ENTY_TEXT: | |
| count = xmlTextWriterEndDTDEntity(writer); | |
| break; | |
| case XML_TEXTWRITER_COMMENT: | |
| count = xmlTextWriterEndComment(writer); | |
| break; | |
| default: | |
| loop = 0; | |
| continue; | |
| } | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| } | |
| return sum; | |
| } | |
| /** | |
| * xmlTextWriterWriteFormatDTD: | |
| * @writer: the xmlTextWriterPtr | |
| * @name: the name of the DTD | |
| * @pubid: the public identifier, which is an alternative to the system identifier | |
| * @sysid: the system identifier, which is the URI of the DTD | |
| * @format: format string (see printf) | |
| * @...: extra parameters for the format | |
| * | |
| * Write a DTD with a formatted markup declarations part. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int XMLCDECL | |
| xmlTextWriterWriteFormatDTD(xmlTextWriterPtr writer, | |
| const xmlChar * name, | |
| const xmlChar * pubid, | |
| const xmlChar * sysid, const char *format, ...) | |
| { | |
| int rc; | |
| va_list ap; | |
| va_start(ap, format); | |
| rc = xmlTextWriterWriteVFormatDTD(writer, name, pubid, sysid, format, | |
| ap); | |
| va_end(ap); | |
| return rc; | |
| } | |
| /** | |
| * xmlTextWriterWriteVFormatDTD: | |
| * @writer: the xmlTextWriterPtr | |
| * @name: the name of the DTD | |
| * @pubid: the public identifier, which is an alternative to the system identifier | |
| * @sysid: the system identifier, which is the URI of the DTD | |
| * @format: format string (see printf) | |
| * @argptr: pointer to the first member of the variable argument list. | |
| * | |
| * Write a DTD with a formatted markup declarations part. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterWriteVFormatDTD(xmlTextWriterPtr writer, | |
| const xmlChar * name, | |
| const xmlChar * pubid, | |
| const xmlChar * sysid, | |
| const char *format, va_list argptr) | |
| { | |
| int rc; | |
| xmlChar *buf; | |
| if (writer == NULL) | |
| return -1; | |
| buf = xmlTextWriterVSprintf(format, argptr); | |
| if (buf == NULL) | |
| return -1; | |
| rc = xmlTextWriterWriteDTD(writer, name, pubid, sysid, buf); | |
| xmlFree(buf); | |
| return rc; | |
| } | |
| /** | |
| * xmlTextWriterWriteDTD: | |
| * @writer: the xmlTextWriterPtr | |
| * @name: the name of the DTD | |
| * @pubid: the public identifier, which is an alternative to the system identifier | |
| * @sysid: the system identifier, which is the URI of the DTD | |
| * @subset: string content of the DTD | |
| * | |
| * Write a DTD. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterWriteDTD(xmlTextWriterPtr writer, | |
| const xmlChar * name, | |
| const xmlChar * pubid, | |
| const xmlChar * sysid, const xmlChar * subset) | |
| { | |
| int count; | |
| int sum; | |
| sum = 0; | |
| count = xmlTextWriterStartDTD(writer, name, pubid, sysid); | |
| if (count == -1) | |
| return -1; | |
| sum += count; | |
| if (subset != 0) { | |
| count = xmlTextWriterWriteString(writer, subset); | |
| if (count == -1) | |
| return -1; | |
| sum += count; | |
| } | |
| count = xmlTextWriterEndDTD(writer); | |
| if (count == -1) | |
| return -1; | |
| sum += count; | |
| return sum; | |
| } | |
| /** | |
| * xmlTextWriterStartDTDElement: | |
| * @writer: the xmlTextWriterPtr | |
| * @name: the name of the DTD element | |
| * | |
| * Start an xml DTD element. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterStartDTDElement(xmlTextWriterPtr writer, const xmlChar * name) | |
| { | |
| int count; | |
| int sum; | |
| xmlLinkPtr lk; | |
| xmlTextWriterStackEntry *p; | |
| if (writer == NULL || name == NULL || *name == '\0') | |
| return -1; | |
| sum = 0; | |
| lk = xmlListFront(writer->nodes); | |
| if (lk == 0) { | |
| return -1; | |
| } | |
| p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); | |
| if (p != 0) { | |
| switch (p->state) { | |
| case XML_TEXTWRITER_DTD: | |
| count = xmlOutputBufferWriteString(writer->out, " ["); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| if (writer->indent) { | |
| count = xmlOutputBufferWriteString(writer->out, "\n"); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| } | |
| p->state = XML_TEXTWRITER_DTD_TEXT; | |
| /* fallthrough */ | |
| case XML_TEXTWRITER_DTD_TEXT: | |
| case XML_TEXTWRITER_NONE: | |
| break; | |
| default: | |
| return -1; | |
| } | |
| } | |
| p = (xmlTextWriterStackEntry *) | |
| xmlMalloc(sizeof(xmlTextWriterStackEntry)); | |
| if (p == 0) { | |
| xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, | |
| "xmlTextWriterStartDTDElement : out of memory!\n"); | |
| return -1; | |
| } | |
| p->name = xmlStrdup(name); | |
| if (p->name == 0) { | |
| xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, | |
| "xmlTextWriterStartDTDElement : out of memory!\n"); | |
| xmlFree(p); | |
| return -1; | |
| } | |
| p->state = XML_TEXTWRITER_DTD_ELEM; | |
| xmlListPushFront(writer->nodes, p); | |
| if (writer->indent) { | |
| count = xmlTextWriterWriteIndent(writer); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| } | |
| count = xmlOutputBufferWriteString(writer->out, "<!ELEMENT "); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlOutputBufferWriteString(writer->out, (const char *) name); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| return sum; | |
| } | |
| /** | |
| * xmlTextWriterEndDTDElement: | |
| * @writer: the xmlTextWriterPtr | |
| * | |
| * End an xml DTD element. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterEndDTDElement(xmlTextWriterPtr writer) | |
| { | |
| int count; | |
| int sum; | |
| xmlLinkPtr lk; | |
| xmlTextWriterStackEntry *p; | |
| if (writer == NULL) | |
| return -1; | |
| sum = 0; | |
| lk = xmlListFront(writer->nodes); | |
| if (lk == 0) | |
| return -1; | |
| p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); | |
| if (p == 0) | |
| return -1; | |
| switch (p->state) { | |
| case XML_TEXTWRITER_DTD_ELEM: | |
| case XML_TEXTWRITER_DTD_ELEM_TEXT: | |
| count = xmlOutputBufferWriteString(writer->out, ">"); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| break; | |
| default: | |
| return -1; | |
| } | |
| if (writer->indent) { | |
| count = xmlOutputBufferWriteString(writer->out, "\n"); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| } | |
| xmlListPopFront(writer->nodes); | |
| return sum; | |
| } | |
| /** | |
| * xmlTextWriterWriteFormatDTDElement: | |
| * @writer: the xmlTextWriterPtr | |
| * @name: the name of the DTD element | |
| * @format: format string (see printf) | |
| * @...: extra parameters for the format | |
| * | |
| * Write a formatted DTD element. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int XMLCDECL | |
| xmlTextWriterWriteFormatDTDElement(xmlTextWriterPtr writer, | |
| const xmlChar * name, | |
| const char *format, ...) | |
| { | |
| int rc; | |
| va_list ap; | |
| va_start(ap, format); | |
| rc = xmlTextWriterWriteVFormatDTDElement(writer, name, format, ap); | |
| va_end(ap); | |
| return rc; | |
| } | |
| /** | |
| * xmlTextWriterWriteVFormatDTDElement: | |
| * @writer: the xmlTextWriterPtr | |
| * @name: the name of the DTD element | |
| * @format: format string (see printf) | |
| * @argptr: pointer to the first member of the variable argument list. | |
| * | |
| * Write a formatted DTD element. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterWriteVFormatDTDElement(xmlTextWriterPtr writer, | |
| const xmlChar * name, | |
| const char *format, va_list argptr) | |
| { | |
| int rc; | |
| xmlChar *buf; | |
| if (writer == NULL) | |
| return -1; | |
| buf = xmlTextWriterVSprintf(format, argptr); | |
| if (buf == NULL) | |
| return -1; | |
| rc = xmlTextWriterWriteDTDElement(writer, name, buf); | |
| xmlFree(buf); | |
| return rc; | |
| } | |
| /** | |
| * xmlTextWriterWriteDTDElement: | |
| * @writer: the xmlTextWriterPtr | |
| * @name: the name of the DTD element | |
| * @content: content of the element | |
| * | |
| * Write a DTD element. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterWriteDTDElement(xmlTextWriterPtr writer, | |
| const xmlChar * name, const xmlChar * content) | |
| { | |
| int count; | |
| int sum; | |
| if (content == NULL) | |
| return -1; | |
| sum = 0; | |
| count = xmlTextWriterStartDTDElement(writer, name); | |
| if (count == -1) | |
| return -1; | |
| sum += count; | |
| count = xmlTextWriterWriteString(writer, content); | |
| if (count == -1) | |
| return -1; | |
| sum += count; | |
| count = xmlTextWriterEndDTDElement(writer); | |
| if (count == -1) | |
| return -1; | |
| sum += count; | |
| return sum; | |
| } | |
| /** | |
| * xmlTextWriterStartDTDAttlist: | |
| * @writer: the xmlTextWriterPtr | |
| * @name: the name of the DTD ATTLIST | |
| * | |
| * Start an xml DTD ATTLIST. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterStartDTDAttlist(xmlTextWriterPtr writer, const xmlChar * name) | |
| { | |
| int count; | |
| int sum; | |
| xmlLinkPtr lk; | |
| xmlTextWriterStackEntry *p; | |
| if (writer == NULL || name == NULL || *name == '\0') | |
| return -1; | |
| sum = 0; | |
| lk = xmlListFront(writer->nodes); | |
| if (lk == 0) { | |
| return -1; | |
| } | |
| p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); | |
| if (p != 0) { | |
| switch (p->state) { | |
| case XML_TEXTWRITER_DTD: | |
| count = xmlOutputBufferWriteString(writer->out, " ["); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| if (writer->indent) { | |
| count = xmlOutputBufferWriteString(writer->out, "\n"); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| } | |
| p->state = XML_TEXTWRITER_DTD_TEXT; | |
| /* fallthrough */ | |
| case XML_TEXTWRITER_DTD_TEXT: | |
| case XML_TEXTWRITER_NONE: | |
| break; | |
| default: | |
| return -1; | |
| } | |
| } | |
| p = (xmlTextWriterStackEntry *) | |
| xmlMalloc(sizeof(xmlTextWriterStackEntry)); | |
| if (p == 0) { | |
| xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, | |
| "xmlTextWriterStartDTDAttlist : out of memory!\n"); | |
| return -1; | |
| } | |
| p->name = xmlStrdup(name); | |
| if (p->name == 0) { | |
| xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, | |
| "xmlTextWriterStartDTDAttlist : out of memory!\n"); | |
| xmlFree(p); | |
| return -1; | |
| } | |
| p->state = XML_TEXTWRITER_DTD_ATTL; | |
| xmlListPushFront(writer->nodes, p); | |
| if (writer->indent) { | |
| count = xmlTextWriterWriteIndent(writer); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| } | |
| count = xmlOutputBufferWriteString(writer->out, "<!ATTLIST "); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlOutputBufferWriteString(writer->out, (const char *) name); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| return sum; | |
| } | |
| /** | |
| * xmlTextWriterEndDTDAttlist: | |
| * @writer: the xmlTextWriterPtr | |
| * | |
| * End an xml DTD attribute list. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterEndDTDAttlist(xmlTextWriterPtr writer) | |
| { | |
| int count; | |
| int sum; | |
| xmlLinkPtr lk; | |
| xmlTextWriterStackEntry *p; | |
| if (writer == NULL) | |
| return -1; | |
| sum = 0; | |
| lk = xmlListFront(writer->nodes); | |
| if (lk == 0) | |
| return -1; | |
| p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); | |
| if (p == 0) | |
| return -1; | |
| switch (p->state) { | |
| case XML_TEXTWRITER_DTD_ATTL: | |
| case XML_TEXTWRITER_DTD_ATTL_TEXT: | |
| count = xmlOutputBufferWriteString(writer->out, ">"); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| break; | |
| default: | |
| return -1; | |
| } | |
| if (writer->indent) { | |
| count = xmlOutputBufferWriteString(writer->out, "\n"); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| } | |
| xmlListPopFront(writer->nodes); | |
| return sum; | |
| } | |
| /** | |
| * xmlTextWriterWriteFormatDTDAttlist: | |
| * @writer: the xmlTextWriterPtr | |
| * @name: the name of the DTD ATTLIST | |
| * @format: format string (see printf) | |
| * @...: extra parameters for the format | |
| * | |
| * Write a formatted DTD ATTLIST. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int XMLCDECL | |
| xmlTextWriterWriteFormatDTDAttlist(xmlTextWriterPtr writer, | |
| const xmlChar * name, | |
| const char *format, ...) | |
| { | |
| int rc; | |
| va_list ap; | |
| va_start(ap, format); | |
| rc = xmlTextWriterWriteVFormatDTDAttlist(writer, name, format, ap); | |
| va_end(ap); | |
| return rc; | |
| } | |
| /** | |
| * xmlTextWriterWriteVFormatDTDAttlist: | |
| * @writer: the xmlTextWriterPtr | |
| * @name: the name of the DTD ATTLIST | |
| * @format: format string (see printf) | |
| * @argptr: pointer to the first member of the variable argument list. | |
| * | |
| * Write a formatted DTD ATTLIST. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterWriteVFormatDTDAttlist(xmlTextWriterPtr writer, | |
| const xmlChar * name, | |
| const char *format, va_list argptr) | |
| { | |
| int rc; | |
| xmlChar *buf; | |
| if (writer == NULL) | |
| return -1; | |
| buf = xmlTextWriterVSprintf(format, argptr); | |
| if (buf == NULL) | |
| return -1; | |
| rc = xmlTextWriterWriteDTDAttlist(writer, name, buf); | |
| xmlFree(buf); | |
| return rc; | |
| } | |
| /** | |
| * xmlTextWriterWriteDTDAttlist: | |
| * @writer: the xmlTextWriterPtr | |
| * @name: the name of the DTD ATTLIST | |
| * @content: content of the ATTLIST | |
| * | |
| * Write a DTD ATTLIST. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterWriteDTDAttlist(xmlTextWriterPtr writer, | |
| const xmlChar * name, const xmlChar * content) | |
| { | |
| int count; | |
| int sum; | |
| if (content == NULL) | |
| return -1; | |
| sum = 0; | |
| count = xmlTextWriterStartDTDAttlist(writer, name); | |
| if (count == -1) | |
| return -1; | |
| sum += count; | |
| count = xmlTextWriterWriteString(writer, content); | |
| if (count == -1) | |
| return -1; | |
| sum += count; | |
| count = xmlTextWriterEndDTDAttlist(writer); | |
| if (count == -1) | |
| return -1; | |
| sum += count; | |
| return sum; | |
| } | |
| /** | |
| * xmlTextWriterStartDTDEntity: | |
| * @writer: the xmlTextWriterPtr | |
| * @pe: TRUE if this is a parameter entity, FALSE if not | |
| * @name: the name of the DTD ATTLIST | |
| * | |
| * Start an xml DTD ATTLIST. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterStartDTDEntity(xmlTextWriterPtr writer, | |
| int pe, const xmlChar * name) | |
| { | |
| int count; | |
| int sum; | |
| xmlLinkPtr lk; | |
| xmlTextWriterStackEntry *p; | |
| if (writer == NULL || name == NULL || *name == '\0') | |
| return -1; | |
| sum = 0; | |
| lk = xmlListFront(writer->nodes); | |
| if (lk != 0) { | |
| p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); | |
| if (p != 0) { | |
| switch (p->state) { | |
| case XML_TEXTWRITER_DTD: | |
| count = xmlOutputBufferWriteString(writer->out, " ["); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| if (writer->indent) { | |
| count = | |
| xmlOutputBufferWriteString(writer->out, "\n"); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| } | |
| p->state = XML_TEXTWRITER_DTD_TEXT; | |
| /* fallthrough */ | |
| case XML_TEXTWRITER_DTD_TEXT: | |
| case XML_TEXTWRITER_NONE: | |
| break; | |
| default: | |
| return -1; | |
| } | |
| } | |
| } | |
| p = (xmlTextWriterStackEntry *) | |
| xmlMalloc(sizeof(xmlTextWriterStackEntry)); | |
| if (p == 0) { | |
| xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, | |
| "xmlTextWriterStartDTDElement : out of memory!\n"); | |
| return -1; | |
| } | |
| p->name = xmlStrdup(name); | |
| if (p->name == 0) { | |
| xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY, | |
| "xmlTextWriterStartDTDElement : out of memory!\n"); | |
| xmlFree(p); | |
| return -1; | |
| } | |
| if (pe != 0) | |
| p->state = XML_TEXTWRITER_DTD_PENT; | |
| else | |
| p->state = XML_TEXTWRITER_DTD_ENTY; | |
| xmlListPushFront(writer->nodes, p); | |
| if (writer->indent) { | |
| count = xmlTextWriterWriteIndent(writer); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| } | |
| count = xmlOutputBufferWriteString(writer->out, "<!ENTITY "); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| if (pe != 0) { | |
| count = xmlOutputBufferWriteString(writer->out, "% "); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| } | |
| count = xmlOutputBufferWriteString(writer->out, (const char *) name); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| return sum; | |
| } | |
| /** | |
| * xmlTextWriterEndDTDEntity: | |
| * @writer: the xmlTextWriterPtr | |
| * | |
| * End an xml DTD entity. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterEndDTDEntity(xmlTextWriterPtr writer) | |
| { | |
| int count; | |
| int sum; | |
| xmlLinkPtr lk; | |
| xmlTextWriterStackEntry *p; | |
| if (writer == NULL) | |
| return -1; | |
| sum = 0; | |
| lk = xmlListFront(writer->nodes); | |
| if (lk == 0) | |
| return -1; | |
| p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); | |
| if (p == 0) | |
| return -1; | |
| switch (p->state) { | |
| case XML_TEXTWRITER_DTD_ENTY_TEXT: | |
| count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| case XML_TEXTWRITER_DTD_ENTY: | |
| case XML_TEXTWRITER_DTD_PENT: | |
| count = xmlOutputBufferWriteString(writer->out, ">"); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| break; | |
| default: | |
| return -1; | |
| } | |
| if (writer->indent) { | |
| count = xmlOutputBufferWriteString(writer->out, "\n"); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| } | |
| xmlListPopFront(writer->nodes); | |
| return sum; | |
| } | |
| /** | |
| * xmlTextWriterWriteFormatDTDInternalEntity: | |
| * @writer: the xmlTextWriterPtr | |
| * @pe: TRUE if this is a parameter entity, FALSE if not | |
| * @name: the name of the DTD entity | |
| * @format: format string (see printf) | |
| * @...: extra parameters for the format | |
| * | |
| * Write a formatted DTD internal entity. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int XMLCDECL | |
| xmlTextWriterWriteFormatDTDInternalEntity(xmlTextWriterPtr writer, | |
| int pe, | |
| const xmlChar * name, | |
| const char *format, ...) | |
| { | |
| int rc; | |
| va_list ap; | |
| va_start(ap, format); | |
| rc = xmlTextWriterWriteVFormatDTDInternalEntity(writer, pe, name, | |
| format, ap); | |
| va_end(ap); | |
| return rc; | |
| } | |
| /** | |
| * xmlTextWriterWriteVFormatDTDInternalEntity: | |
| * @writer: the xmlTextWriterPtr | |
| * @pe: TRUE if this is a parameter entity, FALSE if not | |
| * @name: the name of the DTD entity | |
| * @format: format string (see printf) | |
| * @argptr: pointer to the first member of the variable argument list. | |
| * | |
| * Write a formatted DTD internal entity. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterWriteVFormatDTDInternalEntity(xmlTextWriterPtr writer, | |
| int pe, | |
| const xmlChar * name, | |
| const char *format, | |
| va_list argptr) | |
| { | |
| int rc; | |
| xmlChar *buf; | |
| if (writer == NULL) | |
| return -1; | |
| buf = xmlTextWriterVSprintf(format, argptr); | |
| if (buf == NULL) | |
| return -1; | |
| rc = xmlTextWriterWriteDTDInternalEntity(writer, pe, name, buf); | |
| xmlFree(buf); | |
| return rc; | |
| } | |
| /** | |
| * xmlTextWriterWriteDTDEntity: | |
| * @writer: the xmlTextWriterPtr | |
| * @pe: TRUE if this is a parameter entity, FALSE if not | |
| * @name: the name of the DTD entity | |
| * @pubid: the public identifier, which is an alternative to the system identifier | |
| * @sysid: the system identifier, which is the URI of the DTD | |
| * @ndataid: the xml notation name. | |
| * @content: content of the entity | |
| * | |
| * Write a DTD entity. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterWriteDTDEntity(xmlTextWriterPtr writer, | |
| int pe, | |
| const xmlChar * name, | |
| const xmlChar * pubid, | |
| const xmlChar * sysid, | |
| const xmlChar * ndataid, | |
| const xmlChar * content) | |
| { | |
| if ((content == NULL) && (pubid == NULL) && (sysid == NULL)) | |
| return -1; | |
| if ((pe != 0) && (ndataid != NULL)) | |
| return -1; | |
| if ((pubid == NULL) && (sysid == NULL)) | |
| return xmlTextWriterWriteDTDInternalEntity(writer, pe, name, | |
| content); | |
| return xmlTextWriterWriteDTDExternalEntity(writer, pe, name, pubid, | |
| sysid, ndataid); | |
| } | |
| /** | |
| * xmlTextWriterWriteDTDInternalEntity: | |
| * @writer: the xmlTextWriterPtr | |
| * @pe: TRUE if this is a parameter entity, FALSE if not | |
| * @name: the name of the DTD entity | |
| * @content: content of the entity | |
| * | |
| * Write a DTD internal entity. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterWriteDTDInternalEntity(xmlTextWriterPtr writer, | |
| int pe, | |
| const xmlChar * name, | |
| const xmlChar * content) | |
| { | |
| int count; | |
| int sum; | |
| if ((name == NULL) || (*name == '\0') || (content == NULL)) | |
| return -1; | |
| sum = 0; | |
| count = xmlTextWriterStartDTDEntity(writer, pe, name); | |
| if (count == -1) | |
| return -1; | |
| sum += count; | |
| count = xmlTextWriterWriteString(writer, content); | |
| if (count == -1) | |
| return -1; | |
| sum += count; | |
| count = xmlTextWriterEndDTDEntity(writer); | |
| if (count == -1) | |
| return -1; | |
| sum += count; | |
| return sum; | |
| } | |
| /** | |
| * xmlTextWriterWriteDTDExternalEntity: | |
| * @writer: the xmlTextWriterPtr | |
| * @pe: TRUE if this is a parameter entity, FALSE if not | |
| * @name: the name of the DTD entity | |
| * @pubid: the public identifier, which is an alternative to the system identifier | |
| * @sysid: the system identifier, which is the URI of the DTD | |
| * @ndataid: the xml notation name. | |
| * | |
| * Write a DTD external entity. The entity must have been started with xmlTextWriterStartDTDEntity | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterWriteDTDExternalEntity(xmlTextWriterPtr writer, | |
| int pe, | |
| const xmlChar * name, | |
| const xmlChar * pubid, | |
| const xmlChar * sysid, | |
| const xmlChar * ndataid) | |
| { | |
| int count; | |
| int sum; | |
| if (((pubid == NULL) && (sysid == NULL))) | |
| return -1; | |
| if ((pe != 0) && (ndataid != NULL)) | |
| return -1; | |
| sum = 0; | |
| count = xmlTextWriterStartDTDEntity(writer, pe, name); | |
| if (count == -1) | |
| return -1; | |
| sum += count; | |
| count = | |
| xmlTextWriterWriteDTDExternalEntityContents(writer, pubid, sysid, | |
| ndataid); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlTextWriterEndDTDEntity(writer); | |
| if (count == -1) | |
| return -1; | |
| sum += count; | |
| return sum; | |
| } | |
| /** | |
| * xmlTextWriterWriteDTDExternalEntityContents: | |
| * @writer: the xmlTextWriterPtr | |
| * @pubid: the public identifier, which is an alternative to the system identifier | |
| * @sysid: the system identifier, which is the URI of the DTD | |
| * @ndataid: the xml notation name. | |
| * | |
| * Write the contents of a DTD external entity. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterWriteDTDExternalEntityContents(xmlTextWriterPtr writer, | |
| const xmlChar * pubid, | |
| const xmlChar * sysid, | |
| const xmlChar * ndataid) | |
| { | |
| int count; | |
| int sum; | |
| xmlLinkPtr lk; | |
| xmlTextWriterStackEntry *p; | |
| if (writer == NULL) { | |
| xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, | |
| "xmlTextWriterWriteDTDExternalEntityContents: xmlTextWriterPtr invalid!\n"); | |
| return -1; | |
| } | |
| sum = 0; | |
| lk = xmlListFront(writer->nodes); | |
| if (lk == 0) { | |
| xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, | |
| "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n"); | |
| return -1; | |
| } | |
| p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); | |
| if (p == 0) | |
| return -1; | |
| switch (p->state) { | |
| case XML_TEXTWRITER_DTD_ENTY: | |
| break; | |
| case XML_TEXTWRITER_DTD_PENT: | |
| if (ndataid != NULL) { | |
| xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, | |
| "xmlTextWriterWriteDTDExternalEntityContents: notation not allowed with parameter entities!\n"); | |
| return -1; | |
| } | |
| break; | |
| default: | |
| xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, | |
| "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n"); | |
| return -1; | |
| } | |
| if (pubid != 0) { | |
| if (sysid == 0) { | |
| xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR, | |
| "xmlTextWriterWriteDTDExternalEntityContents: system identifier needed!\n"); | |
| return -1; | |
| } | |
| count = xmlOutputBufferWriteString(writer->out, " PUBLIC "); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = | |
| xmlOutputBufferWriteString(writer->out, (const char *) pubid); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| } | |
| if (sysid != 0) { | |
| if (pubid == 0) { | |
| count = xmlOutputBufferWriteString(writer->out, " SYSTEM"); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| } | |
| count = xmlOutputBufferWriteString(writer->out, " "); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = | |
| xmlOutputBufferWriteString(writer->out, (const char *) sysid); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| } | |
| if (ndataid != NULL) { | |
| count = xmlOutputBufferWriteString(writer->out, " NDATA "); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = | |
| xmlOutputBufferWriteString(writer->out, | |
| (const char *) ndataid); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| } | |
| return sum; | |
| } | |
| /** | |
| * xmlTextWriterWriteDTDNotation: | |
| * @writer: the xmlTextWriterPtr | |
| * @name: the name of the xml notation | |
| * @pubid: the public identifier, which is an alternative to the system identifier | |
| * @sysid: the system identifier, which is the URI of the DTD | |
| * | |
| * Write a DTD entity. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterWriteDTDNotation(xmlTextWriterPtr writer, | |
| const xmlChar * name, | |
| const xmlChar * pubid, const xmlChar * sysid) | |
| { | |
| int count; | |
| int sum; | |
| xmlLinkPtr lk; | |
| xmlTextWriterStackEntry *p; | |
| if (writer == NULL || name == NULL || *name == '\0') | |
| return -1; | |
| sum = 0; | |
| lk = xmlListFront(writer->nodes); | |
| if (lk == 0) { | |
| return -1; | |
| } | |
| p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); | |
| if (p != 0) { | |
| switch (p->state) { | |
| case XML_TEXTWRITER_DTD: | |
| count = xmlOutputBufferWriteString(writer->out, " ["); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| if (writer->indent) { | |
| count = xmlOutputBufferWriteString(writer->out, "\n"); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| } | |
| p->state = XML_TEXTWRITER_DTD_TEXT; | |
| /* fallthrough */ | |
| case XML_TEXTWRITER_DTD_TEXT: | |
| break; | |
| default: | |
| return -1; | |
| } | |
| } | |
| if (writer->indent) { | |
| count = xmlTextWriterWriteIndent(writer); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| } | |
| count = xmlOutputBufferWriteString(writer->out, "<!NOTATION "); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlOutputBufferWriteString(writer->out, (const char *) name); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| if (pubid != 0) { | |
| count = xmlOutputBufferWriteString(writer->out, " PUBLIC "); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = | |
| xmlOutputBufferWriteString(writer->out, (const char *) pubid); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| } | |
| if (sysid != 0) { | |
| if (pubid == 0) { | |
| count = xmlOutputBufferWriteString(writer->out, " SYSTEM"); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| } | |
| count = xmlOutputBufferWriteString(writer->out, " "); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = | |
| xmlOutputBufferWriteString(writer->out, (const char *) sysid); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| } | |
| count = xmlOutputBufferWriteString(writer->out, ">"); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| return sum; | |
| } | |
| /** | |
| * xmlTextWriterFlush: | |
| * @writer: the xmlTextWriterPtr | |
| * | |
| * Flush the output buffer. | |
| * | |
| * Returns the bytes written (may be 0 because of buffering) or -1 in case of error | |
| */ | |
| int | |
| xmlTextWriterFlush(xmlTextWriterPtr writer) | |
| { | |
| int count; | |
| if (writer == NULL) | |
| return -1; | |
| if (writer->out == NULL) | |
| count = 0; | |
| else | |
| count = xmlOutputBufferFlush(writer->out); | |
| return count; | |
| } | |
| /** | |
| * misc | |
| */ | |
| /** | |
| * xmlFreeTextWriterStackEntry: | |
| * @lk: the xmlLinkPtr | |
| * | |
| * Free callback for the xmlList. | |
| */ | |
| static void | |
| xmlFreeTextWriterStackEntry(xmlLinkPtr lk) | |
| { | |
| xmlTextWriterStackEntry *p; | |
| p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk); | |
| if (p == 0) | |
| return; | |
| if (p->name != 0) | |
| xmlFree(p->name); | |
| xmlFree(p); | |
| } | |
| /** | |
| * xmlCmpTextWriterStackEntry: | |
| * @data0: the first data | |
| * @data1: the second data | |
| * | |
| * Compare callback for the xmlList. | |
| * | |
| * Returns -1, 0, 1 | |
| */ | |
| static int | |
| xmlCmpTextWriterStackEntry(const void *data0, const void *data1) | |
| { | |
| xmlTextWriterStackEntry *p0; | |
| xmlTextWriterStackEntry *p1; | |
| if (data0 == data1) | |
| return 0; | |
| if (data0 == 0) | |
| return -1; | |
| if (data1 == 0) | |
| return 1; | |
| p0 = (xmlTextWriterStackEntry *) data0; | |
| p1 = (xmlTextWriterStackEntry *) data1; | |
| return xmlStrcmp(p0->name, p1->name); | |
| } | |
| /** | |
| * misc | |
| */ | |
| /** | |
| * xmlTextWriterOutputNSDecl: | |
| * @writer: the xmlTextWriterPtr | |
| * | |
| * Output the current namespace declarations. | |
| */ | |
| static int | |
| xmlTextWriterOutputNSDecl(xmlTextWriterPtr writer) | |
| { | |
| xmlLinkPtr lk; | |
| xmlTextWriterNsStackEntry *np; | |
| int count; | |
| int sum; | |
| sum = 0; | |
| while (!xmlListEmpty(writer->nsstack)) { | |
| xmlChar *namespaceURI = NULL; | |
| xmlChar *prefix = NULL; | |
| lk = xmlListFront(writer->nsstack); | |
| np = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk); | |
| if (np != 0) { | |
| namespaceURI = xmlStrdup(np->uri); | |
| prefix = xmlStrdup(np->prefix); | |
| } | |
| xmlListPopFront(writer->nsstack); | |
| if (np != 0) { | |
| count = xmlTextWriterWriteAttribute(writer, prefix, namespaceURI); | |
| xmlFree(namespaceURI); | |
| xmlFree(prefix); | |
| if (count < 0) { | |
| xmlListDelete(writer->nsstack); | |
| writer->nsstack = NULL; | |
| return -1; | |
| } | |
| sum += count; | |
| } | |
| } | |
| return sum; | |
| } | |
| /** | |
| * xmlFreeTextWriterNsStackEntry: | |
| * @lk: the xmlLinkPtr | |
| * | |
| * Free callback for the xmlList. | |
| */ | |
| static void | |
| xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk) | |
| { | |
| xmlTextWriterNsStackEntry *p; | |
| p = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk); | |
| if (p == 0) | |
| return; | |
| if (p->prefix != 0) | |
| xmlFree(p->prefix); | |
| if (p->uri != 0) | |
| xmlFree(p->uri); | |
| xmlFree(p); | |
| } | |
| /** | |
| * xmlCmpTextWriterNsStackEntry: | |
| * @data0: the first data | |
| * @data1: the second data | |
| * | |
| * Compare callback for the xmlList. | |
| * | |
| * Returns -1, 0, 1 | |
| */ | |
| static int | |
| xmlCmpTextWriterNsStackEntry(const void *data0, const void *data1) | |
| { | |
| xmlTextWriterNsStackEntry *p0; | |
| xmlTextWriterNsStackEntry *p1; | |
| int rc; | |
| if (data0 == data1) | |
| return 0; | |
| if (data0 == 0) | |
| return -1; | |
| if (data1 == 0) | |
| return 1; | |
| p0 = (xmlTextWriterNsStackEntry *) data0; | |
| p1 = (xmlTextWriterNsStackEntry *) data1; | |
| rc = xmlStrcmp(p0->prefix, p1->prefix); | |
| if ((rc != 0) || (p0->elem != p1->elem)) | |
| rc = -1; | |
| return rc; | |
| } | |
| /** | |
| * xmlTextWriterWriteDocCallback: | |
| * @context: the xmlBufferPtr | |
| * @str: the data to write | |
| * @len: the length of the data | |
| * | |
| * Write callback for the xmlOutputBuffer with target xmlBuffer | |
| * | |
| * Returns -1, 0, 1 | |
| */ | |
| static int | |
| xmlTextWriterWriteDocCallback(void *context, const xmlChar * str, int len) | |
| { | |
| xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context; | |
| int rc; | |
| if ((rc = xmlParseChunk(ctxt, (const char *) str, len, 0)) != 0) { | |
| xmlWriterErrMsgInt(NULL, XML_ERR_INTERNAL_ERROR, | |
| "xmlTextWriterWriteDocCallback : XML error %d !\n", | |
| rc); | |
| return -1; | |
| } | |
| return len; | |
| } | |
| /** | |
| * xmlTextWriterCloseDocCallback: | |
| * @context: the xmlBufferPtr | |
| * | |
| * Close callback for the xmlOutputBuffer with target xmlBuffer | |
| * | |
| * Returns -1, 0, 1 | |
| */ | |
| static int | |
| xmlTextWriterCloseDocCallback(void *context) | |
| { | |
| xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context; | |
| int rc; | |
| if ((rc = xmlParseChunk(ctxt, NULL, 0, 1)) != 0) { | |
| xmlWriterErrMsgInt(NULL, XML_ERR_INTERNAL_ERROR, | |
| "xmlTextWriterWriteDocCallback : XML error %d !\n", | |
| rc); | |
| return -1; | |
| } | |
| return 0; | |
| } | |
| /** | |
| * xmlTextWriterVSprintf: | |
| * @format: see printf | |
| * @argptr: pointer to the first member of the variable argument list. | |
| * | |
| * Utility function for formatted output | |
| * | |
| * Returns a new xmlChar buffer with the data or NULL on error. This buffer must be freed. | |
| */ | |
| static xmlChar * | |
| xmlTextWriterVSprintf(const char *format, va_list argptr) | |
| { | |
| int size; | |
| int count; | |
| xmlChar *buf; | |
| va_list locarg; | |
| size = BUFSIZ; | |
| buf = (xmlChar *) xmlMalloc(size); | |
| if (buf == NULL) { | |
| xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY, | |
| "xmlTextWriterVSprintf : out of memory!\n"); | |
| return NULL; | |
| } | |
| VA_COPY(locarg, argptr); | |
| while (((count = vsnprintf((char *) buf, size, format, locarg)) < 0) | |
| || (count == size - 1) || (count == size) || (count > size)) { | |
| va_end(locarg); | |
| xmlFree(buf); | |
| size += BUFSIZ; | |
| buf = (xmlChar *) xmlMalloc(size); | |
| if (buf == NULL) { | |
| xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY, | |
| "xmlTextWriterVSprintf : out of memory!\n"); | |
| return NULL; | |
| } | |
| VA_COPY(locarg, argptr); | |
| } | |
| va_end(locarg); | |
| return buf; | |
| } | |
| /** | |
| * xmlTextWriterStartDocumentCallback: | |
| * @ctx: the user data (XML parser context) | |
| * | |
| * called at the start of document processing. | |
| */ | |
| static void | |
| xmlTextWriterStartDocumentCallback(void *ctx) | |
| { | |
| xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; | |
| xmlDocPtr doc; | |
| if (ctxt->html) { | |
| #ifdef LIBXML_HTML_ENABLED | |
| if (ctxt->myDoc == NULL) | |
| ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL); | |
| if (ctxt->myDoc == NULL) { | |
| if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) | |
| ctxt->sax->error(ctxt->userData, | |
| "SAX.startDocument(): out of memory\n"); | |
| ctxt->errNo = XML_ERR_NO_MEMORY; | |
| ctxt->instate = XML_PARSER_EOF; | |
| ctxt->disableSAX = 1; | |
| return; | |
| } | |
| #else | |
| xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR, | |
| "libxml2 built without HTML support\n"); | |
| ctxt->errNo = XML_ERR_INTERNAL_ERROR; | |
| ctxt->instate = XML_PARSER_EOF; | |
| ctxt->disableSAX = 1; | |
| return; | |
| #endif | |
| } else { | |
| doc = ctxt->myDoc; | |
| if (doc == NULL) | |
| doc = ctxt->myDoc = xmlNewDoc(ctxt->version); | |
| if (doc != NULL) { | |
| if (doc->children == NULL) { | |
| if (ctxt->encoding != NULL) | |
| doc->encoding = xmlStrdup(ctxt->encoding); | |
| else | |
| doc->encoding = NULL; | |
| doc->standalone = ctxt->standalone; | |
| } | |
| } else { | |
| if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) | |
| ctxt->sax->error(ctxt->userData, | |
| "SAX.startDocument(): out of memory\n"); | |
| ctxt->errNo = XML_ERR_NO_MEMORY; | |
| ctxt->instate = XML_PARSER_EOF; | |
| ctxt->disableSAX = 1; | |
| return; | |
| } | |
| } | |
| if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) && | |
| (ctxt->input != NULL) && (ctxt->input->filename != NULL)) { | |
| ctxt->myDoc->URL = | |
| xmlCanonicPath((const xmlChar *) ctxt->input->filename); | |
| if (ctxt->myDoc->URL == NULL) | |
| ctxt->myDoc->URL = | |
| xmlStrdup((const xmlChar *) ctxt->input->filename); | |
| } | |
| } | |
| /** | |
| * xmlTextWriterSetIndent: | |
| * @writer: the xmlTextWriterPtr | |
| * @indent: do indentation? | |
| * | |
| * Set indentation output. indent = 0 do not indentation. indent > 0 do indentation. | |
| * | |
| * Returns -1 on error or 0 otherwise. | |
| */ | |
| int | |
| xmlTextWriterSetIndent(xmlTextWriterPtr writer, int indent) | |
| { | |
| if ((writer == NULL) || (indent < 0)) | |
| return -1; | |
| writer->indent = indent; | |
| writer->doindent = 1; | |
| return 0; | |
| } | |
| /** | |
| * xmlTextWriterSetIndentString: | |
| * @writer: the xmlTextWriterPtr | |
| * @str: the xmlChar string | |
| * | |
| * Set string indentation. | |
| * | |
| * Returns -1 on error or 0 otherwise. | |
| */ | |
| int | |
| xmlTextWriterSetIndentString(xmlTextWriterPtr writer, const xmlChar * str) | |
| { | |
| if ((writer == NULL) || (!str)) | |
| return -1; | |
| if (writer->ichar != NULL) | |
| xmlFree(writer->ichar); | |
| writer->ichar = xmlStrdup(str); | |
| if (!writer->ichar) | |
| return -1; | |
| else | |
| return 0; | |
| } | |
| /** | |
| * xmlTextWriterSetQuoteChar: | |
| * @writer: the xmlTextWriterPtr | |
| * @quotechar: the quote character | |
| * | |
| * Set the character used for quoting attributes. | |
| * | |
| * Returns -1 on error or 0 otherwise. | |
| */ | |
| int | |
| xmlTextWriterSetQuoteChar(xmlTextWriterPtr writer, xmlChar quotechar) | |
| { | |
| if ((writer == NULL) || ((quotechar != '\'') && (quotechar != '"'))) | |
| return -1; | |
| writer->qchar = quotechar; | |
| return 0; | |
| } | |
| /** | |
| * xmlTextWriterWriteIndent: | |
| * @writer: the xmlTextWriterPtr | |
| * | |
| * Write indent string. | |
| * | |
| * Returns -1 on error or the number of strings written. | |
| */ | |
| static int | |
| xmlTextWriterWriteIndent(xmlTextWriterPtr writer) | |
| { | |
| int lksize; | |
| int i; | |
| int ret; | |
| lksize = xmlListSize(writer->nodes); | |
| if (lksize < 1) | |
| return (-1); /* list is empty */ | |
| for (i = 0; i < (lksize - 1); i++) { | |
| ret = xmlOutputBufferWriteString(writer->out, | |
| (const char *) writer->ichar); | |
| if (ret == -1) | |
| return (-1); | |
| } | |
| return (lksize - 1); | |
| } | |
| /** | |
| * xmlTextWriterHandleStateDependencies: | |
| * @writer: the xmlTextWriterPtr | |
| * @p: the xmlTextWriterStackEntry | |
| * | |
| * Write state dependent strings. | |
| * | |
| * Returns -1 on error or the number of characters written. | |
| */ | |
| static int | |
| xmlTextWriterHandleStateDependencies(xmlTextWriterPtr writer, | |
| xmlTextWriterStackEntry * p) | |
| { | |
| int count; | |
| int sum; | |
| char extra[3]; | |
| if (writer == NULL) | |
| return -1; | |
| if (p == NULL) | |
| return 0; | |
| sum = 0; | |
| extra[0] = extra[1] = extra[2] = '\0'; | |
| if (p != 0) { | |
| sum = 0; | |
| switch (p->state) { | |
| case XML_TEXTWRITER_NAME: | |
| /* Output namespace declarations */ | |
| count = xmlTextWriterOutputNSDecl(writer); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| extra[0] = '>'; | |
| p->state = XML_TEXTWRITER_TEXT; | |
| break; | |
| case XML_TEXTWRITER_PI: | |
| extra[0] = ' '; | |
| p->state = XML_TEXTWRITER_PI_TEXT; | |
| break; | |
| case XML_TEXTWRITER_DTD: | |
| extra[0] = ' '; | |
| extra[1] = '['; | |
| p->state = XML_TEXTWRITER_DTD_TEXT; | |
| break; | |
| case XML_TEXTWRITER_DTD_ELEM: | |
| extra[0] = ' '; | |
| p->state = XML_TEXTWRITER_DTD_ELEM_TEXT; | |
| break; | |
| case XML_TEXTWRITER_DTD_ATTL: | |
| extra[0] = ' '; | |
| p->state = XML_TEXTWRITER_DTD_ATTL_TEXT; | |
| break; | |
| case XML_TEXTWRITER_DTD_ENTY: | |
| case XML_TEXTWRITER_DTD_PENT: | |
| extra[0] = ' '; | |
| extra[1] = writer->qchar; | |
| p->state = XML_TEXTWRITER_DTD_ENTY_TEXT; | |
| break; | |
| default: | |
| break; | |
| } | |
| } | |
| if (*extra != '\0') { | |
| count = xmlOutputBufferWriteString(writer->out, extra); | |
| if (count < 0) | |
| return -1; | |
| sum += count; | |
| } | |
| return sum; | |
| } | |
| #define bottom_xmlwriter | |
| #include "elfgcchack.h" | |
| #endif |