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