[3/5] propsys: Add basic implementation of PropVariantCompareEx.

Vincent Povirk madewokherd at gmail.com
Thu Sep 13 17:26:47 CDT 2012


-------------- next part --------------
From 402cd16207196ffb8a6c8bb993572f306f6b0724 Mon Sep 17 00:00:00 2001
From: Vincent Povirk <vincent at codeweavers.com>
Date: Thu, 13 Sep 2012 15:54:39 -0500
Subject: [PATCH 3/5] propsys: Add basic implementation of
 PropVariantCompareEx.

---
 dlls/propsys/propvar.c       |   97 +++++++++++++++++++++++++++++++++++++++++-
 dlls/propsys/tests/propsys.c |   15 ++++---
 2 files changed, 104 insertions(+), 8 deletions(-)

diff --git a/dlls/propsys/propvar.c b/dlls/propsys/propvar.c
index 0877801..bbfe8ca 100644
--- a/dlls/propsys/propvar.c
+++ b/dlls/propsys/propvar.c
@@ -284,10 +284,103 @@ HRESULT WINAPI VariantToGUID(const VARIANT *pvar, GUID *guid)
     }
 }
 
+static int isemptyornull(const PROPVARIANT *propvar)
+{
+    if (propvar->vt == VT_EMPTY || propvar->vt == VT_NULL)
+        return 1;
+    if ((propvar->vt & VT_ARRAY) == VT_ARRAY)
+    {
+        int i;
+        for (i=0; i<propvar->u.parray->cDims; i++)
+        {
+            if (propvar->u.parray->rgsabound[i].cElements != 0)
+                break;
+        }
+        return i == propvar->u.parray->cDims;
+    }
+    /* FIXME: vectors, byrefs, errors? */
+    return 0;
+}
+
 INT WINAPI PropVariantCompareEx(REFPROPVARIANT propvar1, REFPROPVARIANT propvar2,
     PROPVAR_COMPARE_UNIT unit, PROPVAR_COMPARE_FLAGS flags)
 {
-    FIXME("%p,%p,%x,%x\n", propvar1, propvar2, unit, flags);
+    const PROPVARIANT *propvar2_converted;
+    PROPVARIANT propvar2_static;
+    HRESULT hr;
+    INT res=-1;
+
+    TRACE("%p,%p,%x,%x\n", propvar1, propvar2, unit, flags);
+
+    if (isemptyornull(propvar1))
+    {
+        if (isemptyornull(propvar2))
+            return 0;
+        return (flags & PVCF_TREATEMPTYASGREATERTHAN) ? 1 : -1;
+    }
+
+    if (isemptyornull(propvar2))
+        return (flags & PVCF_TREATEMPTYASGREATERTHAN) ? -1 : 1;
+
+    if (propvar1->vt != propvar2->vt)
+    {
+        hr = PropVariantChangeType(&propvar2_static, propvar2, 0, propvar1->vt);
+
+        if (FAILED(hr))
+            return -1;
+
+        propvar2_converted = &propvar2_static;
+    }
+    else
+        propvar2_converted = propvar2;
+
+#define CMP_INT_VALUE(var) do { \
+    if (propvar1->u.var > propvar2_converted->u.var) \
+        res = 1; \
+    else if (propvar1->u.var < propvar2_converted->u.var) \
+        res = -1; \
+    else \
+        res = 0; \
+    } while (0)
+
+    switch (propvar1->vt)
+    {
+    case VT_I1:
+        CMP_INT_VALUE(cVal);
+        break;
+    case VT_UI1:
+        CMP_INT_VALUE(bVal);
+        break;
+    case VT_I2:
+        CMP_INT_VALUE(iVal);
+        break;
+    case VT_UI2:
+        CMP_INT_VALUE(uiVal);
+        break;
+    case VT_I4:
+        CMP_INT_VALUE(lVal);
+        break;
+    case VT_UI4:
+        CMP_INT_VALUE(uiVal);
+        break;
+    case VT_I8:
+        CMP_INT_VALUE(hVal.QuadPart);
+        break;
+    case VT_UI8:
+        CMP_INT_VALUE(uhVal.QuadPart);
+        break;
+    case VT_BSTR:
+        /* FIXME: Use string flags. */
+        res = lstrcmpW(propvar1->u.bstrVal, propvar2->u.bstrVal);
+        break;
+    default:
+        FIXME("vartype %d not handled\n", propvar1->vt);
+        res = -1;
+        break;
+    }
+
+    if (propvar2_converted == &propvar2_static)
+        PropVariantClear(&propvar2_static);
 
-    return -1;
+    return res;
 }
diff --git a/dlls/propsys/tests/propsys.c b/dlls/propsys/tests/propsys.c
index 92a6668..789eee8 100644
--- a/dlls/propsys/tests/propsys.c
+++ b/dlls/propsys/tests/propsys.c
@@ -682,28 +682,28 @@ static void test_PropVariantCompare(void)
     str_b.u.bstrVal = SysAllocString(str_bW);
 
     res = PropVariantCompareEx(&empty, &empty, 0, 0);
-    todo_wine ok(res == 0, "res=%i\n", res);
+    ok(res == 0, "res=%i\n", res);
 
     res = PropVariantCompareEx(&empty, &null, 0, 0);
-    todo_wine ok(res == 0, "res=%i\n", res);
+    ok(res == 0, "res=%i\n", res);
 
     res = PropVariantCompareEx(&null, &emptyarray, 0, 0);
-    todo_wine ok(res == 0, "res=%i\n", res);
+    ok(res == 0, "res=%i\n", res);
 
     res = PropVariantCompareEx(&null, &i2_0, 0, 0);
     ok(res == -1, "res=%i\n", res);
 
     res = PropVariantCompareEx(&i2_0, &null, 0, 0);
-    todo_wine ok(res == 1, "res=%i\n", res);
+    ok(res == 1, "res=%i\n", res);
 
     res = PropVariantCompareEx(&null, &i2_0, 0, PVCF_TREATEMPTYASGREATERTHAN);
-    todo_wine ok(res == 1, "res=%i\n", res);
+    ok(res == 1, "res=%i\n", res);
 
     res = PropVariantCompareEx(&i2_0, &null, 0, PVCF_TREATEMPTYASGREATERTHAN);
     ok(res == -1, "res=%i\n", res);
 
     res = PropVariantCompareEx(&i2_2, &i2_0, 0, 0);
-    todo_wine ok(res == 1, "res=%i\n", res);
+    ok(res == 1, "res=%i\n", res);
 
     res = PropVariantCompareEx(&i2_0, &i2_2, 0, 0);
     ok(res == -1, "res=%i\n", res);
@@ -742,6 +742,9 @@ static void test_PropVariantCompare(void)
     res = PropVariantCompareEx(&str_02, &str_b, 0, 0);
     ok(res == -1, "res=%i\n", res);
 
+    res = PropVariantCompareEx(&str_2, &str_02, 0, 0);
+    ok(res == 1, "res=%i\n", res);
+
     res = PropVariantCompareEx(&i4_large, &str_b, 0, 0);
     todo_wine ok(res == -5 /* ??? */, "res=%i\n", res);
 
-- 
1.7.9.5


More information about the wine-patches mailing list