Commit 7db7d857 authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

msxml3: Fix putProperty() for declaration handler.

parent 864f1701
...@@ -2244,25 +2244,45 @@ static HRESULT internal_putProperty( ...@@ -2244,25 +2244,45 @@ static HRESULT internal_putProperty(
{ {
if(This->isParsing) return E_FAIL; if(This->isParsing) return E_FAIL;
if(V_UNKNOWN(&value)) switch (V_VT(&value))
{ {
if(vbInterface) case VT_EMPTY:
IVBSAXDeclHandler_AddRef((IVBSAXDeclHandler*)V_UNKNOWN(&value)); if (vbInterface)
{
if (This->vbdeclHandler)
{
IVBSAXDeclHandler_Release(This->vbdeclHandler);
This->vbdeclHandler = NULL;
}
}
else else
ISAXDeclHandler_AddRef((ISAXDeclHandler*)V_UNKNOWN(&value)); if (This->declHandler)
} {
if((vbInterface && This->vbdeclHandler) ISAXDeclHandler_Release(This->declHandler);
|| (!vbInterface && This->declHandler)) This->declHandler = NULL;
{ }
if(vbInterface) break;
IVBSAXDeclHandler_Release(This->vbdeclHandler); case VT_UNKNOWN:
if (V_UNKNOWN(&value)) IUnknown_AddRef(V_UNKNOWN(&value));
if ((vbInterface && This->vbdeclHandler) ||
(!vbInterface && This->declHandler))
{
if (vbInterface)
IVBSAXDeclHandler_Release(This->vbdeclHandler);
else
ISAXDeclHandler_Release(This->declHandler);
}
if (vbInterface)
This->vbdeclHandler = (IVBSAXDeclHandler*)V_UNKNOWN(&value);
else else
ISAXDeclHandler_Release(This->declHandler); This->declHandler = (ISAXDeclHandler*)V_UNKNOWN(&value);
break;
default:
return E_INVALIDARG;
} }
if(vbInterface)
This->vbdeclHandler = (IVBSAXDeclHandler*)V_UNKNOWN(&value);
else
This->declHandler = (ISAXDeclHandler*)V_UNKNOWN(&value);
return S_OK; return S_OK;
} }
...@@ -2358,6 +2378,14 @@ static HRESULT internal_getProperty(const saxreader* This, const WCHAR *prop, VA ...@@ -2358,6 +2378,14 @@ static HRESULT internal_getProperty(const saxreader* This, const WCHAR *prop, VA
return S_OK; return S_OK;
} }
if (!memcmp(PropertyDeclHandlerW, prop, sizeof(PropertyDeclHandlerW)))
{
V_VT(value) = VT_UNKNOWN;
V_UNKNOWN(value) = vb ? (IUnknown*)This->vbdeclHandler : (IUnknown*)This->declHandler;
if (V_UNKNOWN(value)) IUnknown_AddRef(V_UNKNOWN(value));
return S_OK;
}
FIXME("(%p)->(%s) unsupported property\n", This, debugstr_w(prop)); FIXME("(%p)->(%s) unsupported property\n", This, debugstr_w(prop));
return E_NOTIMPL; return E_NOTIMPL;
......
...@@ -711,7 +711,7 @@ static const ISAXAttributesVtbl SAXAttributesVtbl = ...@@ -711,7 +711,7 @@ static const ISAXAttributesVtbl SAXAttributesVtbl =
static ISAXAttributes saxattributes = { &SAXAttributesVtbl }; static ISAXAttributes saxattributes = { &SAXAttributesVtbl };
static int lexicalhandler_addrefcalled; static int handler_addrefcalled;
static HRESULT WINAPI isaxlexical_QueryInterface(ISAXLexicalHandler* iface, REFIID riid, void **ppvObject) static HRESULT WINAPI isaxlexical_QueryInterface(ISAXLexicalHandler* iface, REFIID riid, void **ppvObject)
{ {
...@@ -732,7 +732,7 @@ static HRESULT WINAPI isaxlexical_QueryInterface(ISAXLexicalHandler* iface, REFI ...@@ -732,7 +732,7 @@ static HRESULT WINAPI isaxlexical_QueryInterface(ISAXLexicalHandler* iface, REFI
static ULONG WINAPI isaxlexical_AddRef(ISAXLexicalHandler* iface) static ULONG WINAPI isaxlexical_AddRef(ISAXLexicalHandler* iface)
{ {
lexicalhandler_addrefcalled++; handler_addrefcalled++;
return 2; return 2;
} }
...@@ -804,6 +804,78 @@ static const ISAXLexicalHandlerVtbl SAXLexicalHandlerVtbl = ...@@ -804,6 +804,78 @@ static const ISAXLexicalHandlerVtbl SAXLexicalHandlerVtbl =
static ISAXLexicalHandler saxlexicalhandler = { &SAXLexicalHandlerVtbl }; static ISAXLexicalHandler saxlexicalhandler = { &SAXLexicalHandlerVtbl };
static HRESULT WINAPI isaxdecl_QueryInterface(ISAXDeclHandler* iface, REFIID riid, void **ppvObject)
{
*ppvObject = NULL;
if(IsEqualGUID(riid, &IID_IUnknown) ||
IsEqualGUID(riid, &IID_ISAXDeclHandler))
{
*ppvObject = iface;
}
else
{
return E_NOINTERFACE;
}
return S_OK;
}
static ULONG WINAPI isaxdecl_AddRef(ISAXDeclHandler* iface)
{
handler_addrefcalled++;
return 2;
}
static ULONG WINAPI isaxdecl_Release(ISAXDeclHandler* iface)
{
return 1;
}
static HRESULT WINAPI isaxdecl_elementDecl(ISAXDeclHandler* iface,
const WCHAR * pName, int nName, const WCHAR * pModel, int nModel)
{
ok(0, "call not expected\n");
return E_NOTIMPL;
}
static HRESULT WINAPI isaxdecl_attributeDecl(ISAXDeclHandler* iface,
const WCHAR * pElementName, int nElementName, const WCHAR * pAttributeName,
int nAttributeName, const WCHAR * pType, int nType, const WCHAR * pValueDefault,
int nValueDefault, const WCHAR * pValue, int nValue)
{
ok(0, "call not expected\n");
return E_NOTIMPL;
}
static HRESULT WINAPI isaxdecl_internalEntityDecl(ISAXDeclHandler* iface,
const WCHAR * pName, int nName, const WCHAR * pValue, int nValue)
{
ok(0, "call not expected\n");
return E_NOTIMPL;
}
static HRESULT WINAPI isaxdecl_externalEntityDecl(ISAXDeclHandler* iface,
const WCHAR * pName, int nName, const WCHAR * pPublicId, int nPublicId,
const WCHAR * pSystemId, int nSystemId)
{
ok(0, "call not expected\n");
return E_NOTIMPL;
}
static const ISAXDeclHandlerVtbl SAXDeclHandlerVtbl =
{
isaxdecl_QueryInterface,
isaxdecl_AddRef,
isaxdecl_Release,
isaxdecl_elementDecl,
isaxdecl_attributeDecl,
isaxdecl_internalEntityDecl,
isaxdecl_externalEntityDecl
};
static ISAXDeclHandler saxdeclhandler = { &SAXDeclHandlerVtbl };
typedef struct mxwriter_write_test_t { typedef struct mxwriter_write_test_t {
BOOL last; BOOL last;
const BYTE *data; const BYTE *data;
...@@ -1094,10 +1166,22 @@ static void test_saxreader(void) ...@@ -1094,10 +1166,22 @@ static void test_saxreader(void)
SysFreeString(bstrData); SysFreeString(bstrData);
} }
struct saxreader_props_test_t
{
const char *prop_name;
IUnknown *iface;
};
static const struct saxreader_props_test_t props_test_data[] = {
{ "http://xml.org/sax/properties/lexical-handler", (IUnknown*)&saxlexicalhandler },
{ "http://xml.org/sax/properties/declaration-handler", (IUnknown*)&saxdeclhandler },
{ 0 }
};
static void test_saxreader_properties(void) static void test_saxreader_properties(void)
{ {
const struct saxreader_props_test_t *ptr = props_test_data;
ISAXXMLReader *reader; ISAXXMLReader *reader;
VARIANT v;
HRESULT hr; HRESULT hr;
hr = CoCreateInstance(&CLSID_SAXXMLReader, NULL, CLSCTX_INPROC_SERVER, hr = CoCreateInstance(&CLSID_SAXXMLReader, NULL, CLSCTX_INPROC_SERVER,
...@@ -1107,71 +1191,77 @@ static void test_saxreader_properties(void) ...@@ -1107,71 +1191,77 @@ static void test_saxreader_properties(void)
hr = ISAXXMLReader_getProperty(reader, _bstr_("http://xml.org/sax/properties/lexical-handler"), NULL); hr = ISAXXMLReader_getProperty(reader, _bstr_("http://xml.org/sax/properties/lexical-handler"), NULL);
EXPECT_HR(hr, E_POINTER); EXPECT_HR(hr, E_POINTER);
/* set/remove lexical handler */ while (ptr->prop_name)
V_VT(&v) = VT_EMPTY; {
V_UNKNOWN(&v) = (IUnknown*)0xdeadbeef; VARIANT v;
hr = ISAXXMLReader_getProperty(reader, _bstr_("http://xml.org/sax/properties/lexical-handler"), &v);
EXPECT_HR(hr, S_OK);
ok(V_VT(&v) == VT_UNKNOWN, "got %d\n", V_VT(&v));
ok(V_UNKNOWN(&v) == NULL, "got %p\n", V_UNKNOWN(&v));
V_VT(&v) = VT_UNKNOWN; V_VT(&v) = VT_EMPTY;
V_UNKNOWN(&v) = (IUnknown*)&saxlexicalhandler; V_UNKNOWN(&v) = (IUnknown*)0xdeadbeef;
hr = ISAXXMLReader_putProperty(reader, _bstr_("http://xml.org/sax/properties/lexical-handler"), v); hr = ISAXXMLReader_getProperty(reader, _bstr_(ptr->prop_name), &v);
EXPECT_HR(hr, S_OK); EXPECT_HR(hr, S_OK);
ok(V_VT(&v) == VT_UNKNOWN, "got %d\n", V_VT(&v));
ok(V_UNKNOWN(&v) == NULL, "got %p\n", V_UNKNOWN(&v));
V_VT(&v) = VT_EMPTY; V_VT(&v) = VT_UNKNOWN;
V_UNKNOWN(&v) = (IUnknown*)0xdeadbeef; V_UNKNOWN(&v) = ptr->iface;
lexicalhandler_addrefcalled = 0; hr = ISAXXMLReader_putProperty(reader, _bstr_(ptr->prop_name), v);
hr = ISAXXMLReader_getProperty(reader, _bstr_("http://xml.org/sax/properties/lexical-handler"), &v); EXPECT_HR(hr, S_OK);
EXPECT_HR(hr, S_OK);
ok(V_VT(&v) == VT_UNKNOWN, "got %d\n", V_VT(&v));
ok(V_UNKNOWN(&v) == (IUnknown*)&saxlexicalhandler, "got %p\n", V_UNKNOWN(&v));
ok(lexicalhandler_addrefcalled == 1, "AddRef called %d times\n", lexicalhandler_addrefcalled);
VariantClear(&v);
V_VT(&v) = VT_EMPTY;
V_UNKNOWN(&v) = (IUnknown*)0xdeadbeef;
hr = ISAXXMLReader_putProperty(reader, _bstr_("http://xml.org/sax/properties/lexical-handler"), v);
EXPECT_HR(hr, S_OK);
V_VT(&v) = VT_EMPTY; V_VT(&v) = VT_EMPTY;
V_UNKNOWN(&v) = (IUnknown*)0xdeadbeef; V_UNKNOWN(&v) = (IUnknown*)0xdeadbeef;
hr = ISAXXMLReader_getProperty(reader, _bstr_("http://xml.org/sax/properties/lexical-handler"), &v); handler_addrefcalled = 0;
EXPECT_HR(hr, S_OK); hr = ISAXXMLReader_getProperty(reader, _bstr_(ptr->prop_name), &v);
ok(V_VT(&v) == VT_UNKNOWN, "got %d\n", V_VT(&v)); EXPECT_HR(hr, S_OK);
ok(V_UNKNOWN(&v) == NULL, "got %p\n", V_UNKNOWN(&v)); ok(V_VT(&v) == VT_UNKNOWN, "got %d\n", V_VT(&v));
ok(V_UNKNOWN(&v) == ptr->iface, "got %p\n", V_UNKNOWN(&v));
ok(handler_addrefcalled == 1, "AddRef called %d times\n", handler_addrefcalled);
VariantClear(&v);
V_VT(&v) = VT_EMPTY;
V_UNKNOWN(&v) = (IUnknown*)0xdeadbeef;
hr = ISAXXMLReader_putProperty(reader, _bstr_(ptr->prop_name), v);
EXPECT_HR(hr, S_OK);
V_VT(&v) = VT_UNKNOWN; V_VT(&v) = VT_EMPTY;
V_UNKNOWN(&v) = (IUnknown*)&saxlexicalhandler; V_UNKNOWN(&v) = (IUnknown*)0xdeadbeef;
hr = ISAXXMLReader_putProperty(reader, _bstr_("http://xml.org/sax/properties/lexical-handler"), v); hr = ISAXXMLReader_getProperty(reader, _bstr_(ptr->prop_name), &v);
EXPECT_HR(hr, S_OK); EXPECT_HR(hr, S_OK);
ok(V_VT(&v) == VT_UNKNOWN, "got %d\n", V_VT(&v));
ok(V_UNKNOWN(&v) == NULL, "got %p\n", V_UNKNOWN(&v));
/* only VT_EMPTY seems to be valid to reset property */ V_VT(&v) = VT_UNKNOWN;
V_VT(&v) = VT_I4; V_UNKNOWN(&v) = ptr->iface;
V_UNKNOWN(&v) = (IUnknown*)0xdeadbeef; hr = ISAXXMLReader_putProperty(reader, _bstr_(ptr->prop_name), v);
hr = ISAXXMLReader_putProperty(reader, _bstr_("http://xml.org/sax/properties/lexical-handler"), v); EXPECT_HR(hr, S_OK);
EXPECT_HR(hr, E_INVALIDARG);
V_VT(&v) = VT_EMPTY; /* only VT_EMPTY seems to be valid to reset property */
V_UNKNOWN(&v) = (IUnknown*)0xdeadbeef; V_VT(&v) = VT_I4;
hr = ISAXXMLReader_getProperty(reader, _bstr_("http://xml.org/sax/properties/lexical-handler"), &v); V_UNKNOWN(&v) = (IUnknown*)0xdeadbeef;
EXPECT_HR(hr, S_OK); hr = ISAXXMLReader_putProperty(reader, _bstr_(ptr->prop_name), v);
ok(V_VT(&v) == VT_UNKNOWN, "got %d\n", V_VT(&v)); EXPECT_HR(hr, E_INVALIDARG);
ok(V_UNKNOWN(&v) == (IUnknown*)&saxlexicalhandler, "got %p\n", V_UNKNOWN(&v));
VariantClear(&v);
V_VT(&v) = VT_UNKNOWN; V_VT(&v) = VT_EMPTY;
V_UNKNOWN(&v) = NULL; V_UNKNOWN(&v) = (IUnknown*)0xdeadbeef;
hr = ISAXXMLReader_putProperty(reader, _bstr_("http://xml.org/sax/properties/lexical-handler"), v); hr = ISAXXMLReader_getProperty(reader, _bstr_(ptr->prop_name), &v);
EXPECT_HR(hr, S_OK); EXPECT_HR(hr, S_OK);
ok(V_VT(&v) == VT_UNKNOWN, "got %d\n", V_VT(&v));
ok(V_UNKNOWN(&v) == ptr->iface, "got %p\n", V_UNKNOWN(&v));
VariantClear(&v);
V_VT(&v) = VT_EMPTY; V_VT(&v) = VT_UNKNOWN;
V_UNKNOWN(&v) = (IUnknown*)0xdeadbeef; V_UNKNOWN(&v) = NULL;
hr = ISAXXMLReader_getProperty(reader, _bstr_("http://xml.org/sax/properties/lexical-handler"), &v); hr = ISAXXMLReader_putProperty(reader, _bstr_(ptr->prop_name), v);
EXPECT_HR(hr, S_OK); EXPECT_HR(hr, S_OK);
ok(V_VT(&v) == VT_UNKNOWN, "got %d\n", V_VT(&v));
ok(V_UNKNOWN(&v) == NULL, "got %p\n", V_UNKNOWN(&v)); V_VT(&v) = VT_EMPTY;
V_UNKNOWN(&v) = (IUnknown*)0xdeadbeef;
hr = ISAXXMLReader_getProperty(reader, _bstr_(ptr->prop_name), &v);
EXPECT_HR(hr, S_OK);
ok(V_VT(&v) == VT_UNKNOWN, "got %d\n", V_VT(&v));
ok(V_UNKNOWN(&v) == NULL, "got %p\n", V_UNKNOWN(&v));
ptr++;
}
ISAXXMLReader_Release(reader); ISAXXMLReader_Release(reader);
free_bstrs(); free_bstrs();
......
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