Use libxml2 functionality to skip top XML decalration node while writing to file

Nikolay Sivov bunglehead at gmail.com
Fri Feb 5 07:25:02 CST 2010


---
 dlls/msxml3/domdoc.c |   56 +++++++++++++++++++++++++++----------------------
 1 files changed, 31 insertions(+), 25 deletions(-)

diff --git a/dlls/msxml3/domdoc.c b/dlls/msxml3/domdoc.c
index 4914a7c..1422988 100644
--- a/dlls/msxml3/domdoc.c
+++ b/dlls/msxml3/domdoc.c
@@ -47,6 +47,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(msxml);
 
 #ifdef HAVE_LIBXML2
 
+#include <libxml/xmlsave.h> 
+
 static const WCHAR SZ_PROPERTY_SELECTION_LANGUAGE[] = {'S','e','l','e','c','t','i','o','n','L','a','n','g','u','a','g','e',0};
 static const WCHAR SZ_VALUE_XPATH[] = {'X','P','a','t','h',0};
 static const WCHAR SZ_VALUE_XSLPATTERN[] = {'X','S','L','P','a','t','t','e','r','n',0};
@@ -1651,6 +1653,24 @@ static HRESULT WINAPI domdoc_loadXML(
     return hr;
 }
 
+static int XMLCALL domdoc_save_writecallback(void *ctx, const char *buffer,
+                                             int len)
+{
+    DWORD written = -1;
+
+    if(!WriteFile(ctx, buffer, len, &written, NULL))
+    {
+        WARN("write error\n");
+        return -1;
+    }
+    else
+        return written;
+}
+
+static int XMLCALL domdoc_save_closecallback(void *ctx)
+{
+    return CloseHandle(ctx) ? 0 : -1;
+}
 
 static HRESULT WINAPI domdoc_save(
     IXMLDOMDocument2 *iface,
@@ -1658,10 +1678,8 @@ static HRESULT WINAPI domdoc_save(
 {
     domdoc *This = impl_from_IXMLDOMDocument2( iface );
     HANDLE handle;
-    xmlChar *mem, *p;
-    int size;
+    xmlSaveCtxtPtr ctx;
     HRESULT ret = S_OK;
-    DWORD written;
 
     TRACE("(%p)->(var(vt %d, %s))\n", This, V_VT(&destination),
           V_VT(&destination) == VT_BSTR ? debugstr_w(V_BSTR(&destination)) : NULL);
@@ -1707,31 +1725,19 @@ static HRESULT WINAPI domdoc_save(
         return S_FALSE;
     }
 
-    xmlDocDumpMemory(get_doc(This), &mem, &size);
-
-    /*
-     * libxml2 always adds XML declaration on top of the file and one for each processing instruction node in DOM tree.
-     * MSXML adds XML declaration only for processing instruction nodes.
-     * We skip the first XML declaration generated by libxml2 to get exactly what we need.
-     */
-    p = mem;
-    if(size > 2 && p[0] == '<' && p[1] == '?') {
-        while(p < mem+size && (p[0] != '?' || p[1] != '>'))
-            p++;
-        p += 2;
-        while(p < mem+size && isspace(*p))
-            p++;
-        size -= p-mem;
-    }
-
-    if(!WriteFile(handle, p, (DWORD)size, &written, NULL) || written != (DWORD)size)
+    /* disable top XML declaration */
+    ctx = xmlSaveToIO(domdoc_save_writecallback, domdoc_save_closecallback,
+                      handle, NULL, XML_SAVE_NO_DECL);
+    if (!ctx)
     {
-        WARN("write error\n");
-        ret = S_FALSE;
+        CloseHandle(handle);
+        return S_FALSE;
     }
 
-    xmlFree(mem);
-    CloseHandle(handle);
+    if (xmlSaveDoc(ctx, get_doc(This)) == -1) ret = S_FALSE;
+    /* will close file through close callback */
+    xmlSaveClose(ctx);
+
     return ret;
 }
 
-- 
1.5.6.5


--=-eKuIM3f53KHhjyEp5QhQ--




More information about the wine-patches mailing list