msxml3: Implement a common way to store and get callback interface pointers.

This commit is contained in:
Nikolay Sivov 2012-07-15 00:36:54 +04:00 committed by Alexandre Julliard
parent 2bff764df0
commit 33a1f892b8
2 changed files with 213 additions and 334 deletions

View File

@ -163,22 +163,48 @@ typedef struct
int ns_count;
} element_entry;
enum saxhandler_type
{
SAXContentHandler = 0,
SAXDeclHandler,
SAXDTDHandler,
SAXErrorHandler,
SAXLexicalHandler,
SAXHandler_Last
};
struct saxhandler_iface
{
IUnknown *handler;
IUnknown *vbhandler;
};
struct saxcontenthandler_iface
{
ISAXContentHandler *handler;
IVBSAXContentHandler *vbhandler;
};
struct saxerrorhandler_iface
{
ISAXErrorHandler *handler;
IVBSAXErrorHandler *vbhandler;
};
struct saxlexicalhandler_iface
{
ISAXLexicalHandler *handler;
IVBSAXLexicalHandler *vbhandler;
};
typedef struct
{
DispatchEx dispex;
IVBSAXXMLReader IVBSAXXMLReader_iface;
ISAXXMLReader ISAXXMLReader_iface;
LONG ref;
ISAXContentHandler *contentHandler;
IVBSAXContentHandler *vbcontentHandler;
ISAXErrorHandler *errorHandler;
IVBSAXErrorHandler *vberrorHandler;
ISAXLexicalHandler *lexicalHandler;
IVBSAXLexicalHandler *vblexicalHandler;
ISAXDeclHandler *declHandler;
IVBSAXDeclHandler *vbdeclHandler;
ISAXDTDHandler *dtdHandler;
IVBSAXDTDHandler *vbdtdHandler;
struct saxhandler_iface saxhandlers[SAXHandler_Last];
xmlSAXHandler sax;
BOOL isParsing;
struct bstrpool pool;
@ -186,6 +212,59 @@ typedef struct
MSXML_VERSION version;
} saxreader;
static HRESULT saxreader_put_handler(saxreader *reader, enum saxhandler_type type, void *ptr, BOOL vb)
{
struct saxhandler_iface *iface = &reader->saxhandlers[type];
IUnknown *unk = (IUnknown*)ptr;
if (unk)
IUnknown_AddRef(unk);
if ((vb && iface->vbhandler) || (!vb && iface->handler))
IUnknown_Release(vb ? iface->vbhandler : iface->handler);
if (vb)
iface->vbhandler = unk;
else
iface->handler = unk;
return S_OK;
}
static HRESULT saxreader_get_handler(const saxreader *reader, enum saxhandler_type type, BOOL vb, void **ret)
{
const struct saxhandler_iface *iface = &reader->saxhandlers[type];
if (!ret) return E_POINTER;
if ((vb && iface->vbhandler) || (!vb && iface->handler))
{
if (vb)
IUnknown_AddRef(iface->vbhandler);
else
IUnknown_AddRef(iface->handler);
}
*ret = vb ? iface->vbhandler : iface->handler;
return S_OK;
}
static struct saxcontenthandler_iface *saxreader_get_contenthandler(saxreader *reader)
{
return (struct saxcontenthandler_iface*)&reader->saxhandlers[SAXContentHandler];
}
static struct saxerrorhandler_iface *saxreader_get_errorhandler(saxreader *reader)
{
return (struct saxerrorhandler_iface*)&reader->saxhandlers[SAXErrorHandler];
}
static struct saxlexicalhandler_iface *saxreader_get_lexicalhandler(saxreader *reader)
{
return (struct saxlexicalhandler_iface*)&reader->saxhandlers[SAXLexicalHandler];
}
typedef struct
{
IVBSAXLocator IVBSAXLocator_iface;
@ -317,20 +396,20 @@ static BOOL is_namespaces_enabled(const saxreader *reader)
static inline int has_content_handler(const saxlocator *locator)
{
return (locator->vbInterface && locator->saxreader->vbcontentHandler) ||
(!locator->vbInterface && locator->saxreader->contentHandler);
return (locator->vbInterface && locator->saxreader->saxhandlers[SAXContentHandler].vbhandler) ||
(!locator->vbInterface && locator->saxreader->saxhandlers[SAXContentHandler].handler);
}
static inline int has_lexical_handler(const saxlocator *locator)
{
return (locator->vbInterface && locator->saxreader->vblexicalHandler) ||
(!locator->vbInterface && locator->saxreader->lexicalHandler);
return (locator->vbInterface && locator->saxreader->saxhandlers[SAXLexicalHandler].vbhandler) ||
(!locator->vbInterface && locator->saxreader->saxhandlers[SAXLexicalHandler].handler);
}
static inline int has_error_handler(const saxlocator *locator)
{
return (locator->vbInterface && locator->saxreader->vberrorHandler) ||
(!locator->vbInterface && locator->saxreader->errorHandler);
return (locator->vbInterface && locator->saxreader->saxhandlers[SAXErrorHandler].vbhandler) ||
(!locator->vbInterface && locator->saxreader->saxhandlers[SAXErrorHandler].handler);
}
static BSTR build_qname(BSTR prefix, BSTR local)
@ -556,6 +635,7 @@ static BSTR pooled_bstr_from_xmlCharN(struct bstrpool *pool, const xmlChar *buf,
static void format_error_message_from_id(saxlocator *This, HRESULT hr)
{
struct saxerrorhandler_iface *handler = saxreader_get_errorhandler(This->saxreader);
xmlStopParser(This->pParserCtxt);
This->ret = hr;
@ -572,12 +652,12 @@ static void format_error_message_from_id(saxlocator *This, HRESULT hr)
if(This->vbInterface)
{
BSTR bstrMsg = SysAllocString(msg);
IVBSAXErrorHandler_fatalError(This->saxreader->vberrorHandler,
IVBSAXErrorHandler_fatalError(handler->vbhandler,
&This->IVBSAXLocator_iface, &bstrMsg, hr);
SysFreeString(bstrMsg);
}
else
ISAXErrorHandler_fatalError(This->saxreader->errorHandler,
ISAXErrorHandler_fatalError(handler->handler,
&This->ISAXLocator_iface, msg, hr);
}
}
@ -1225,6 +1305,7 @@ static HRESULT SAXAttributes_populate(saxlocator *locator,
static void libxmlStartDocument(void *ctx)
{
saxlocator *This = ctx;
struct saxcontenthandler_iface *handler = saxreader_get_contenthandler(This->saxreader);
HRESULT hr;
if (This->saxreader->version >= MSXML4)
@ -1245,9 +1326,9 @@ static void libxmlStartDocument(void *ctx)
if(has_content_handler(This))
{
if(This->vbInterface)
hr = IVBSAXContentHandler_startDocument(This->saxreader->vbcontentHandler);
hr = IVBSAXContentHandler_startDocument(handler->vbhandler);
else
hr = ISAXContentHandler_startDocument(This->saxreader->contentHandler);
hr = ISAXContentHandler_startDocument(handler->handler);
if (sax_callback_failed(This, hr))
format_error_message_from_id(This, hr);
@ -1257,6 +1338,7 @@ static void libxmlStartDocument(void *ctx)
static void libxmlEndDocument(void *ctx)
{
saxlocator *This = ctx;
struct saxcontenthandler_iface *handler = saxreader_get_contenthandler(This->saxreader);
HRESULT hr;
if (This->saxreader->version >= MSXML4) {
@ -1274,9 +1356,9 @@ static void libxmlEndDocument(void *ctx)
if(has_content_handler(This))
{
if(This->vbInterface)
hr = IVBSAXContentHandler_endDocument(This->saxreader->vbcontentHandler);
hr = IVBSAXContentHandler_endDocument(handler->vbhandler);
else
hr = ISAXContentHandler_endDocument(This->saxreader->contentHandler);
hr = ISAXContentHandler_endDocument(handler->handler);
if (sax_callback_failed(This, hr))
format_error_message_from_id(This, hr);
@ -1295,6 +1377,7 @@ static void libxmlStartElementNS(
const xmlChar **attributes)
{
saxlocator *This = ctx;
struct saxcontenthandler_iface *handler = saxreader_get_contenthandler(This->saxreader);
element_entry *element;
HRESULT hr = S_OK;
BSTR uri;
@ -1316,12 +1399,12 @@ static void libxmlStartElementNS(
{
if (This->vbInterface)
hr = IVBSAXContentHandler_startPrefixMapping(
This->saxreader->vbcontentHandler,
handler->vbhandler,
&element->ns[i].prefix,
&element->ns[i].uri);
else
hr = ISAXContentHandler_startPrefixMapping(
This->saxreader->contentHandler,
handler->handler,
element->ns[i].prefix,
SysStringLen(element->ns[i].prefix),
element->ns[i].uri,
@ -1347,10 +1430,10 @@ static void libxmlStartElementNS(
uri = local = NULL;
if (This->vbInterface)
hr = IVBSAXContentHandler_startElement(This->saxreader->vbcontentHandler,
hr = IVBSAXContentHandler_startElement(handler->vbhandler,
&uri, &local, &element->qname, &This->IVBSAXAttributes_iface);
else
hr = ISAXContentHandler_startElement(This->saxreader->contentHandler,
hr = ISAXContentHandler_startElement(handler->handler,
uri, SysStringLen(uri),
local, SysStringLen(local),
element->qname, SysStringLen(element->qname),
@ -1368,6 +1451,7 @@ static void libxmlEndElementNS(
const xmlChar *URI)
{
saxlocator *This = ctx;
struct saxcontenthandler_iface *handler = saxreader_get_contenthandler(This->saxreader);
element_entry *element;
const xmlChar *p;
BSTR uri, local;
@ -1418,11 +1502,11 @@ static void libxmlEndElementNS(
if (This->vbInterface)
hr = IVBSAXContentHandler_endElement(
This->saxreader->vbcontentHandler,
handler->vbhandler,
&uri, &local, &element->qname);
else
hr = ISAXContentHandler_endElement(
This->saxreader->contentHandler,
handler->handler,
uri, SysStringLen(uri),
local, SysStringLen(local),
element->qname, SysStringLen(element->qname));
@ -1443,11 +1527,10 @@ static void libxmlEndElementNS(
{
if (This->vbInterface)
hr = IVBSAXContentHandler_endPrefixMapping(
This->saxreader->vbcontentHandler, &element->ns[i].prefix);
handler->vbhandler, &element->ns[i].prefix);
else
hr = ISAXContentHandler_endPrefixMapping(
This->saxreader->contentHandler,
element->ns[i].prefix, SysStringLen(element->ns[i].prefix));
handler->handler, element->ns[i].prefix, SysStringLen(element->ns[i].prefix));
if (sax_callback_failed(This, hr)) break;
}
@ -1465,6 +1548,7 @@ static void libxmlCharacters(
int len)
{
saxlocator *This = ctx;
struct saxcontenthandler_iface *handler = saxreader_get_contenthandler(This->saxreader);
BSTR Chars;
HRESULT hr;
xmlChar *cur, *end;
@ -1524,12 +1608,9 @@ static void libxmlCharacters(
Chars = pooled_bstr_from_xmlCharN(&This->saxreader->pool, cur, end-cur);
if(This->vbInterface)
hr = IVBSAXContentHandler_characters(
This->saxreader->vbcontentHandler, &Chars);
hr = IVBSAXContentHandler_characters(handler->vbhandler, &Chars);
else
hr = ISAXContentHandler_characters(
This->saxreader->contentHandler,
Chars, SysStringLen(Chars));
hr = ISAXContentHandler_characters(handler->handler, Chars, SysStringLen(Chars));
if (sax_callback_failed(This, hr))
{
@ -1560,16 +1641,16 @@ static void libxmlSetDocumentLocator(
xmlSAXLocatorPtr loc)
{
saxlocator *This = ctx;
struct saxcontenthandler_iface *handler = saxreader_get_contenthandler(This->saxreader);
HRESULT hr = S_OK;
if(has_content_handler(This))
{
if(This->vbInterface)
hr = IVBSAXContentHandler_putref_documentLocator(This->saxreader->vbcontentHandler,
hr = IVBSAXContentHandler_putref_documentLocator(handler->vbhandler,
&This->IVBSAXLocator_iface);
else
hr = ISAXContentHandler_putDocumentLocator(This->saxreader->contentHandler,
&This->ISAXLocator_iface);
hr = ISAXContentHandler_putDocumentLocator(handler->handler, &This->ISAXLocator_iface);
}
if(FAILED(hr))
@ -1579,6 +1660,7 @@ static void libxmlSetDocumentLocator(
static void libxmlComment(void *ctx, const xmlChar *value)
{
saxlocator *This = ctx;
struct saxlexicalhandler_iface *handler = saxreader_get_lexicalhandler(This->saxreader);
BSTR bValue;
HRESULT hr;
const xmlChar *p = This->pParserCtxt->input->cur;
@ -1600,13 +1682,10 @@ static void libxmlComment(void *ctx, const xmlChar *value)
bValue = pooled_bstr_from_xmlChar(&This->saxreader->pool, value);
if(This->vbInterface)
hr = IVBSAXLexicalHandler_comment(
This->saxreader->vblexicalHandler, &bValue);
if (This->vbInterface)
hr = IVBSAXLexicalHandler_comment(handler->vbhandler, &bValue);
else
hr = ISAXLexicalHandler_comment(
This->saxreader->lexicalHandler,
bValue, SysStringLen(bValue));
hr = ISAXLexicalHandler_comment(handler->handler, bValue, SysStringLen(bValue));
if(FAILED(hr))
format_error_message_from_id(This, hr);
@ -1615,6 +1694,7 @@ static void libxmlComment(void *ctx, const xmlChar *value)
static void libxmlFatalError(void *ctx, const char *msg, ...)
{
saxlocator *This = ctx;
struct saxerrorhandler_iface *handler = saxreader_get_errorhandler(This->saxreader);
char message[1024];
WCHAR *error;
DWORD len;
@ -1650,13 +1730,12 @@ static void libxmlFatalError(void *ctx, const char *msg, ...)
if(This->vbInterface)
{
BSTR bstrError = SysAllocString(error);
IVBSAXErrorHandler_fatalError(This->saxreader->vberrorHandler, &This->IVBSAXLocator_iface,
IVBSAXErrorHandler_fatalError(handler->vbhandler, &This->IVBSAXLocator_iface,
&bstrError, E_FAIL);
SysFreeString(bstrError);
}
else
ISAXErrorHandler_fatalError(This->saxreader->errorHandler, &This->ISAXLocator_iface,
error, E_FAIL);
ISAXErrorHandler_fatalError(handler->handler, &This->ISAXLocator_iface, error, E_FAIL);
heap_free(error);
@ -1667,6 +1746,8 @@ static void libxmlFatalError(void *ctx, const char *msg, ...)
static void libxmlCDataBlock(void *ctx, const xmlChar *value, int len)
{
saxlocator *This = ctx;
struct saxcontenthandler_iface *content = saxreader_get_contenthandler(This->saxreader);
struct saxlexicalhandler_iface *lexical = saxreader_get_lexicalhandler(This->saxreader);
HRESULT hr = S_OK;
xmlChar *beg = (xmlChar*)This->pParserCtxt->input->cur-len;
xmlChar *cur, *end;
@ -1689,9 +1770,9 @@ static void libxmlCDataBlock(void *ctx, const xmlChar *value, int len)
if (has_lexical_handler(This))
{
if (This->vbInterface)
hr = IVBSAXLexicalHandler_startCDATA(This->saxreader->vblexicalHandler);
hr = IVBSAXLexicalHandler_startCDATA(lexical->vbhandler);
else
hr = ISAXLexicalHandler_startCDATA(This->saxreader->lexicalHandler);
hr = ISAXLexicalHandler_startCDATA(lexical->handler);
}
if(FAILED(hr))
@ -1720,16 +1801,13 @@ static void libxmlCDataBlock(void *ctx, const xmlChar *value, int len)
if(change) *end = '\n';
if(has_content_handler(This))
if (has_content_handler(This))
{
Chars = pooled_bstr_from_xmlCharN(&This->saxreader->pool, cur, end-cur+1);
if(This->vbInterface)
hr = IVBSAXContentHandler_characters(
This->saxreader->vbcontentHandler, &Chars);
if (This->vbInterface)
hr = IVBSAXContentHandler_characters(content->vbhandler, &Chars);
else
hr = ISAXContentHandler_characters(
This->saxreader->contentHandler,
Chars, SysStringLen(Chars));
hr = ISAXContentHandler_characters(content->handler, Chars, SysStringLen(Chars));
}
if(change) *end = '\r';
@ -1745,9 +1823,9 @@ static void libxmlCDataBlock(void *ctx, const xmlChar *value, int len)
if (has_lexical_handler(This))
{
if (This->vbInterface)
hr = IVBSAXLexicalHandler_endCDATA(This->saxreader->vblexicalHandler);
hr = IVBSAXLexicalHandler_endCDATA(lexical->vbhandler);
else
hr = ISAXLexicalHandler_endCDATA(This->saxreader->lexicalHandler);
hr = ISAXLexicalHandler_endCDATA(lexical->handler);
}
if(FAILED(hr))
@ -2308,154 +2386,6 @@ static HRESULT internal_putEntityResolver(
return E_NOTIMPL;
}
static HRESULT internal_getContentHandler(
saxreader* This,
void *pContentHandler,
BOOL vbInterface)
{
TRACE("(%p)->(%p)\n", This, pContentHandler);
if(pContentHandler == NULL)
return E_POINTER;
if((vbInterface && This->vbcontentHandler)
|| (!vbInterface && This->contentHandler))
{
if(vbInterface)
IVBSAXContentHandler_AddRef(This->vbcontentHandler);
else
ISAXContentHandler_AddRef(This->contentHandler);
}
if(vbInterface) *(IVBSAXContentHandler**)pContentHandler =
This->vbcontentHandler;
else *(ISAXContentHandler**)pContentHandler = This->contentHandler;
return S_OK;
}
static HRESULT internal_putContentHandler(
saxreader* This,
void *contentHandler,
BOOL vbInterface)
{
TRACE("(%p)->(%p)\n", This, contentHandler);
if(contentHandler)
{
if(vbInterface)
IVBSAXContentHandler_AddRef((IVBSAXContentHandler*)contentHandler);
else
ISAXContentHandler_AddRef((ISAXContentHandler*)contentHandler);
}
if((vbInterface && This->vbcontentHandler)
|| (!vbInterface && This->contentHandler))
{
if(vbInterface)
IVBSAXContentHandler_Release(This->vbcontentHandler);
else
ISAXContentHandler_Release(This->contentHandler);
}
if(vbInterface)
This->vbcontentHandler = contentHandler;
else
This->contentHandler = contentHandler;
return S_OK;
}
static HRESULT internal_getDTDHandler(saxreader* This, void *dtdHandler, BOOL vbInterface)
{
TRACE("(%p)->(%p)\n", This, dtdHandler);
if (!dtdHandler) return E_POINTER;
if ((vbInterface && This->vbdtdHandler) || (!vbInterface && This->dtdHandler))
{
if (vbInterface)
IVBSAXContentHandler_AddRef(This->vbdtdHandler);
else
ISAXContentHandler_AddRef(This->dtdHandler);
}
if (vbInterface) *(IVBSAXDTDHandler**)dtdHandler = This->vbdtdHandler;
else *(ISAXDTDHandler**)dtdHandler = This->dtdHandler;
return S_OK;
}
static HRESULT internal_putDTDHandler(saxreader* This, void *dtdHandler, BOOL vbInterface)
{
TRACE("(%p)->(%p)\n", This, dtdHandler);
if (dtdHandler)
{
if (vbInterface)
IVBSAXDTDHandler_AddRef((IVBSAXDTDHandler*)dtdHandler);
else
ISAXDTDHandler_AddRef((ISAXDTDHandler*)dtdHandler);
}
if ((vbInterface && This->vbdtdHandler) || (!vbInterface && This->dtdHandler))
{
if (vbInterface)
IVBSAXDTDHandler_Release(This->vbdtdHandler);
else
ISAXDTDHandler_Release(This->dtdHandler);
}
if (vbInterface)
This->vbdtdHandler = dtdHandler;
else
This->dtdHandler = dtdHandler;
return S_OK;
}
static HRESULT internal_getErrorHandler(
saxreader* This,
void *pErrorHandler,
BOOL vbInterface)
{
TRACE("(%p)->(%p)\n", This, pErrorHandler);
if(pErrorHandler == NULL)
return E_POINTER;
if(vbInterface && This->vberrorHandler)
IVBSAXErrorHandler_AddRef(This->vberrorHandler);
else if(!vbInterface && This->errorHandler)
ISAXErrorHandler_AddRef(This->errorHandler);
if(vbInterface)
*(IVBSAXErrorHandler**)pErrorHandler = This->vberrorHandler;
else
*(ISAXErrorHandler**)pErrorHandler = This->errorHandler;
return S_OK;
}
static HRESULT internal_putErrorHandler(
saxreader* This,
void *errorHandler,
BOOL vbInterface)
{
TRACE("(%p)->(%p)\n", This, errorHandler);
if(errorHandler)
{
if(vbInterface)
IVBSAXErrorHandler_AddRef((IVBSAXErrorHandler*)errorHandler);
else
ISAXErrorHandler_AddRef((ISAXErrorHandler*)errorHandler);
}
if(vbInterface && This->vberrorHandler)
IVBSAXErrorHandler_Release(This->vberrorHandler);
else if(!vbInterface && This->errorHandler)
ISAXErrorHandler_Release(This->errorHandler);
if(vbInterface)
This->vberrorHandler = errorHandler;
else
This->errorHandler = errorHandler;
return S_OK;
}
static HRESULT internal_parse(
saxreader* This,
VARIANT varInput,
@ -2598,43 +2528,27 @@ static HRESULT internal_putProperty(
switch (V_VT(&value))
{
case VT_EMPTY:
if (vbInterface)
{
if (This->vbdeclHandler)
{
IVBSAXDeclHandler_Release(This->vbdeclHandler);
This->vbdeclHandler = NULL;
}
}
else
if (This->declHandler)
{
ISAXDeclHandler_Release(This->declHandler);
This->declHandler = NULL;
}
saxreader_put_handler(This, SAXDeclHandler, NULL, vbInterface);
break;
case VT_UNKNOWN:
if ((vbInterface && This->vbdeclHandler) ||
(!vbInterface && This->declHandler))
{
if (vbInterface)
IVBSAXDeclHandler_Release(This->vbdeclHandler);
else
ISAXDeclHandler_Release(This->declHandler);
}
{
IUnknown *handler = NULL;
if (V_UNKNOWN(&value))
{
return vbInterface ?
IVBSAXDeclHandler_QueryInterface(V_UNKNOWN(&value), &IID_IVBSAXDeclHandler, (void**)&This->vbdeclHandler) :
ISAXDeclHandler_QueryInterface(V_UNKNOWN(&value), &IID_ISAXDeclHandler, (void**)&This->declHandler);
}
else
{
This->vbdeclHandler = NULL;
This->declHandler = NULL;
HRESULT hr;
if (vbInterface)
hr = IUnknown_QueryInterface(V_UNKNOWN(&value), &IID_IVBSAXDeclHandler, (void**)&handler);
else
hr = IUnknown_QueryInterface(V_UNKNOWN(&value), &IID_ISAXDeclHandler, (void**)&handler);
if (FAILED(hr)) return hr;
}
saxreader_put_handler(This, SAXDeclHandler, handler, vbInterface);
if (handler) IUnknown_Release(handler);
break;
}
default:
return E_INVALIDARG;
}
@ -2649,44 +2563,27 @@ static HRESULT internal_putProperty(
switch (V_VT(&value))
{
case VT_EMPTY:
if (vbInterface)
{
if (This->vblexicalHandler)
{
IVBSAXLexicalHandler_Release(This->vblexicalHandler);
This->vblexicalHandler = NULL;
}
}
else
if (This->lexicalHandler)
{
ISAXLexicalHandler_Release(This->lexicalHandler);
This->lexicalHandler = NULL;
}
saxreader_put_handler(This, SAXLexicalHandler, NULL, vbInterface);
break;
case VT_UNKNOWN:
if ((vbInterface && This->vblexicalHandler) ||
(!vbInterface && This->lexicalHandler))
{
if (vbInterface)
IVBSAXLexicalHandler_Release(This->vblexicalHandler);
else
ISAXLexicalHandler_Release(This->lexicalHandler);
}
{
IUnknown *handler = NULL;
if (V_UNKNOWN(&value))
{
return vbInterface ?
IVBSAXLexicalHandler_QueryInterface(V_UNKNOWN(&value), &IID_IVBSAXLexicalHandler, (void**)&This->vblexicalHandler) :
ISAXLexicalHandler_QueryInterface(V_UNKNOWN(&value), &IID_ISAXLexicalHandler, (void**)&This->lexicalHandler);
}
else
{
This->vblexicalHandler = NULL;
This->lexicalHandler = NULL;
HRESULT hr;
if (vbInterface)
hr = IUnknown_QueryInterface(V_UNKNOWN(&value), &IID_IVBSAXLexicalHandler, (void**)&handler);
else
hr = IUnknown_QueryInterface(V_UNKNOWN(&value), &IID_ISAXLexicalHandler, (void**)&handler);
if (FAILED(hr)) return hr;
}
saxreader_put_handler(This, SAXLexicalHandler, handler, vbInterface);
if (handler) IUnknown_Release(handler);
break;
}
default:
return E_INVALIDARG;
}
@ -2743,16 +2640,14 @@ static HRESULT internal_getProperty(const saxreader* This, const WCHAR *prop, VA
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));
saxreader_get_handler(This, SAXLexicalHandler, vb, (void**)&V_UNKNOWN(value));
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));
saxreader_get_handler(This, SAXDeclHandler, vb, (void**)&V_UNKNOWN(value));
return S_OK;
}
@ -2814,35 +2709,18 @@ static ULONG WINAPI saxxmlreader_Release(
ref = InterlockedDecrement( &This->ref );
if ( ref == 0 )
{
if(This->contentHandler)
ISAXContentHandler_Release(This->contentHandler);
int i;
if(This->vbcontentHandler)
IVBSAXContentHandler_Release(This->vbcontentHandler);
for (i = 0; i < SAXHandler_Last; i++)
{
struct saxhandler_iface *iface = &This->saxhandlers[i];
if(This->errorHandler)
ISAXErrorHandler_Release(This->errorHandler);
if (iface->handler)
IUnknown_Release(iface->handler);
if(This->vberrorHandler)
IVBSAXErrorHandler_Release(This->vberrorHandler);
if(This->lexicalHandler)
ISAXLexicalHandler_Release(This->lexicalHandler);
if(This->vblexicalHandler)
IVBSAXLexicalHandler_Release(This->vblexicalHandler);
if(This->declHandler)
ISAXDeclHandler_Release(This->declHandler);
if(This->vbdeclHandler)
IVBSAXDeclHandler_Release(This->vbdeclHandler);
if(This->dtdHandler)
ISAXDTDHandler_Release(This->dtdHandler);
if(This->vbdtdHandler)
IVBSAXDTDHandler_Release(This->vbdtdHandler);
if (iface->vbhandler)
IUnknown_Release(iface->vbhandler);
}
free_bstr_pool(&This->pool);
@ -2983,50 +2861,50 @@ static HRESULT WINAPI saxxmlreader_put_entityResolver(
static HRESULT WINAPI saxxmlreader_get_contentHandler(
IVBSAXXMLReader* iface,
IVBSAXContentHandler **ppContentHandler)
IVBSAXContentHandler **handler)
{
saxreader *This = impl_from_IVBSAXXMLReader( iface );
return internal_getContentHandler(This, ppContentHandler, TRUE);
return saxreader_get_handler(This, SAXContentHandler, TRUE, (void**)handler);
}
static HRESULT WINAPI saxxmlreader_put_contentHandler(
IVBSAXXMLReader* iface,
IVBSAXContentHandler *contentHandler)
IVBSAXContentHandler *handler)
{
saxreader *This = impl_from_IVBSAXXMLReader( iface );
return internal_putContentHandler(This, contentHandler, TRUE);
return saxreader_put_handler(This, SAXContentHandler, handler, TRUE);
}
static HRESULT WINAPI saxxmlreader_get_dtdHandler(
IVBSAXXMLReader* iface,
IVBSAXDTDHandler **pDTDHandler)
IVBSAXDTDHandler **handler)
{
saxreader *This = impl_from_IVBSAXXMLReader( iface );
return internal_getDTDHandler(This, pDTDHandler, TRUE);
return saxreader_get_handler(This, SAXDTDHandler, TRUE, (void**)handler);
}
static HRESULT WINAPI saxxmlreader_put_dtdHandler(
IVBSAXXMLReader* iface,
IVBSAXDTDHandler *pDTDHandler)
IVBSAXDTDHandler *handler)
{
saxreader *This = impl_from_IVBSAXXMLReader( iface );
return internal_putDTDHandler(This, pDTDHandler, TRUE);
return saxreader_put_handler(This, SAXDTDHandler, handler, TRUE);
}
static HRESULT WINAPI saxxmlreader_get_errorHandler(
IVBSAXXMLReader* iface,
IVBSAXErrorHandler **pErrorHandler)
IVBSAXErrorHandler **handler)
{
saxreader *This = impl_from_IVBSAXXMLReader( iface );
return internal_getErrorHandler(This, pErrorHandler, TRUE);
return saxreader_get_handler(This, SAXErrorHandler, TRUE, (void**)handler);
}
static HRESULT WINAPI saxxmlreader_put_errorHandler(
IVBSAXXMLReader* iface,
IVBSAXErrorHandler *errorHandler)
IVBSAXErrorHandler *handler)
{
saxreader *This = impl_from_IVBSAXXMLReader( iface );
return internal_putErrorHandler(This, errorHandler, TRUE);
return saxreader_put_handler(This, SAXErrorHandler, handler, TRUE);
}
static HRESULT WINAPI saxxmlreader_get_baseURL(
@ -3190,50 +3068,48 @@ static HRESULT WINAPI isaxxmlreader_putEntityResolver(
static HRESULT WINAPI isaxxmlreader_getContentHandler(
ISAXXMLReader* iface,
ISAXContentHandler **pContentHandler)
ISAXContentHandler **handler)
{
saxreader *This = impl_from_ISAXXMLReader( iface );
return internal_getContentHandler(This, pContentHandler, FALSE);
return saxreader_get_handler(This, SAXContentHandler, FALSE, (void**)handler);
}
static HRESULT WINAPI isaxxmlreader_putContentHandler(
ISAXXMLReader* iface,
ISAXContentHandler *contentHandler)
ISAXXMLReader* iface,
ISAXContentHandler *handler)
{
saxreader *This = impl_from_ISAXXMLReader( iface );
return internal_putContentHandler(This, contentHandler, FALSE);
return saxreader_put_handler(This, SAXContentHandler, handler, FALSE);
}
static HRESULT WINAPI isaxxmlreader_getDTDHandler(
ISAXXMLReader* iface,
ISAXDTDHandler **pDTDHandler)
ISAXDTDHandler **handler)
{
saxreader *This = impl_from_ISAXXMLReader( iface );
return internal_getDTDHandler(This, pDTDHandler, FALSE);
return saxreader_get_handler(This, SAXDTDHandler, FALSE, (void**)handler);
}
static HRESULT WINAPI isaxxmlreader_putDTDHandler(
ISAXXMLReader* iface,
ISAXDTDHandler *pDTDHandler)
ISAXDTDHandler *handler)
{
saxreader *This = impl_from_ISAXXMLReader( iface );
return internal_putDTDHandler(This, pDTDHandler, FALSE);
return saxreader_put_handler(This, SAXDTDHandler, handler, FALSE);
}
static HRESULT WINAPI isaxxmlreader_getErrorHandler(
ISAXXMLReader* iface,
ISAXErrorHandler **pErrorHandler)
ISAXErrorHandler **handler)
{
saxreader *This = impl_from_ISAXXMLReader( iface );
return internal_getErrorHandler(This, pErrorHandler, FALSE);
return saxreader_get_handler(This, SAXErrorHandler, FALSE, (void**)handler);
}
static HRESULT WINAPI isaxxmlreader_putErrorHandler(
ISAXXMLReader* iface,
ISAXErrorHandler *errorHandler)
static HRESULT WINAPI isaxxmlreader_putErrorHandler(ISAXXMLReader* iface, ISAXErrorHandler *handler)
{
saxreader *This = impl_from_ISAXXMLReader( iface );
return internal_putErrorHandler(This, errorHandler, FALSE);
return saxreader_put_handler(This, SAXErrorHandler, handler, FALSE);
}
static HRESULT WINAPI isaxxmlreader_getBaseURL(
@ -3333,16 +3209,7 @@ HRESULT SAXXMLReader_create(MSXML_VERSION version, IUnknown *outer, LPVOID *ppOb
reader->IVBSAXXMLReader_iface.lpVtbl = &VBSAXXMLReaderVtbl;
reader->ISAXXMLReader_iface.lpVtbl = &SAXXMLReaderVtbl;
reader->ref = 1;
reader->contentHandler = NULL;
reader->vbcontentHandler = NULL;
reader->errorHandler = NULL;
reader->vberrorHandler = NULL;
reader->lexicalHandler = NULL;
reader->vblexicalHandler = NULL;
reader->declHandler = NULL;
reader->vbdeclHandler = NULL;
reader->dtdHandler = NULL;
reader->vbdtdHandler = NULL;
memset(reader->saxhandlers, 0, sizeof(reader->saxhandlers));
reader->isParsing = FALSE;
reader->pool.pool = NULL;
reader->pool.index = 0;

View File

@ -2332,6 +2332,11 @@ static void test_saxreader_properties(void)
ok(V_UNKNOWN(&v) == NULL, "got %p\n", V_UNKNOWN(&v));
/* block QueryInterface on handler riid */
V_VT(&v) = VT_UNKNOWN;
V_UNKNOWN(&v) = ptr->iface;
hr = ISAXXMLReader_putProperty(reader, _bstr_(ptr->prop_name), v);
EXPECT_HR(hr, S_OK);
init_saxlexicalhandler(&lexicalhandler, E_NOINTERFACE);
init_saxdeclhandler(&declhandler, E_NOINTERFACE);
@ -2343,6 +2348,13 @@ static void test_saxreader_properties(void)
EXPECT_HR(hr, E_NOINTERFACE);
EXPECT_REF(ptr->iface, 1);
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++;
}