From 33a1f892b80df9ee4fddaa9a094aa2aba9c40dad Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Sun, 15 Jul 2012 00:36:54 +0400 Subject: [PATCH] msxml3: Implement a common way to store and get callback interface pointers. --- dlls/msxml3/saxreader.c | 533 ++++++++++++++++-------------------------- dlls/msxml3/tests/saxreader.c | 12 + 2 files changed, 212 insertions(+), 333 deletions(-) diff --git a/dlls/msxml3/saxreader.c b/dlls/msxml3/saxreader.c index 1125d1c360e..bdfdcab7ad1 100644 --- a/dlls/msxml3/saxreader.c +++ b/dlls/msxml3/saxreader.c @@ -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)) + { + IUnknown *handler = NULL; + + if (V_UNKNOWN(&value)) { + HRESULT hr; + if (vbInterface) - IVBSAXDeclHandler_Release(This->vbdeclHandler); + hr = IUnknown_QueryInterface(V_UNKNOWN(&value), &IID_IVBSAXDeclHandler, (void**)&handler); else - ISAXDeclHandler_Release(This->declHandler); + hr = IUnknown_QueryInterface(V_UNKNOWN(&value), &IID_ISAXDeclHandler, (void**)&handler); + if (FAILED(hr)) return hr; } - 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; - } + 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); - - if(This->vbcontentHandler) - IVBSAXContentHandler_Release(This->vbcontentHandler); - - if(This->errorHandler) - ISAXErrorHandler_Release(This->errorHandler); - - 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); + int i; - if(This->vbdeclHandler) - IVBSAXDeclHandler_Release(This->vbdeclHandler); + for (i = 0; i < SAXHandler_Last; i++) + { + struct saxhandler_iface *iface = &This->saxhandlers[i]; - if(This->dtdHandler) - ISAXDTDHandler_Release(This->dtdHandler); + if (iface->handler) + IUnknown_Release(iface->handler); - 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; diff --git a/dlls/msxml3/tests/saxreader.c b/dlls/msxml3/tests/saxreader.c index 2858583d96b..9216f3a2f49 100644 --- a/dlls/msxml3/tests/saxreader.c +++ b/dlls/msxml3/tests/saxreader.c @@ -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++; } -- 2.11.4.GIT