Nikolay Sivov : msxml3: Make it possible to use different outer objects with single IEnumVARIANT implementation .

Alexandre Julliard julliard at winehq.org
Mon Jul 2 13:22:02 CDT 2012


Module: wine
Branch: master
Commit: 27eedd5f5eae5d62e5c8c13f3b47d5b2f9c59029
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=27eedd5f5eae5d62e5c8c13f3b47d5b2f9c59029

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Sat Jun 30 20:34:27 2012 +0400

msxml3: Make it possible to use different outer objects with single IEnumVARIANT implementation.

---

 dlls/msxml3/selection.c |   71 ++++++++++++++++++++++++++++++----------------
 1 files changed, 46 insertions(+), 25 deletions(-)

diff --git a/dlls/msxml3/selection.c b/dlls/msxml3/selection.c
index 3cbf4e9..b41e323 100644
--- a/dlls/msxml3/selection.c
+++ b/dlls/msxml3/selection.c
@@ -59,18 +59,26 @@ WINE_DEFAULT_DEBUG_CHANNEL(msxml);
 int registerNamespaces(xmlXPathContextPtr ctxt);
 xmlChar* XSLPattern_to_XPath(xmlXPathContextPtr ctxt, xmlChar const* xslpat_str);
 
-typedef struct _enumvariant
+struct enumvariant_funcs
+{
+    HRESULT (*get_item)(IUnknown*, LONG, IDispatch**);
+    HRESULT (*next)(IUnknown*);
+};
+
+typedef struct
 {
     IEnumVARIANT IEnumVARIANT_iface;
     LONG ref;
 
-    IXMLDOMSelection *selection;
+    IUnknown *outer;
     BOOL own;
 
     LONG pos;
+
+    const struct enumvariant_funcs *funcs;
 } enumvariant;
 
-typedef struct _domselection
+typedef struct
 {
     DispatchEx dispex;
     IXMLDOMSelection IXMLDOMSelection_iface;
@@ -81,6 +89,24 @@ typedef struct _domselection
     IEnumVARIANT *enumvariant;
 } domselection;
 
+static HRESULT selection_get_item(IUnknown *iface, LONG index, IDispatch** item)
+{
+    return IXMLDOMSelection_get_item((IXMLDOMSelection*)iface, index, (IXMLDOMNode**)item);
+}
+
+static HRESULT selection_next(IUnknown *iface)
+{
+    IXMLDOMNode *node;
+    HRESULT hr = IXMLDOMSelection_nextNode((IXMLDOMSelection*)iface, &node);
+    if (hr == S_OK) IXMLDOMNode_Release(node);
+    return hr;
+}
+
+static const struct enumvariant_funcs selection_enumvariant = {
+    selection_get_item,
+    selection_next
+};
+
 static inline domselection *impl_from_IXMLDOMSelection( IXMLDOMSelection *iface )
 {
     return CONTAINING_RECORD(iface, domselection, IXMLDOMSelection_iface);
@@ -91,7 +117,7 @@ static inline enumvariant *impl_from_IEnumVARIANT( IEnumVARIANT *iface )
     return CONTAINING_RECORD(iface, enumvariant, IEnumVARIANT_iface);
 }
 
-static HRESULT create_enumvariant(IXMLDOMSelection*, BOOL, IUnknown**);
+static HRESULT create_enumvariant(IUnknown*, BOOL, IEnumVARIANT**);
 
 static HRESULT WINAPI domselection_QueryInterface(
     IXMLDOMSelection *iface,
@@ -115,7 +141,7 @@ static HRESULT WINAPI domselection_QueryInterface(
     {
         if (!This->enumvariant)
         {
-            HRESULT hr = create_enumvariant(iface, FALSE, (IUnknown**)&This->enumvariant);
+            HRESULT hr = create_enumvariant((IUnknown*)iface, FALSE, &This->enumvariant);
             if (FAILED(hr)) return hr;
         }
 
@@ -284,13 +310,13 @@ static HRESULT WINAPI domselection_reset(
 
 static HRESULT WINAPI domselection_get__newEnum(
         IXMLDOMSelection* iface,
-        IUnknown** ppUnk)
+        IUnknown** enumv)
 {
     domselection *This = impl_from_IXMLDOMSelection( iface );
 
-    TRACE("(%p)->(%p)\n", This, ppUnk);
+    TRACE("(%p)->(%p)\n", This, enumv);
 
-    return create_enumvariant(iface, TRUE, ppUnk);
+    return create_enumvariant((IUnknown*)iface, TRUE, (IEnumVARIANT**)enumv);
 }
 
 static HRESULT WINAPI domselection_get_expr(
@@ -438,14 +464,14 @@ static HRESULT WINAPI enumvariant_QueryInterface(
         if (This->own)
             *ppvObject = &This->IEnumVARIANT_iface;
         else
-            return IXMLDOMSelection_QueryInterface(This->selection, riid, ppvObject);
+            return IUnknown_QueryInterface(This->outer, riid, ppvObject);
     }
     else if (IsEqualGUID( riid, &IID_IEnumVARIANT ))
     {
         *ppvObject = &This->IEnumVARIANT_iface;
     }
     else
-        return IXMLDOMSelection_QueryInterface(This->selection, riid, ppvObject);
+        return IUnknown_QueryInterface(This->outer, riid, ppvObject);
 
     IEnumVARIANT_AddRef( iface );
 
@@ -468,7 +494,7 @@ static ULONG WINAPI enumvariant_Release(IEnumVARIANT *iface )
     TRACE("(%p)->(%d)\n", This, ref);
     if ( ref == 0 )
     {
-        if (This->own) IXMLDOMSelection_Release(This->selection);
+        if (This->own) IUnknown_Release(This->outer);
         heap_free(This);
     }
 
@@ -482,7 +508,6 @@ static HRESULT WINAPI enumvariant_Next(
     ULONG *fetched)
 {
     enumvariant *This = impl_from_IEnumVARIANT( iface );
-    IXMLDOMNode *node;
     ULONG ret_count = 0;
 
     TRACE("(%p)->(%u %p %p)\n", This, celt, var, fetched);
@@ -496,13 +521,9 @@ static HRESULT WINAPI enumvariant_Next(
         IDispatch *disp = NULL;
         HRESULT hr;
 
-        node = NULL;
-        hr = IXMLDOMSelection_get_item(This->selection, This->pos, &node);
+        hr = This->funcs->get_item(This->outer, This->pos, &disp);
         if (hr != S_OK) break;
 
-        IXMLDOMNode_QueryInterface(node, &IID_IDispatch, (void**)&disp);
-        IXMLDOMNode_Release(node);
-
         V_VT(var) = VT_DISPATCH;
         V_DISPATCH(var) = disp;
 
@@ -514,9 +535,8 @@ static HRESULT WINAPI enumvariant_Next(
     /* we need to advance one step more for some reason */
     if (ret_count)
     {
-        node = NULL;
-        IXMLDOMSelection_nextNode(This->selection, &node);
-        if (node) IXMLDOMNode_Release(node);
+        if (This->funcs->next)
+            This->funcs->next(This->outer);
     }
 
     return celt == 0 ? S_OK : S_FALSE;
@@ -557,7 +577,7 @@ static const struct IEnumVARIANTVtbl EnumVARIANTVtbl =
     enumvariant_Clone
 };
 
-static HRESULT create_enumvariant(IXMLDOMSelection *selection, BOOL own, IUnknown **penum)
+static HRESULT create_enumvariant(IUnknown *outer, BOOL own, IEnumVARIANT **penum)
 {
     enumvariant *This;
 
@@ -566,15 +586,16 @@ static HRESULT create_enumvariant(IXMLDOMSelection *selection, BOOL own, IUnknow
 
     This->IEnumVARIANT_iface.lpVtbl = &EnumVARIANTVtbl;
     This->ref = 0;
-    This->selection = selection;
+    This->outer = outer;
     This->own = own;
     This->pos = 0;
+    This->funcs = &selection_enumvariant;
 
     if (This->own)
-        IXMLDOMSelection_AddRef(selection);
+        IUnknown_AddRef(This->outer);
 
-    *penum = (IUnknown*)&This->IEnumVARIANT_iface;
-    IUnknown_AddRef(*penum);
+    *penum = &This->IEnumVARIANT_iface;
+    IEnumVARIANT_AddRef(*penum);
     return S_OK;
 }
 




More information about the wine-cvs mailing list