Nikolay Sivov : ole32/composite: Reimplement Reduce().

Alexandre Julliard julliard at winehq.org
Wed Sep 29 15:54:09 CDT 2021


Module: wine
Branch: master
Commit: f95fe051f0ef6d8032d81befc944f6907b38d793
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=f95fe051f0ef6d8032d81befc944f6907b38d793

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Wed Sep 29 10:23:27 2021 +0300

ole32/composite: Reimplement Reduce().

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ole32/compositemoniker.c | 89 ++++++++++++++-----------------------------
 dlls/ole32/tests/moniker.c    | 19 ++++++++-
 2 files changed, 46 insertions(+), 62 deletions(-)

diff --git a/dlls/ole32/compositemoniker.c b/dlls/ole32/compositemoniker.c
index c6d0d3c47a6..80a1a675766 100644
--- a/dlls/ole32/compositemoniker.c
+++ b/dlls/ole32/compositemoniker.c
@@ -408,76 +408,43 @@ static HRESULT WINAPI CompositeMonikerImpl_BindToStorage(IMoniker *iface, IBindC
     return hr;
 }
 
-/******************************************************************************
- *        CompositeMoniker_Reduce
- ******************************************************************************/
-static HRESULT WINAPI
-CompositeMonikerImpl_Reduce(IMoniker* iface, IBindCtx* pbc, DWORD dwReduceHowFar,
-               IMoniker** ppmkToLeft, IMoniker** ppmkReduced)
+static HRESULT WINAPI CompositeMonikerImpl_Reduce(IMoniker *iface, IBindCtx *pbc, DWORD howfar,
+        IMoniker **toleft, IMoniker **reduced)
 {
-    HRESULT   res;
-    IMoniker *tempMk,*antiMk,*rightMostMk,*leftReducedComposedMk,*rightMostReducedMk;
-    IEnumMoniker *enumMoniker;
-
-    TRACE("(%p,%p,%d,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
-
-    if (ppmkReduced==NULL)
-        return E_POINTER;
-
-    /* This method recursively calls Reduce for each of its component monikers. */
-
-    if (ppmkToLeft==NULL){
+    CompositeMonikerImpl *moniker = impl_from_IMoniker(iface);
+    IMoniker *m, *reduced_left, *reduced_right;
+    BOOL was_reduced;
+    HRESULT hr;
 
-        IMoniker_Enum(iface,FALSE,&enumMoniker);
-        IEnumMoniker_Next(enumMoniker,1,&rightMostMk,NULL);
-        IEnumMoniker_Release(enumMoniker);
+    TRACE("%p, %p, %d, %p, %p.\n", iface, pbc, howfar, toleft, reduced);
 
-        CreateAntiMoniker(&antiMk);
-        IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
-        IMoniker_Release(antiMk);
+    if (!pbc || !reduced)
+        return E_INVALIDARG;
 
-        res = IMoniker_Reduce(rightMostMk,pbc,dwReduceHowFar,&tempMk, ppmkReduced);
-        IMoniker_Release(tempMk);
-        IMoniker_Release(rightMostMk);
+    if (FAILED(hr = IMoniker_Reduce(moniker->left, pbc, howfar, NULL, &reduced_left)))
+        return hr;
 
-        return res;
+    m = moniker->left;
+    if (FAILED(hr = IMoniker_Reduce(moniker->right, pbc, howfar, &m, &reduced_right)))
+    {
+        IMoniker_Release(reduced_left);
+        return hr;
     }
-    else if (*ppmkToLeft==NULL)
 
-        return IMoniker_Reduce(iface,pbc,dwReduceHowFar,NULL,ppmkReduced);
-
-    else{
-
-        /* separate the composite moniker in to left and right moniker */
-        IMoniker_Enum(iface,FALSE,&enumMoniker);
-        IEnumMoniker_Next(enumMoniker,1,&rightMostMk,NULL);
-        IEnumMoniker_Release(enumMoniker);
-
-        CreateAntiMoniker(&antiMk);
-        IMoniker_ComposeWith(iface,antiMk,0,&tempMk);
-        IMoniker_Release(antiMk);
-
-        /* If any of the components  reduces itself, the method returns S_OK and passes back a composite */
-        /* of the reduced components */
-        if (IMoniker_Reduce(rightMostMk,pbc,dwReduceHowFar,NULL,&rightMostReducedMk) &&
-            IMoniker_Reduce(rightMostMk,pbc,dwReduceHowFar,&tempMk,&leftReducedComposedMk) ){
-            IMoniker_Release(tempMk);
-            IMoniker_Release(rightMostMk);
-
-            return CreateGenericComposite(leftReducedComposedMk,rightMostReducedMk,ppmkReduced);
-        }
-        else{
-            /* If no reduction occurred, the method passes back the same moniker and returns MK_S_REDUCED_TO_SELF.*/
-            IMoniker_Release(tempMk);
-            IMoniker_Release(rightMostMk);
-
-            IMoniker_AddRef(iface);
+    if ((was_reduced = (reduced_left != moniker->left || reduced_right != moniker->right)))
+    {
+        hr = CreateGenericComposite(reduced_left, reduced_right, reduced);
+    }
+    else
+    {
+        *reduced = iface;
+        IMoniker_AddRef(*reduced);
+    }
 
-            *ppmkReduced=iface;
+    IMoniker_Release(reduced_left);
+    IMoniker_Release(reduced_right);
 
-            return MK_S_REDUCED_TO_SELF;
-        }
-    }
+    return was_reduced ? hr : MK_S_REDUCED_TO_SELF;
 }
 
 static HRESULT WINAPI CompositeMonikerImpl_ComposeWith(IMoniker *iface, IMoniker *right,
diff --git a/dlls/ole32/tests/moniker.c b/dlls/ole32/tests/moniker.c
index ea58c09356e..7e4a42a0ee6 100644
--- a/dlls/ole32/tests/moniker.c
+++ b/dlls/ole32/tests/moniker.c
@@ -3439,7 +3439,6 @@ todo_wine
     ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
 
     hr = IMoniker_GetTimeOfLastChange(moniker, bindctx, moniker1, &ft);
-todo_wine
     ok(hr == MK_E_NOTBINDABLE, "Unexpected hr %#x.\n", hr);
 
     hr = IRunningObjectTable_Revoke(rot, cookie);
@@ -3629,6 +3628,24 @@ todo_wine {
 
     IMoniker_Release(moniker);
 
+    /* Reduce() */
+    hr = create_moniker_from_desc("CI1I2", &moniker);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    hr = IMoniker_Reduce(moniker, NULL, MKRREDUCE_ALL, NULL, NULL);
+    ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
+    hr = IMoniker_Reduce(moniker, bindctx, MKRREDUCE_ALL, NULL, NULL);
+    ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
+    hr = IMoniker_Reduce(moniker, NULL, MKRREDUCE_ALL, NULL, &moniker2);
+    ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
+
+    hr = IMoniker_Reduce(moniker, bindctx, MKRREDUCE_ALL, NULL, &moniker2);
+    ok(hr == MK_S_REDUCED_TO_SELF, "Unexpected hr %#x.\n", hr);
+    ok(moniker2 == moniker, "Unexpected object.\n");
+    IMoniker_Release(moniker2);
+
+    IMoniker_Release(moniker);
+
     IBindCtx_Release(bindctx);
 }
 




More information about the wine-cvs mailing list