msxml3: Fix putProperty() for lexical handler case.

This commit is contained in:
Nikolay Sivov 2011-09-21 21:01:10 +04:00 committed by Alexandre Julliard
parent be0d294485
commit 864f17016f
2 changed files with 294 additions and 84 deletions

View File

@ -137,6 +137,49 @@ static inline saxattributes *impl_from_ISAXAttributes( ISAXAttributes *iface )
return CONTAINING_RECORD(iface, saxattributes, ISAXAttributes_iface);
}
/* property names */
static const WCHAR PropertyCharsetW[] = {
'c','h','a','r','s','e','t',0
};
static const WCHAR PropertyDeclHandlerW[] = {
'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
'd','e','c','l','a','r','a','t','i','o','n',
'-','h','a','n','d','l','e','r',0
};
static const WCHAR PropertyDomNodeW[] = {
'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
'd','o','m','-','n','o','d','e',0
};
static const WCHAR PropertyInputSourceW[] = {
'i','n','p','u','t','-','s','o','u','r','c','e',0
};
static const WCHAR PropertyLexicalHandlerW[] = {
'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
'l','e','x','i','c','a','l','-','h','a','n','d','l','e','r',0
};
static const WCHAR PropertyMaxElementDepthW[] = {
'm','a','x','-','e','l','e','m','e','n','t','-','d','e','p','t','h',0
};
static const WCHAR PropertyMaxXMLSizeW[] = {
'm','a','x','-','x','m','l','-','s','i','z','e',0
};
static const WCHAR PropertySchemaDeclHandlerW[] = {
's','c','h','e','m','a','-','d','e','c','l','a','r','a','t','i','o','n','-',
'h','a','n','d','l','e','r',0
};
static const WCHAR PropertyXMLDeclEncodingW[] = {
'x','m','l','d','e','c','l','-','e','n','c','o','d','i','n','g',0
};
static const WCHAR PropertyXMLDeclStandaloneW[] = {
'x','m','l','d','e','c','l','-','s','t','a','n','d','a','l','o','n','e',0
};
static const WCHAR PropertyXMLDeclVersionW[] = {
'x','m','l','d','e','c','l','-','v','e','r','s','i','o','n',0
};
static inline BOOL has_content_handler(const saxlocator *locator)
{
return (locator->vbInterface && locator->saxreader->vbcontentHandler) ||
@ -2191,57 +2234,13 @@ static HRESULT internal_parseURL(
static HRESULT internal_putProperty(
saxreader* This,
const WCHAR *pProp,
const WCHAR *prop,
VARIANT value,
BOOL vbInterface)
{
static const WCHAR wszCharset[] = {
'c','h','a','r','s','e','t',0
};
static const WCHAR wszDeclarationHandler[] = {
'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
'd','e','c','l','a','r','a','t','i','o','n',
'-','h','a','n','d','l','e','r',0
};
static const WCHAR wszDomNode[] = {
'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
'd','o','m','-','n','o','d','e',0
};
static const WCHAR wszInputSource[] = {
'i','n','p','u','t','-','s','o','u','r','c','e',0
};
static const WCHAR wszLexicalHandler[] = {
'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
'l','e','x','i','c','a','l','-','h','a','n','d','l','e','r',0
};
static const WCHAR wszMaxElementDepth[] = {
'm','a','x','-','e','l','e','m','e','n','t','-','d','e','p','t','h',0
};
static const WCHAR wszMaxXMLSize[] = {
'm','a','x','-','x','m','l','-','s','i','z','e',0
};
static const WCHAR wszSchemaDeclarationHandler[] = {
's','c','h','e','m','a','-',
'd','e','c','l','a','r','a','t','i','o','n','-',
'h','a','n','d','l','e','r',0
};
static const WCHAR wszXMLDeclEncoding[] = {
'x','m','l','d','e','c','l','-','e','n','c','o','d','i','n','g',0
};
static const WCHAR wszXMLDeclStandalone[] = {
'x','m','l','d','e','c','l',
'-','s','t','a','n','d','a','l','o','n','e',0
};
static const WCHAR wszXMLDeclVersion[] = {
'x','m','l','d','e','c','l','-','v','e','r','s','i','o','n',0
};
TRACE("(%p)->(%s %s)\n", This, debugstr_w(prop), debugstr_variant(&value));
TRACE("(%p)->(%s %s)\n", This, debugstr_w(pProp), debugstr_variant(&value));
if(!memcmp(pProp, wszDeclarationHandler, sizeof(wszDeclarationHandler)))
if(!memcmp(prop, PropertyDeclHandlerW, sizeof(PropertyDeclHandlerW)))
{
if(This->isParsing) return E_FAIL;
@ -2267,67 +2266,103 @@ static HRESULT internal_putProperty(
return S_OK;
}
if(!memcmp(pProp, wszLexicalHandler, sizeof(wszLexicalHandler)))
if(!memcmp(prop, PropertyLexicalHandlerW, sizeof(PropertyLexicalHandlerW)))
{
if(This->isParsing) return E_FAIL;
if(V_UNKNOWN(&value))
switch (V_VT(&value))
{
if(vbInterface)
IVBSAXLexicalHandler_AddRef(
(IVBSAXLexicalHandler*)V_UNKNOWN(&value));
case VT_EMPTY:
if (vbInterface)
{
if (This->vblexicalHandler)
{
IVBSAXLexicalHandler_Release(This->vblexicalHandler);
This->vblexicalHandler = NULL;
}
}
else
ISAXLexicalHandler_AddRef(
(ISAXLexicalHandler*)V_UNKNOWN(&value));
}
if((vbInterface && This->vblexicalHandler)
|| (!vbInterface && This->lexicalHandler))
{
if(vbInterface)
IVBSAXLexicalHandler_Release(This->vblexicalHandler);
if (This->lexicalHandler)
{
ISAXLexicalHandler_Release(This->lexicalHandler);
This->lexicalHandler = NULL;
}
break;
case VT_UNKNOWN:
if (V_UNKNOWN(&value)) IUnknown_AddRef(V_UNKNOWN(&value));
if ((vbInterface && This->vblexicalHandler) ||
(!vbInterface && This->lexicalHandler))
{
if (vbInterface)
IVBSAXLexicalHandler_Release(This->vblexicalHandler);
else
ISAXLexicalHandler_Release(This->lexicalHandler);
}
if (vbInterface)
This->vblexicalHandler = (IVBSAXLexicalHandler*)V_UNKNOWN(&value);
else
ISAXLexicalHandler_Release(This->lexicalHandler);
This->lexicalHandler = (ISAXLexicalHandler*)V_UNKNOWN(&value);
break;
default:
return E_INVALIDARG;
}
if(vbInterface)
This->vblexicalHandler = (IVBSAXLexicalHandler*)V_UNKNOWN(&value);
else
This->lexicalHandler = (ISAXLexicalHandler*)V_UNKNOWN(&value);
return S_OK;
}
FIXME("(%p)->(%s): unsupported property\n", This, debugstr_w(pProp));
FIXME("(%p)->(%s): unsupported property\n", This, debugstr_w(prop));
if(!memcmp(pProp, wszCharset, sizeof(wszCharset)))
if(!memcmp(prop, PropertyCharsetW, sizeof(PropertyCharsetW)))
return E_NOTIMPL;
if(!memcmp(pProp, wszDomNode, sizeof(wszDomNode)))
if(!memcmp(prop, PropertyDomNodeW, sizeof(PropertyDomNodeW)))
return E_FAIL;
if(!memcmp(pProp, wszInputSource, sizeof(wszInputSource)))
if(!memcmp(prop, PropertyInputSourceW, sizeof(PropertyInputSourceW)))
return E_NOTIMPL;
if(!memcmp(pProp, wszMaxElementDepth, sizeof(wszMaxElementDepth)))
if(!memcmp(prop, PropertyMaxElementDepthW, sizeof(PropertyMaxElementDepthW)))
return E_NOTIMPL;
if(!memcmp(pProp, wszMaxXMLSize, sizeof(wszMaxXMLSize)))
if(!memcmp(prop, PropertyMaxXMLSizeW, sizeof(PropertyMaxXMLSizeW)))
return E_NOTIMPL;
if(!memcmp(pProp, wszSchemaDeclarationHandler,
sizeof(wszSchemaDeclarationHandler)))
if(!memcmp(prop, PropertySchemaDeclHandlerW, sizeof(PropertySchemaDeclHandlerW)))
return E_NOTIMPL;
if(!memcmp(pProp, wszXMLDeclEncoding, sizeof(wszXMLDeclEncoding)))
if(!memcmp(prop, PropertyXMLDeclEncodingW, sizeof(PropertyXMLDeclEncodingW)))
return E_FAIL;
if(!memcmp(pProp, wszXMLDeclStandalone, sizeof(wszXMLDeclStandalone)))
if(!memcmp(prop, PropertyXMLDeclStandaloneW, sizeof(PropertyXMLDeclStandaloneW)))
return E_FAIL;
if(!memcmp(pProp, wszXMLDeclVersion, sizeof(wszXMLDeclVersion)))
if(!memcmp(prop, PropertyXMLDeclVersionW, sizeof(PropertyXMLDeclVersionW)))
return E_FAIL;
return E_INVALIDARG;
}
static HRESULT internal_getProperty(const saxreader* This, const WCHAR *prop, VARIANT *value, BOOL vb)
{
TRACE("(%p)->(%s)\n", This, debugstr_w(prop));
if (!value) return E_POINTER;
if (!memcmp(PropertyLexicalHandlerW, prop, sizeof(PropertyLexicalHandlerW)))
{
V_VT(value) = VT_UNKNOWN;
V_UNKNOWN(value) = vb ? (IUnknown*)This->vblexicalHandler : (IUnknown*)This->lexicalHandler;
if (V_UNKNOWN(value)) IUnknown_AddRef(V_UNKNOWN(value));
return S_OK;
}
FIXME("(%p)->(%s) unsupported property\n", This, debugstr_w(prop));
return E_NOTIMPL;
}
/*** IVBSAXXMLReader interface ***/
/*** IUnknown methods ***/
static HRESULT WINAPI saxxmlreader_QueryInterface(IVBSAXXMLReader* iface, REFIID riid, void **ppvObject)
@ -2516,13 +2551,11 @@ static HRESULT WINAPI saxxmlreader_putFeature(
static HRESULT WINAPI saxxmlreader_getProperty(
IVBSAXXMLReader* iface,
const WCHAR *pProp,
VARIANT *pValue)
const WCHAR *prop,
VARIANT *value)
{
saxreader *This = impl_from_IVBSAXXMLReader( iface );
FIXME("(%p)->(%s %p) stub\n", This, debugstr_w(pProp), pValue);
return E_NOTIMPL;
return internal_getProperty(This, prop, value, TRUE);
}
static HRESULT WINAPI saxxmlreader_putProperty(
@ -2725,11 +2758,11 @@ static HRESULT WINAPI isaxxmlreader_putFeature(
static HRESULT WINAPI isaxxmlreader_getProperty(
ISAXXMLReader* iface,
const WCHAR *pProp,
VARIANT *pValue)
const WCHAR *prop,
VARIANT *value)
{
saxreader *This = impl_from_ISAXXMLReader( iface );
return IVBSAXXMLReader_getProperty(&This->IVBSAXXMLReader_iface, pProp, pValue);
return internal_getProperty(This, prop, value, FALSE);
}
static HRESULT WINAPI isaxxmlreader_putProperty(

View File

@ -711,6 +711,99 @@ static const ISAXAttributesVtbl SAXAttributesVtbl =
static ISAXAttributes saxattributes = { &SAXAttributesVtbl };
static int lexicalhandler_addrefcalled;
static HRESULT WINAPI isaxlexical_QueryInterface(ISAXLexicalHandler* iface, REFIID riid, void **ppvObject)
{
*ppvObject = NULL;
if(IsEqualGUID(riid, &IID_IUnknown) ||
IsEqualGUID(riid, &IID_ISAXLexicalHandler))
{
*ppvObject = iface;
}
else
{
return E_NOINTERFACE;
}
return S_OK;
}
static ULONG WINAPI isaxlexical_AddRef(ISAXLexicalHandler* iface)
{
lexicalhandler_addrefcalled++;
return 2;
}
static ULONG WINAPI isaxlexical_Release(ISAXLexicalHandler* iface)
{
return 1;
}
static HRESULT WINAPI isaxlexical_startDTD(ISAXLexicalHandler* 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 HRESULT WINAPI isaxlexical_endDTD(ISAXLexicalHandler* iface)
{
ok(0, "call not expected\n");
return E_NOTIMPL;
}
static HRESULT WINAPI isaxlexical_startEntity(ISAXLexicalHandler *iface,
const WCHAR * pName, int nName)
{
ok(0, "call not expected\n");
return E_NOTIMPL;
}
static HRESULT WINAPI isaxlexical_endEntity(ISAXLexicalHandler *iface,
const WCHAR * pName, int nName)
{
ok(0, "call not expected\n");
return E_NOTIMPL;
}
static HRESULT WINAPI isaxlexical_startCDATA(ISAXLexicalHandler *iface)
{
ok(0, "call not expected\n");
return E_NOTIMPL;
}
static HRESULT WINAPI isaxlexical_endCDATA(ISAXLexicalHandler *iface)
{
ok(0, "call not expected\n");
return E_NOTIMPL;
}
static HRESULT WINAPI isaxlexical_comment(ISAXLexicalHandler *iface,
const WCHAR * pChars, int nChars)
{
ok(0, "call not expected\n");
return E_NOTIMPL;
}
static const ISAXLexicalHandlerVtbl SAXLexicalHandlerVtbl =
{
isaxlexical_QueryInterface,
isaxlexical_AddRef,
isaxlexical_Release,
isaxlexical_startDTD,
isaxlexical_endDTD,
isaxlexical_startEntity,
isaxlexical_endEntity,
isaxlexical_startCDATA,
isaxlexical_endCDATA,
isaxlexical_comment
};
static ISAXLexicalHandler saxlexicalhandler = { &SAXLexicalHandlerVtbl };
typedef struct mxwriter_write_test_t {
BOOL last;
const BYTE *data;
@ -1001,6 +1094,89 @@ static void test_saxreader(void)
SysFreeString(bstrData);
}
static void test_saxreader_properties(void)
{
ISAXXMLReader *reader;
VARIANT v;
HRESULT hr;
hr = CoCreateInstance(&CLSID_SAXXMLReader, NULL, CLSCTX_INPROC_SERVER,
&IID_ISAXXMLReader, (void**)&reader);
EXPECT_HR(hr, S_OK);
hr = ISAXXMLReader_getProperty(reader, _bstr_("http://xml.org/sax/properties/lexical-handler"), NULL);
EXPECT_HR(hr, E_POINTER);
/* set/remove lexical handler */
V_VT(&v) = VT_EMPTY;
V_UNKNOWN(&v) = (IUnknown*)0xdeadbeef;
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_UNKNOWN(&v) = (IUnknown*)&saxlexicalhandler;
hr = ISAXXMLReader_putProperty(reader, _bstr_("http://xml.org/sax/properties/lexical-handler"), v);
EXPECT_HR(hr, S_OK);
V_VT(&v) = VT_EMPTY;
V_UNKNOWN(&v) = (IUnknown*)0xdeadbeef;
lexicalhandler_addrefcalled = 0;
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) == (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_UNKNOWN(&v) = (IUnknown*)0xdeadbeef;
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_UNKNOWN(&v) = (IUnknown*)&saxlexicalhandler;
hr = ISAXXMLReader_putProperty(reader, _bstr_("http://xml.org/sax/properties/lexical-handler"), v);
EXPECT_HR(hr, S_OK);
/* only VT_EMPTY seems to be valid to reset property */
V_VT(&v) = VT_I4;
V_UNKNOWN(&v) = (IUnknown*)0xdeadbeef;
hr = ISAXXMLReader_putProperty(reader, _bstr_("http://xml.org/sax/properties/lexical-handler"), v);
EXPECT_HR(hr, E_INVALIDARG);
V_VT(&v) = VT_EMPTY;
V_UNKNOWN(&v) = (IUnknown*)0xdeadbeef;
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) == (IUnknown*)&saxlexicalhandler, "got %p\n", V_UNKNOWN(&v));
VariantClear(&v);
V_VT(&v) = VT_UNKNOWN;
V_UNKNOWN(&v) = NULL;
hr = ISAXXMLReader_putProperty(reader, _bstr_("http://xml.org/sax/properties/lexical-handler"), v);
EXPECT_HR(hr, S_OK);
V_VT(&v) = VT_EMPTY;
V_UNKNOWN(&v) = (IUnknown*)0xdeadbeef;
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));
ISAXXMLReader_Release(reader);
free_bstrs();
}
/* UTF-8 data with UTF-8 BOM and UTF-16 in prolog */
static const CHAR UTF8BOMTest[] =
"\xEF\xBB\xBF<?xml version = \"1.0\" encoding = \"UTF-16\"?>\n"
@ -2050,6 +2226,7 @@ START_TEST(saxreader)
ISAXXMLReader_Release(reader);
test_saxreader();
test_saxreader_properties();
test_encoding();
/* MXXMLWriter tests */