Nikolay Sivov : msxml3: Basic support for startDocument().

Alexandre Julliard julliard at winehq.org
Mon May 2 14:16:15 CDT 2011


Module: wine
Branch: master
Commit: c8f9c4581cf3bad1150e0459c4eea6a8af40257e
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=c8f9c4581cf3bad1150e0459c4eea6a8af40257e

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Sun May  1 20:05:31 2011 +0400

msxml3: Basic support for startDocument().

---

 dlls/msxml3/mxwriter.c        |   80 ++++++++++++++++++++++++++++++++++---
 dlls/msxml3/tests/saxreader.c |   87 ++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 159 insertions(+), 8 deletions(-)

diff --git a/dlls/msxml3/mxwriter.c b/dlls/msxml3/mxwriter.c
index fe7fba7..ec82611 100644
--- a/dlls/msxml3/mxwriter.c
+++ b/dlls/msxml3/mxwriter.c
@@ -38,6 +38,10 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
 
+#ifdef HAVE_LIBXML2
+
+static const char crlfA[] = "\r\n";
+
 typedef struct _mxwriter
 {
     IMXWriter IMXWriter_iface;
@@ -47,8 +51,11 @@ typedef struct _mxwriter
 
     VARIANT_BOOL standalone;
     BSTR encoding;
+    BSTR version;
 
     IStream *dest;
+
+    xmlOutputBufferPtr buffer;
 } mxwriter;
 
 static inline mxwriter *impl_from_IMXWriter(IMXWriter *iface)
@@ -109,6 +116,9 @@ static ULONG WINAPI mxwriter_Release(IMXWriter *iface)
     {
         if (This->dest) IStream_Release(This->dest);
         SysFreeString(This->encoding);
+        SysFreeString(This->version);
+
+        xmlOutputBufferClose(This->buffer);
         heap_free(This);
     }
 
@@ -228,7 +238,19 @@ static HRESULT WINAPI mxwriter_put_output(IMXWriter *iface, VARIANT dest)
 static HRESULT WINAPI mxwriter_get_output(IMXWriter *iface, VARIANT *dest)
 {
     mxwriter *This = impl_from_IMXWriter( iface );
-    FIXME("(%p)->(%p)\n", This, dest);
+
+    TRACE("(%p)->(%p)\n", This, dest);
+
+    if (!This->dest)
+    {
+        V_VT(dest)   = VT_BSTR;
+        V_BSTR(dest) = bstr_from_xmlChar(This->buffer->buffer->content);
+
+        return S_OK;
+    }
+    else
+        FIXME("not implemented when stream is set up\n");
+
     return E_NOTIMPL;
 }
 
@@ -340,8 +362,12 @@ static HRESULT WINAPI mxwriter_put_version(IMXWriter *iface, BSTR version)
 static HRESULT WINAPI mxwriter_get_version(IMXWriter *iface, BSTR *version)
 {
     mxwriter *This = impl_from_IMXWriter( iface );
-    FIXME("(%p)->(%p)\n", This, version);
-    return E_NOTIMPL;
+
+    TRACE("(%p)->(%p)\n", This, version);
+
+    if (!version) return E_POINTER;
+
+    return return_bstr(This->version, version);
 }
 
 static HRESULT WINAPI mxwriter_put_disableOutputEscaping(IMXWriter *iface, VARIANT_BOOL value)
@@ -427,8 +453,34 @@ static HRESULT WINAPI mxwriter_saxcontent_putDocumentLocator(
 static HRESULT WINAPI mxwriter_saxcontent_startDocument(ISAXContentHandler *iface)
 {
     mxwriter *This = impl_from_ISAXContentHandler( iface );
-    FIXME("(%p)\n", This);
-    return E_NOTIMPL;
+    xmlChar *s;
+
+    TRACE("(%p)\n", This);
+
+    /* version */
+    xmlOutputBufferWriteString(This->buffer, "<?xml version=\"");
+    s = xmlchar_from_wchar(This->version);
+    xmlOutputBufferWriteString(This->buffer, (char*)s);
+    heap_free(s);
+    xmlOutputBufferWriteString(This->buffer, "\"");
+
+    /* encoding */
+    xmlOutputBufferWriteString(This->buffer, " encoding=\"");
+    s = xmlchar_from_wchar(This->encoding);
+    xmlOutputBufferWriteString(This->buffer, (char*)s);
+    heap_free(s);
+    xmlOutputBufferWriteString(This->buffer, "\"");
+
+    /* standalone */
+    xmlOutputBufferWriteString(This->buffer, " standalone=\"");
+    if (This->standalone == VARIANT_TRUE)
+        xmlOutputBufferWriteString(This->buffer, "yes\"?>");
+    else
+        xmlOutputBufferWriteString(This->buffer, "no\"?>");
+
+    xmlOutputBufferWriteString(This->buffer, crlfA);
+
+    return S_OK;
 }
 
 static HRESULT WINAPI mxwriter_saxcontent_endDocument(ISAXContentHandler *iface)
@@ -554,6 +606,7 @@ static const struct ISAXContentHandlerVtbl mxwriter_saxcontent_vtbl =
 HRESULT MXWriter_create(IUnknown *pUnkOuter, void **ppObj)
 {
     static const WCHAR utf16W[] = {'U','T','F','-','1','6',0};
+    static const WCHAR version10W[] = {'1','.','0',0};
     mxwriter *This;
 
     TRACE("(%p,%p)\n", pUnkOuter, ppObj);
@@ -569,13 +622,28 @@ HRESULT MXWriter_create(IUnknown *pUnkOuter, void **ppObj)
     This->ref = 1;
 
     This->standalone = VARIANT_FALSE;
-    This->encoding = SysAllocString(utf16W);
+    This->encoding   = SysAllocString(utf16W);
+    This->version    = SysAllocString(version10W);
 
     This->dest = NULL;
 
+    /* set up a buffer, default encoding is UTF-16 */
+    This->buffer = xmlAllocOutputBuffer(xmlFindCharEncodingHandler("UTF-16"));
+
     *ppObj = &This->IMXWriter_iface;
 
     TRACE("returning iface %p\n", *ppObj);
 
     return S_OK;
 }
+
+#else
+
+HRESULT MXWriter_create(IUnknown *pUnkOuter, void **obj)
+{
+    MESSAGE("This program tried to use a MXXMLWriter object, but\n"
+            "libxml2 support was not present at compile time.\n");
+    return E_NOTIMPL;
+}
+
+#endif /* HAVE_LIBXML2 */
diff --git a/dlls/msxml3/tests/saxreader.c b/dlls/msxml3/tests/saxreader.c
index 34fa902..6ae7e3d 100644
--- a/dlls/msxml3/tests/saxreader.c
+++ b/dlls/msxml3/tests/saxreader.c
@@ -22,6 +22,8 @@
 #define CONST_VTABLE
 
 #include <stdio.h>
+#include <assert.h>
+
 #include "windows.h"
 #include "ole2.h"
 #include "msxml2.h"
@@ -37,6 +39,32 @@ static void _expect_ref(IUnknown* obj, ULONG ref, int line)
     ok_(__FILE__,line)(rc-1 == ref, "expected refcount %d, got %d\n", ref, rc-1);
 }
 
+static BSTR alloc_str_from_narrow(const char *str)
+{
+    int len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
+    BSTR ret = SysAllocStringLen(NULL, len - 1);  /* NUL character added automatically */
+    MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
+    return ret;
+}
+
+static BSTR alloced_bstrs[256];
+static int alloced_bstrs_count;
+
+static BSTR _bstr_(const char *str)
+{
+    assert(alloced_bstrs_count < sizeof(alloced_bstrs)/sizeof(alloced_bstrs[0]));
+    alloced_bstrs[alloced_bstrs_count] = alloc_str_from_narrow(str);
+    return alloced_bstrs[alloced_bstrs_count++];
+}
+
+static void free_bstrs(void)
+{
+    int i;
+    for (i = 0; i < alloced_bstrs_count; i++)
+        SysFreeString(alloced_bstrs[i]);
+    alloced_bstrs_count = 0;
+}
+
 typedef enum _CH {
     CH_ENDTEST,
     CH_PUTDOCUMENTLOCATOR,
@@ -754,7 +782,15 @@ static void test_mxwriter_properties(void)
     ok(hr == E_INVALIDARG, "got %08x\n", hr);
     SysFreeString(str);
 
+    hr = IMXWriter_get_version(writer, NULL);
+    ok(hr == E_POINTER, "got %08x\n", hr);
+    /* default version is 'surprisingly' 1.0 */
+    hr = IMXWriter_get_version(writer, &str);
+    ok(hr == S_OK, "got %08x\n", hr);
+    ok(!lstrcmpW(str, _bstr_("1.0")), "got %s\n", wine_dbgstr_w(str));
+
     IMXWriter_Release(writer);
+    free_bstrs();
 }
 
 static void test_mxwriter_flush(void)
@@ -814,7 +850,7 @@ todo_wine {
     ok(hr == S_OK, "got %08x\n", hr);
 
     hr = ISAXContentHandler_startDocument(content);
-    todo_wine ok(hr == S_OK, "got %08x\n", hr);
+    ok(hr == S_OK, "got %08x\n", hr);
 
     pos.QuadPart = 0;
     hr = IStream_Seek(stream, pos, STREAM_SEEK_CUR, &pos2);
@@ -823,7 +859,7 @@ todo_wine {
 
     /* already started */
     hr = ISAXContentHandler_startDocument(content);
-    todo_wine ok(hr == S_OK, "got %08x\n", hr);
+    ok(hr == S_OK, "got %08x\n", hr);
 
     hr = ISAXContentHandler_endDocument(content);
     todo_wine ok(hr == S_OK, "got %08x\n", hr);
@@ -839,6 +875,52 @@ todo_wine {
     IMXWriter_Release(writer);
 }
 
+static void test_mxwriter_startenddocument(void)
+{
+    ISAXContentHandler *content;
+    IMXWriter *writer;
+    VARIANT dest;
+    HRESULT hr;
+
+    hr = CoCreateInstance(&CLSID_MXXMLWriter, NULL, CLSCTX_INPROC_SERVER,
+            &IID_IMXWriter, (void**)&writer);
+    ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
+
+    hr = IMXWriter_QueryInterface(writer, &IID_ISAXContentHandler, (void**)&content);
+    ok(hr == S_OK, "got %08x\n", hr);
+
+    hr = ISAXContentHandler_startDocument(content);
+    ok(hr == S_OK, "got %08x\n", hr);
+
+    hr = ISAXContentHandler_endDocument(content);
+    todo_wine ok(hr == S_OK, "got %08x\n", hr);
+
+    V_VT(&dest) = VT_EMPTY;
+    hr = IMXWriter_get_output(writer, &dest);
+    ok(hr == S_OK, "got %08x\n", hr);
+    ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
+    ok(!lstrcmpW(_bstr_("<?xml version=\"1.0\" encoding=\"UTF-16\" standalone=\"no\"?>\r\n"), V_BSTR(&dest)),
+        "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
+    VariantClear(&dest);
+
+    /* now try another startDocument */
+    hr = ISAXContentHandler_startDocument(content);
+    ok(hr == S_OK, "got %08x\n", hr);
+    /* and get duplcated prolog */
+    V_VT(&dest) = VT_EMPTY;
+    hr = IMXWriter_get_output(writer, &dest);
+    ok(hr == S_OK, "got %08x\n", hr);
+    ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest));
+    ok(!lstrcmpW(_bstr_("<?xml version=\"1.0\" encoding=\"UTF-16\" standalone=\"no\"?>\r\n"
+                        "<?xml version=\"1.0\" encoding=\"UTF-16\" standalone=\"no\"?>\r\n"), V_BSTR(&dest)),
+        "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest)));
+    VariantClear(&dest);
+
+    ISAXContentHandler_Release(content);
+    IMXWriter_Release(writer);
+    free_bstrs();
+}
+
 START_TEST(saxreader)
 {
     ISAXXMLReader *reader;
@@ -869,6 +951,7 @@ START_TEST(saxreader)
         IMXWriter_Release(writer);
 
         test_mxwriter_contenthandler();
+        test_mxwriter_startenddocument();
         test_mxwriter_properties();
         test_mxwriter_flush();
     }




More information about the wine-cvs mailing list