Sync to Wine-0_9_1:
[reactos.git] / reactos / lib / oleaut32 / variant.c
index 9305d3f..953595b 100644 (file)
 
 WINE_DEFAULT_DEBUG_CHANNEL(variant);
 
-const char* wine_vtypes[VT_CLSID] =
+const char* wine_vtypes[VT_CLSID+1] =
 {
   "VT_EMPTY","VT_NULL","VT_I2","VT_I4","VT_R4","VT_R8","VT_CY","VT_DATE",
   "VT_BSTR","VT_DISPATCH","VT_ERROR","VT_BOOL","VT_VARIANT","VT_UNKNOWN",
   "VT_DECIMAL","15","VT_I1","VT_UI1","VT_UI2","VT_UI4","VT_I8","VT_UI8",
   "VT_INT","VT_UINT","VT_VOID","VT_HRESULT","VT_PTR","VT_SAFEARRAY",
-  "VT_CARRAY","VT_USERDEFINED","VT_LPSTR","VT_LPWSTR""32","33","34","35",
+  "VT_CARRAY","VT_USERDEFINED","VT_LPSTR","VT_LPWSTR","32","33","34","35",
   "VT_RECORD","VT_INT_PTR","VT_UINT_PTR","39","40","41","42","43","44","45",
   "46","47","48","49","50","51","52","53","54","55","56","57","58","59","60",
   "61","62","63","VT_FILETIME","VT_BLOB","VT_STREAM","VT_STORAGE",
@@ -2512,11 +2512,14 @@ HRESULT WINAPI VarCmp(LPVARIANT left, LPVARIANT right, LCID lcid, DWORD flags)
 {
     BOOL       lOk        = TRUE;
     BOOL       rOk        = TRUE;
+    BOOL       l_isR      = FALSE;
+    BOOL       r_isR      = FALSE;
     LONGLONG   lVal = -1;
     LONGLONG   rVal = -1;
     VARIANT    rv,lv;
     DWORD      xmask;
     HRESULT    rc;
+    double     lDouble =0.0,rDouble=0.0;
 
     TRACE("(%p->(%s%s),%p->(%s%s),0x%08lx,0x%08lx)\n", left, debugstr_VT(left),
           debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), lcid, flags);
@@ -2537,6 +2540,13 @@ HRESULT WINAPI VarCmp(LPVARIANT left, LPVARIANT right, LCID lcid, DWORD flags)
     }
 
     xmask = (1<<(V_VT(left)&VT_TYPEMASK))|(1<<(V_VT(right)&VT_TYPEMASK));
+    if (xmask & VTBIT_DECIMAL) {
+       rc = VariantChangeType(&lv,left,0,VT_DECIMAL);
+       if (FAILED(rc)) return rc;
+       rc = VariantChangeType(&rv,right,0,VT_DECIMAL);
+       if (FAILED(rc)) return rc;
+        return VarDecCmp(&V_DECIMAL(&lv), &V_DECIMAL(&rv));
+    }
     if (xmask & VTBIT_R8) {
        rc = VariantChangeType(&lv,left,0,VT_R8);
        if (FAILED(rc)) return rc;
@@ -2574,6 +2584,8 @@ HRESULT WINAPI VarCmp(LPVARIANT left, LPVARIANT right, LCID lcid, DWORD flags)
     case VT_UINT : lVal = V_UI4(left); break;
     case VT_BOOL : lVal = V_BOOL(left); break;
     case VT_EMPTY : lVal = 0; break;
+    case VT_R4 : lDouble = V_R4(left); lOk = FALSE; l_isR= TRUE; break;
+    case VT_R8 : lDouble = V_R8(left); lOk = FALSE; l_isR= TRUE; break;
     default: lOk = FALSE;
     }
 
@@ -2589,6 +2601,8 @@ HRESULT WINAPI VarCmp(LPVARIANT left, LPVARIANT right, LCID lcid, DWORD flags)
     case VT_UINT : rVal = V_UI4(right); break;
     case VT_BOOL : rVal = V_BOOL(right); break;
     case VT_EMPTY : rVal = 0; break;
+    case VT_R4 : rDouble = V_R4(right); rOk = FALSE;r_isR= TRUE; break;
+    case VT_R8 : rDouble = V_R8(right); rOk = FALSE;r_isR= TRUE; break;
     default: rOk = FALSE;
     }
 
@@ -2601,7 +2615,47 @@ HRESULT WINAPI VarCmp(LPVARIANT left, LPVARIANT right, LCID lcid, DWORD flags)
             return VARCMP_EQ;
         }
     }
-
+    else if (l_isR && r_isR) {
+        if (lDouble < rDouble) {
+            return VARCMP_LT;
+        } else if (lDouble > rDouble) {
+            return VARCMP_GT;
+        } else {
+            return VARCMP_EQ;
+        }
+    }
+    else if (lOk && r_isR) {
+        if (lVal < rDouble) {
+            return VARCMP_LT;
+        } else if (lVal > rDouble) {
+            return VARCMP_GT;
+        } else {
+            return VARCMP_EQ;
+        }
+    }
+    else if (l_isR && rOk) {
+        if (lDouble < rVal) {
+            return VARCMP_LT;
+        } else if (lDouble > rVal) {
+            return VARCMP_GT;
+        } else {
+            return VARCMP_EQ;
+        }
+    }
+    if ((V_VT(left)&VT_TYPEMASK) == VT_BSTR ) {
+       if(((V_VT(right)&VT_TYPEMASK) == VT_EMPTY ) && !(V_BSTR(left))) {
+           return VARCMP_EQ;
+       } else {
+           return VARCMP_GT;
+       }
+    }
+    if ((V_VT(right)&VT_TYPEMASK) == VT_BSTR ) {
+       if(((V_VT(left)&VT_TYPEMASK) == VT_EMPTY ) && !(V_BSTR(right))) {
+           return VARCMP_EQ;
+       } else {
+           return VARCMP_LT;
+       }
+    }
     /* Dates */
     if ((V_VT(left)&VT_TYPEMASK) == VT_DATE &&
         (V_VT(right)&VT_TYPEMASK) == VT_DATE) {
@@ -2635,7 +2689,9 @@ HRESULT WINAPI VarCmp(LPVARIANT left, LPVARIANT right, LCID lcid, DWORD flags)
             return VARCMP_GT;
         }
     }
-    FIXME("VarCmp partial implementation, doesn't support vt 0x%x / 0x%x\n",V_VT(left), V_VT(right));
+    else if((V_VT(right)&VT_TYPEMASK) == VT_EMPTY)
+        return VARCMP_GT;
+    FIXME("VarCmp partial implementation, doesn't support %s / %s\n",wine_vtypes[V_VT(left)], wine_vtypes[V_VT(right)]);
     return E_FAIL;
 }
 
@@ -3120,7 +3176,7 @@ HRESULT WINAPI VarDiv(LPVARIANT left, LPVARIANT right, LPVARIANT result)
     lvt = V_VT(left)&VT_TYPEMASK;
     rvt = V_VT(right)&VT_TYPEMASK;
     found = FALSE;resvt = VT_VOID;
-    if (((1<<lvt) | (1<<rvt)) & (VTBIT_R4|VTBIT_R8)) {
+    if (((1<<lvt) | (1<<rvt)) & (VTBIT_R4|VTBIT_R8|VTBIT_CY)) {
        found = TRUE;
        resvt = VT_R8;
     }