Commit c8f9c458 authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

msxml3: Basic support for startDocument().

parent e93125f3
...@@ -38,6 +38,10 @@ ...@@ -38,6 +38,10 @@
WINE_DEFAULT_DEBUG_CHANNEL(msxml); WINE_DEFAULT_DEBUG_CHANNEL(msxml);
#ifdef HAVE_LIBXML2
static const char crlfA[] = "\r\n";
typedef struct _mxwriter typedef struct _mxwriter
{ {
IMXWriter IMXWriter_iface; IMXWriter IMXWriter_iface;
...@@ -47,8 +51,11 @@ typedef struct _mxwriter ...@@ -47,8 +51,11 @@ typedef struct _mxwriter
VARIANT_BOOL standalone; VARIANT_BOOL standalone;
BSTR encoding; BSTR encoding;
BSTR version;
IStream *dest; IStream *dest;
xmlOutputBufferPtr buffer;
} mxwriter; } mxwriter;
static inline mxwriter *impl_from_IMXWriter(IMXWriter *iface) static inline mxwriter *impl_from_IMXWriter(IMXWriter *iface)
...@@ -109,6 +116,9 @@ static ULONG WINAPI mxwriter_Release(IMXWriter *iface) ...@@ -109,6 +116,9 @@ static ULONG WINAPI mxwriter_Release(IMXWriter *iface)
{ {
if (This->dest) IStream_Release(This->dest); if (This->dest) IStream_Release(This->dest);
SysFreeString(This->encoding); SysFreeString(This->encoding);
SysFreeString(This->version);
xmlOutputBufferClose(This->buffer);
heap_free(This); heap_free(This);
} }
...@@ -228,7 +238,19 @@ static HRESULT WINAPI mxwriter_put_output(IMXWriter *iface, VARIANT dest) ...@@ -228,7 +238,19 @@ static HRESULT WINAPI mxwriter_put_output(IMXWriter *iface, VARIANT dest)
static HRESULT WINAPI mxwriter_get_output(IMXWriter *iface, VARIANT *dest) static HRESULT WINAPI mxwriter_get_output(IMXWriter *iface, VARIANT *dest)
{ {
mxwriter *This = impl_from_IMXWriter( iface ); 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; return E_NOTIMPL;
} }
...@@ -340,8 +362,12 @@ static HRESULT WINAPI mxwriter_put_version(IMXWriter *iface, BSTR version) ...@@ -340,8 +362,12 @@ static HRESULT WINAPI mxwriter_put_version(IMXWriter *iface, BSTR version)
static HRESULT WINAPI mxwriter_get_version(IMXWriter *iface, BSTR *version) static HRESULT WINAPI mxwriter_get_version(IMXWriter *iface, BSTR *version)
{ {
mxwriter *This = impl_from_IMXWriter( iface ); 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) static HRESULT WINAPI mxwriter_put_disableOutputEscaping(IMXWriter *iface, VARIANT_BOOL value)
...@@ -427,8 +453,34 @@ static HRESULT WINAPI mxwriter_saxcontent_putDocumentLocator( ...@@ -427,8 +453,34 @@ static HRESULT WINAPI mxwriter_saxcontent_putDocumentLocator(
static HRESULT WINAPI mxwriter_saxcontent_startDocument(ISAXContentHandler *iface) static HRESULT WINAPI mxwriter_saxcontent_startDocument(ISAXContentHandler *iface)
{ {
mxwriter *This = impl_from_ISAXContentHandler( iface ); mxwriter *This = impl_from_ISAXContentHandler( iface );
FIXME("(%p)\n", This); xmlChar *s;
return E_NOTIMPL;
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) static HRESULT WINAPI mxwriter_saxcontent_endDocument(ISAXContentHandler *iface)
...@@ -554,6 +606,7 @@ static const struct ISAXContentHandlerVtbl mxwriter_saxcontent_vtbl = ...@@ -554,6 +606,7 @@ static const struct ISAXContentHandlerVtbl mxwriter_saxcontent_vtbl =
HRESULT MXWriter_create(IUnknown *pUnkOuter, void **ppObj) HRESULT MXWriter_create(IUnknown *pUnkOuter, void **ppObj)
{ {
static const WCHAR utf16W[] = {'U','T','F','-','1','6',0}; static const WCHAR utf16W[] = {'U','T','F','-','1','6',0};
static const WCHAR version10W[] = {'1','.','0',0};
mxwriter *This; mxwriter *This;
TRACE("(%p,%p)\n", pUnkOuter, ppObj); TRACE("(%p,%p)\n", pUnkOuter, ppObj);
...@@ -570,12 +623,27 @@ HRESULT MXWriter_create(IUnknown *pUnkOuter, void **ppObj) ...@@ -570,12 +623,27 @@ HRESULT MXWriter_create(IUnknown *pUnkOuter, void **ppObj)
This->standalone = VARIANT_FALSE; This->standalone = VARIANT_FALSE;
This->encoding = SysAllocString(utf16W); This->encoding = SysAllocString(utf16W);
This->version = SysAllocString(version10W);
This->dest = NULL; This->dest = NULL;
/* set up a buffer, default encoding is UTF-16 */
This->buffer = xmlAllocOutputBuffer(xmlFindCharEncodingHandler("UTF-16"));
*ppObj = &This->IMXWriter_iface; *ppObj = &This->IMXWriter_iface;
TRACE("returning iface %p\n", *ppObj); TRACE("returning iface %p\n", *ppObj);
return S_OK; 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 */
...@@ -22,6 +22,8 @@ ...@@ -22,6 +22,8 @@
#define CONST_VTABLE #define CONST_VTABLE
#include <stdio.h> #include <stdio.h>
#include <assert.h>
#include "windows.h" #include "windows.h"
#include "ole2.h" #include "ole2.h"
#include "msxml2.h" #include "msxml2.h"
...@@ -37,6 +39,32 @@ static void _expect_ref(IUnknown* obj, ULONG ref, int line) ...@@ -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); 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 { typedef enum _CH {
CH_ENDTEST, CH_ENDTEST,
CH_PUTDOCUMENTLOCATOR, CH_PUTDOCUMENTLOCATOR,
...@@ -754,7 +782,15 @@ static void test_mxwriter_properties(void) ...@@ -754,7 +782,15 @@ static void test_mxwriter_properties(void)
ok(hr == E_INVALIDARG, "got %08x\n", hr); ok(hr == E_INVALIDARG, "got %08x\n", hr);
SysFreeString(str); 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); IMXWriter_Release(writer);
free_bstrs();
} }
static void test_mxwriter_flush(void) static void test_mxwriter_flush(void)
...@@ -814,7 +850,7 @@ todo_wine { ...@@ -814,7 +850,7 @@ todo_wine {
ok(hr == S_OK, "got %08x\n", hr); ok(hr == S_OK, "got %08x\n", hr);
hr = ISAXContentHandler_startDocument(content); 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; pos.QuadPart = 0;
hr = IStream_Seek(stream, pos, STREAM_SEEK_CUR, &pos2); hr = IStream_Seek(stream, pos, STREAM_SEEK_CUR, &pos2);
...@@ -823,7 +859,7 @@ todo_wine { ...@@ -823,7 +859,7 @@ todo_wine {
/* already started */ /* already started */
hr = ISAXContentHandler_startDocument(content); 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); hr = ISAXContentHandler_endDocument(content);
todo_wine ok(hr == S_OK, "got %08x\n", hr); todo_wine ok(hr == S_OK, "got %08x\n", hr);
...@@ -839,6 +875,52 @@ todo_wine { ...@@ -839,6 +875,52 @@ todo_wine {
IMXWriter_Release(writer); 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) START_TEST(saxreader)
{ {
ISAXXMLReader *reader; ISAXXMLReader *reader;
...@@ -869,6 +951,7 @@ START_TEST(saxreader) ...@@ -869,6 +951,7 @@ START_TEST(saxreader)
IMXWriter_Release(writer); IMXWriter_Release(writer);
test_mxwriter_contenthandler(); test_mxwriter_contenthandler();
test_mxwriter_startenddocument();
test_mxwriter_properties(); test_mxwriter_properties();
test_mxwriter_flush(); test_mxwriter_flush();
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment