#define IN_LIBXML
#include "libxml.h"
-
#include <string.h>
#include <libxml/xmlmemory.h>
#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 (i.e. it may need
- * something involving a memcpy) but (hopefully) will be
- * sufficient for libxml2.
+ * esoteric implementations of va_list but (hopefully) will
+ * be sufficient for libxml2.
*/
#ifndef VA_COPY
#ifdef HAVE_VA_COPY
#ifdef HAVE___VA_COPY
#define VA_COPY(dest,src) __va_copy(dest, src)
#else
- #define VA_COPY(dest,src) (dest) = (src)
+ #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
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);
if (ctxt != NULL) {
__xmlRaiseError(NULL, NULL, NULL, ctxt->ctxt,
NULL, XML_FROM_WRITER, error, XML_ERR_FATAL,
- NULL, 0, NULL, NULL, NULL, 0, 0, msg);
+ 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, msg);
+ XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, 0, 0, "%s", msg);
}
}
out = xmlOutputBufferCreateFilename(uri, NULL, compression);
if (out == NULL) {
- xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
- "xmlNewTextWriterFilename : out of memory!\n");
+ xmlWriterErrMsg(NULL, XML_IO_EIO,
+ "xmlNewTextWriterFilename : cannot open uri\n");
return NULL;
}
ctxt = xmlCreatePushParserCtxt(&saxHandler, NULL, NULL, 0, NULL);
if (ctxt == NULL) {
xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
- "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\n");
+ "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\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");
+ "xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n");
return NULL;
}
writer->out->encoder = encoder;
if (encoder != NULL) {
- writer->out->conv = xmlBufferCreateSize(4000);
- xmlCharEncOutFunc(encoder, writer->out->conv, 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
* xmlTextWriterEndDocument:
* @writer: the xmlTextWriterPtr
*
- * End an xml document. All open elements are closed
+ * End an xml document. All open elements are closed, and
+ * the content is flushed to the output.
*
- * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
+ * Returns the bytes written or -1 in case of error
*/
int
xmlTextWriterEndDocument(xmlTextWriterPtr writer)
return -1;
sum += count;
}
+
+ sum += xmlTextWriterFlush(writer);
+
return sum;
}
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;
}
buf = xmlTextWriterVSprintf(format, argptr);
- if (buf == 0)
- return 0;
+ if (buf == NULL)
+ return -1;
rc = xmlTextWriterWriteComment(writer, buf);
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 (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);
}
- count = xmlTextWriterWriteAttribute(writer, buf, namespaceURI);
- xmlFree(buf);
- if (count < 0)
+ 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;
- sum += count;
+ }
+ p->elem = xmlListFront(writer->nodes);
+
+ xmlListPushFront(writer->nsstack, p);
}
return sum;
return -1;
lk = xmlListFront(writer->nodes);
- if (lk == 0)
+ if (lk == 0) {
+ xmlListDelete(writer->nsstack);
+ writer->nsstack = NULL;
return -1;
+ }
p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
- if (p == 0)
+ 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)
+ 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, "/>");
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;
return -1;
}
+ if (writer->indent) {
+ count = xmlOutputBufferWriteString(writer->out, "\n");
+ sum += count;
+ }
+
xmlListPopFront(writer->nodes);
return sum;
}
return -1;
buf = xmlTextWriterVSprintf(format, argptr);
- if (buf == 0)
- return 0;
+ if (buf == NULL)
+ return -1;
rc = xmlTextWriterWriteRaw(writer, buf);
return -1;
buf = xmlTextWriterVSprintf(format, argptr);
- if (buf == 0)
- return 0;
+ if (buf == NULL)
+ return -1;
rc = xmlTextWriterWriteString(writer, buf);
break;
case XML_TEXTWRITER_ATTRIBUTE:
buf = NULL;
- xmlAttrSerializeTxtContent(writer->out->buffer, writer->doc,
- NULL, content);
+ xmlBufAttrSerializeTxtContent(writer->out->buffer,
+ writer->doc, NULL, content);
break;
default:
break;
if (buf != NULL) {
count = xmlTextWriterWriteRaw(writer, buf);
- if (count < 0)
- return -1;
- sum += count;
if (buf != content) /* buf was allocated by us, so free it */
xmlFree(buf);
+
+ if (count < 0)
+ return -1;
+ sum += count;
}
return sum;
* Write hqx encoded data to an xmlOutputBuffer.
* ::todo
*
- * Returns the bytes written (may be 0 because of buffering)
+ * Returns the bytes written (may be 0 because of buffering)
* or -1 in case of error
*/
static int
{
int count;
int sum;
- static char hex[16] =
- {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
+ 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)) {
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);
return -1;
sum += count;
- if (namespaceURI != 0) {
- buf = xmlStrdup(BAD_CAST "xmlns");
- if (prefix != 0) {
- buf = xmlStrcat(buf, BAD_CAST ":");
- buf = xmlStrcat(buf, prefix);
- }
-
- 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);
- }
-
return sum;
}
int sum;
xmlLinkPtr lk;
xmlTextWriterStackEntry *p;
- xmlTextWriterNsStackEntry *np;
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;
}
count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
if (count < 0) {
- xmlListDelete(writer->nsstack);
- writer->nsstack = NULL;
return -1;
}
sum += count;
-
- 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;
- }
- }
break;
-
default:
- xmlListClear(writer->nsstack);
return -1;
}
return -1;
buf = xmlTextWriterVSprintf(format, argptr);
- if (buf == 0)
- return 0;
+ if (buf == NULL)
+ return -1;
rc = xmlTextWriterWriteAttribute(writer, name, buf);
return -1;
buf = xmlTextWriterVSprintf(format, argptr);
- if (buf == 0)
- return 0;
+ if (buf == NULL)
+ return -1;
rc = xmlTextWriterWriteAttributeNS(writer, prefix, name, namespaceURI,
buf);
{
int count;
int sum;
- xmlChar *buf;
if ((writer == NULL) || (name == NULL) || (*name == '\0'))
return -1;
- buf = NULL;
- if (prefix != NULL) {
- buf = xmlStrdup(prefix);
- buf = xmlStrcat(buf, BAD_CAST ":");
- }
- buf = xmlStrcat(buf, name);
-
sum = 0;
- count = xmlTextWriterWriteAttribute(writer, buf, content);
- xmlFree(buf);
+ 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;
- if (namespaceURI != NULL) {
- buf = NULL;
- buf = xmlStrdup(BAD_CAST "xmlns");
- if (prefix != NULL) {
- buf = xmlStrcat(buf, BAD_CAST ":");
- buf = xmlStrcat(buf, prefix);
- }
- count = xmlTextWriterWriteAttribute(writer, buf, namespaceURI);
- xmlFree(buf);
- if (count < 0)
- return -1;
- sum += count;
- }
return sum;
}
return -1;
buf = xmlTextWriterVSprintf(format, argptr);
- if (buf == 0)
- return 0;
+ if (buf == NULL)
+ return -1;
rc = xmlTextWriterWriteElement(writer, name, buf);
if (count == -1)
return -1;
sum += count;
- count = xmlTextWriterWriteString(writer, content);
- 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;
return -1;
buf = xmlTextWriterVSprintf(format, argptr);
- if (buf == 0)
- return 0;
+ if (buf == NULL)
+ return -1;
rc = xmlTextWriterWriteElementNS(writer, prefix, name, namespaceURI,
buf);
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;
if (writer->indent) {
count = xmlOutputBufferWriteString(writer->out, "\n");
- if (count < 0)
- return -1;
+ if (count < 0)
+ return -1;
sum += count;
}
return -1;
buf = xmlTextWriterVSprintf(format, argptr);
- if (buf == 0)
- return 0;
+ if (buf == NULL)
+ return -1;
rc = xmlTextWriterWritePI(writer, target, buf);
if (p != 0) {
switch (p->state) {
case XML_TEXTWRITER_NONE:
+ case XML_TEXTWRITER_TEXT:
case XML_TEXTWRITER_PI:
case XML_TEXTWRITER_PI_TEXT:
break;
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;
return -1;
buf = xmlTextWriterVSprintf(format, argptr);
- if (buf == 0)
- return 0;
+ if (buf == NULL)
+ return -1;
rc = xmlTextWriterWriteCDATA(writer, buf);
return -1;
buf = xmlTextWriterVSprintf(format, argptr);
- if (buf == 0)
- return 0;
+ if (buf == NULL)
+ return -1;
rc = xmlTextWriterWriteDTD(writer, name, pubid, sysid, buf);
return -1;
buf = xmlTextWriterVSprintf(format, argptr);
- if (buf == 0)
- return 0;
+ if (buf == NULL)
+ return -1;
rc = xmlTextWriterWriteDTDElement(writer, name, buf);
return -1;
buf = xmlTextWriterVSprintf(format, argptr);
- if (buf == 0)
- return 0;
+ if (buf == NULL)
+ return -1;
rc = xmlTextWriterWriteDTDAttlist(writer, name, buf);
return -1;
buf = xmlTextWriterVSprintf(format, argptr);
- if (buf == 0)
- return 0;
+ if (buf == NULL)
+ return -1;
rc = xmlTextWriterWriteDTDInternalEntity(writer, pe, name, buf);
*/
/**
+ * 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
*
rc = xmlStrcmp(p0->prefix, p1->prefix);
- if (rc == 0)
- rc = p0->elem == p1->elem;
+ if ((rc != 0) || (p0->elem != p1->elem))
+ rc = -1;
return rc;
}
}
/**
+ * 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
*
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;