Re: [xml] PATCH: implement xmlSaveToBuffer()
- From: Geert Jansen <geert boskant nl>
- To: veillard redhat com
- Cc: xml gnome org
- Subject: Re: [xml] PATCH: implement xmlSaveToBuffer()
- Date: Mon, 07 Nov 2005 00:22:03 +0100
Daniel,
The xmlBuffer should be used when you don't dump to an I/O channel.
Then the user just want a memory string and an xmlBuffer makes way more sense
than an xmlOutputBuffer in that case.
See the attached patch. I took your original suggestion and used the
original prototype for xmlSaveToBuffer(). I now create an
xmlOutputBuffer from the xmlBuffer. This is done by a new function in
xmlIO.c: xmlOutputBufferCreateBuffer(). It uses xmlAllocOutputBuffer()
to create a new output buffer and then replaces either .buffer or .conv
by the user supplied buffer. This requires me to free one buffer that
was just allocated. This isn't ideal but I thought this would be better
than either duplicating xmlAllocOutputBuffer() or changing it signature
to accept a flag indicating that it should not allocate buffers.
In order to ensure that xmlFreeSaveCtxt() does not free the user
supplied buffer, I had to extend xmlSaveCtxt with two members:
"user_buffer" and "user_conv" to indicate that buffer or conv
respectively are allocated by the user and should not be freed. I didn't
feel very confident about extending this structure but I could not come
up with something else. Did you have something else in mind?
Regards,
Geert
diff -ur libxml2-2.6.22.orig/include/libxml/xmlIO.h libxml2-2.6.22/include/libxml/xmlIO.h
--- libxml2-2.6.22.orig/include/libxml/xmlIO.h 2005-07-27 22:59:37.000000000 +0200
+++ libxml2-2.6.22/include/libxml/xmlIO.h 2005-11-06 22:51:07.000000000 +0100
@@ -149,6 +149,8 @@
xmlBufferPtr conv; /* if encoder != NULL buffer for output */
int written; /* total number of byte written */
int error;
+ int user_buffer; /* User allocated buffer */
+ int user_conv; /* User allocated conv */
};
#endif /* LIBXML_OUTPUT_ENABLED */
@@ -232,6 +234,10 @@
xmlCharEncodingHandlerPtr encoder);
XMLPUBFUN xmlOutputBufferPtr XMLCALL
+ xmlOutputBufferCreateBuffer (xmlBufferPtr buffer,
+ xmlCharEncodingHandlerPtr encoder);
+
+XMLPUBFUN xmlOutputBufferPtr XMLCALL
xmlOutputBufferCreateFd (int fd,
xmlCharEncodingHandlerPtr encoder);
diff -ur libxml2-2.6.22.orig/include/libxml/xmlsave.h libxml2-2.6.22/include/libxml/xmlsave.h
--- libxml2-2.6.22.orig/include/libxml/xmlsave.h 2005-09-12 17:34:25.000000000 +0200
+++ libxml2-2.6.22/include/libxml/xmlsave.h 2005-11-06 22:49:37.000000000 +0100
@@ -45,14 +45,12 @@
xmlSaveToFilename (const char *filename,
const char *encoding,
int options);
-/******
- Not yet implemented.
XMLPUBFUN xmlSaveCtxtPtr XMLCALL
xmlSaveToBuffer (xmlBufferPtr buffer,
const char *encoding,
int options);
- ******/
+
XMLPUBFUN xmlSaveCtxtPtr XMLCALL
xmlSaveToIO (xmlOutputWriteCallback iowrite,
xmlOutputCloseCallback ioclose,
diff -ur libxml2-2.6.22.orig/xmlIO.c libxml2-2.6.22/xmlIO.c
--- libxml2-2.6.22.orig/xmlIO.c 2005-08-05 15:53:39.000000000 +0200
+++ libxml2-2.6.22/xmlIO.c 2005-11-06 23:07:09.000000000 +0100
@@ -2071,6 +2071,8 @@
ret->closecallback = NULL;
ret->context = NULL;
ret->written = 0;
+ ret->user_buffer = 0;
+ ret->user_conv = 0;
return(ret);
}
@@ -2128,14 +2130,14 @@
err_rc = out->closecallback(out->context);
}
written = out->written;
- if (out->conv) {
+ if (out->conv && !out->user_conv) {
xmlBufferFree(out->conv);
out->conv = NULL;
}
if (out->encoder != NULL) {
xmlCharEncCloseFunc(out->encoder);
}
- if (out->buffer != NULL) {
+ if (out->buffer && !out->user_buffer) {
xmlBufferFree(out->buffer);
out->buffer = NULL;
}
@@ -2436,6 +2438,39 @@
return(ret);
}
+
+/**
+ * xmlOutputBufferCreateBuffer:
+ * @buffer: a xmlBufferPtr
+ * @encoder: the encoding converter or NULL
+ *
+ * Create a buffered output for the progressive saving to a xmlBuffer
+ *
+ * Returns the new parser output or NULL
+ */
+xmlOutputBufferPtr
+xmlOutputBufferCreateBuffer(xmlBufferPtr buffer,
+ xmlCharEncodingHandlerPtr encoder) {
+ xmlOutputBufferPtr ret;
+
+ if (buffer == NULL) return(NULL);
+
+ ret = xmlAllocOutputBuffer(encoder);
+ if (ret != NULL) {
+ if (ret->encoder == NULL) {
+ if (ret->buffer) xmlBufferFree(ret->buffer);
+ ret->buffer = buffer;
+ ret->user_buffer = 1;
+ } else {
+ if (ret->conv) xmlBufferFree(ret->conv);
+ ret->conv = buffer;
+ ret->user_conv = 1;
+ }
+ }
+
+ return(ret);
+}
+
#endif /* LIBXML_OUTPUT_ENABLED */
/**
diff -ur libxml2-2.6.22.orig/xmlsave.c libxml2-2.6.22/xmlsave.c
--- libxml2-2.6.22.orig/xmlsave.c 2005-09-12 17:35:07.000000000 +0200
+++ libxml2-2.6.22/xmlsave.c 2005-11-06 23:06:09.000000000 +0100
@@ -1473,13 +1473,36 @@
* with the encoding and the options given
*
* Returns a new serialization context or NULL in case of error.
+ */
+
xmlSaveCtxtPtr
xmlSaveToBuffer(xmlBufferPtr buffer, const char *encoding, int options)
{
- TODO
- return(NULL);
+ xmlSaveCtxtPtr ret;
+ xmlOutputBufferPtr out_buff;
+ xmlCharEncodingHandlerPtr handler;
+
+ ret = xmlNewSaveCtxt(encoding, options);
+ if (ret == NULL) return(NULL);
+
+ if (encoding != NULL) {
+ handler = xmlFindCharEncodingHandler(encoding);
+ if (handler == NULL) {
+ xmlFree(ret);
+ return(NULL);
+ }
+ } else
+ handler = NULL;
+ out_buff = xmlOutputBufferCreateBuffer(buffer, handler);
+ if (out_buff == NULL) {
+ xmlFree(ret);
+ if (handler) xmlCharEncCloseFunc(handler);
+ return(NULL);
+ }
+
+ ret->buf = out_buff;
+ return(ret);
}
- */
/**
* xmlSaveToIO:
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]