[3/3] msxml3: Implement a common way to store and get callback interface pointers

Nikolay Sivov nsivov at codeweavers.com
Mon Jul 16 04:11:20 CDT 2012


Implement a common way to store and get callback interface pointers
-------------- next part --------------
>From 26a57a6ef06ce3748443bee757d2640bcf343038 Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <nsivov at codeweavers.com>
Date: Sun, 15 Jul 2012 00:36:54 +0400
Subject: [PATCH 6/6] 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 1125d1c..bdfdcab 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 2858583..9216f3a 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++;
     }
 
-- 
1.5.6.5




More information about the wine-patches mailing list