scrrun: Implement IDictionary get_HashVal (try 3)

Alistair Leslie-Hughes leslie_alistair at hotmail.com
Thu Nov 8 03:31:07 CST 2012


Hi,
Thanks Piotr for your help.

Changelog:
       scrrun: Implement IDictionary get_HashVal


Best Regards
    Alistair Leslie-Hughes


-------------- next part --------------
>From ef149db46bbee9d49d78fc77a22f94600dd24577 Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair at hotmail.com>
Date: Mon, 29 Oct 2012 16:05:06 +1100
Subject: [PATCH] Implement IDictionary get_HashVal
To: wine-patches <wine-patches at winehq.org>

---
 dlls/scrrun/dictionary.c       |   80 ++++++++++++++++++++++++++++++++-
 dlls/scrrun/tests/dictionary.c |   97 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 175 insertions(+), 2 deletions(-)

diff --git a/dlls/scrrun/dictionary.c b/dlls/scrrun/dictionary.c
index b75d23c..c6240ee 100644
--- a/dlls/scrrun/dictionary.c
+++ b/dlls/scrrun/dictionary.c
@@ -18,7 +18,10 @@
 #define COBJMACROS
 
 #include "config.h"
+#include "wine/port.h"
+
 #include <stdarg.h>
+#include <math.h>
 
 #include "windef.h"
 #include "winbase.h"
@@ -43,6 +46,59 @@ static inline dictionary *impl_from_IDictionary(IDictionary *iface)
     return CONTAINING_RECORD(iface, dictionary, IDictionary_iface);
 }
 
+static LONG create_hash_val(BSTR name)
+{
+    LONG hash = 0;
+    int len = SysStringLen(name);
+    int i;
+
+    for(i =0; i < len; i++)
+    {
+          hash += (hash <<4) + name[i];
+    }
+
+    return hash % 1201;
+}
+
+static LONG create_hash_val_float(float fval)
+{
+    TRACE("val = %f\n", fval);
+
+    if(isinf(fval))
+        return 0;
+
+    return (*((DWORD*)&fval)) % 1201;
+}
+
+static const char *debugstr_variant(const VARIANT *v)
+{
+    if(!v)
+        return "(null)";
+
+    switch(V_VT(v)) {
+    case VT_EMPTY:
+        return "{VT_EMPTY}";
+    case VT_NULL:
+        return "{VT_NULL}";
+    case VT_I4:
+        return wine_dbg_sprintf("{VT_I4: %d}", V_I4(v));
+    case VT_UI4:
+        return wine_dbg_sprintf("{VT_UI4: %u}", V_UI4(v));
+    case VT_R8:
+        return wine_dbg_sprintf("{VT_R8: %lf}", V_R8(v));
+    case VT_BSTR:
+        return wine_dbg_sprintf("{VT_BSTR: %s}", debugstr_w(V_BSTR(v)));
+    case VT_DISPATCH:
+        return wine_dbg_sprintf("{VT_DISPATCH: %p}", V_DISPATCH(v));
+    case VT_BOOL:
+        return wine_dbg_sprintf("{VT_BOOL: %x}", V_BOOL(v));
+    case VT_ARRAY|VT_VARIANT:
+        return "{VT_ARRAY|VT_VARIANT: ...}";
+    default:
+        return wine_dbg_sprintf("{vt %d}", V_VT(v));
+    }
+}
+
 static HRESULT WINAPI dictionary_QueryInterface(IDictionary *iface, REFIID riid, void **obj)
 {
     dictionary *This = impl_from_IDictionary(iface);
@@ -292,10 +348,30 @@ static HRESULT WINAPI dictionary__NewEnum(IDictionary *iface, IUnknown **ppunk)
 static HRESULT WINAPI dictionary_get_HashVal(IDictionary *iface, VARIANT *Key, VARIANT *HashVal)
 {
     dictionary *This = impl_from_IDictionary(iface);
+    HRESULT hr = S_OK;
 
-    FIXME("(%p)->(%p %p)\n", This, Key, HashVal);
+    TRACE("(%p)->(%s %s)\n", This, debugstr_variant(Key), debugstr_variant(HashVal));
 
-    return E_NOTIMPL;
+    V_VT(HashVal) = VT_I4;
+    V_I4(HashVal) = 0;
+
+    switch(V_VT(Key))
+    {
+        case VT_BSTR:
+            V_I4(HashVal) = create_hash_val(V_BSTR(Key));
+            break;
+        case VT_R8:
+            V_I4(HashVal) = create_hash_val_float(V_R8(Key));
+            break;
+        case VT_I4:
+            V_I4(HashVal) = create_hash_val_float(V_I4(Key));
+            break;
+        default:
+             FIXME("Unsuported type %s\n", debugstr_variant(Key));
+             hr = E_FAIL;
+    }
+
+    return hr;
 }
 
 
diff --git a/dlls/scrrun/tests/dictionary.c b/dlls/scrrun/tests/dictionary.c
index e28bbb1..f7590e9 100644
--- a/dlls/scrrun/tests/dictionary.c
+++ b/dlls/scrrun/tests/dictionary.c
@@ -28,6 +28,102 @@
 
 #include "scrrun.h"
 
+#define check_hash_val(d, k, r) _check_hash_val(__LINE__, d, k, r)
+static void _check_hash_val(unsigned line, IDictionary *dict, VARIANT key, LONG result)
+{
+    VARIANT value;
+    HRESULT hr;
+
+    VariantInit(&value);
+
+    hr = IDictionary_get_HashVal(dict, &key, &value);
+    ok_(__FILE__,line)(hr == S_OK, "got 0x%08x, expected 0x%08x\n", hr, S_OK);
+    ok_(__FILE__,line)(V_I4(&value) == result, "got %d, expected %d\n", V_I4(&value), result);
+    ok_(__FILE__,line)(hr == S_OK, "GetCurrentMoniker failed: %08x\n", hr);
+
+    VariantClear(&value);
+}
+
+
+
+static void test_hash(void)
+{
+    static const WCHAR key_a[] = {'a', 0};
+    static const WCHAR key_aa[] = {'a', 'a', 0};
+    static const WCHAR key_b[] = {'b', 0};
+    static const WCHAR key_11[] = {'1', '1', 0};
+    VARIANT key;
+    HRESULT hr;
+
+    IDispatch *disp;
+    IDictionary *dict;
+
+    hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
+            &IID_IDispatch, (void**)&disp);
+    if(FAILED(hr)) {
+        win_skip("Could not create FileSystem object: %08x\n", hr);
+        return;
+    }
+
+    VariantInit(&key);
+
+    hr = IDispatch_QueryInterface(disp, &IID_IDictionary, (void**)&dict);
+    ok(hr == S_OK, "got 0x%08x, expected 0x%08x\n", hr, S_OK);
+
+    V_VT(&key) = VT_BSTR;
+    V_BSTR(&key) = SysAllocString(key_a);
+    check_hash_val(dict, key, 97);
+    VariantClear(&key);
+
+    V_VT(&key) = VT_BSTR;
+    V_BSTR(&key) = SysAllocString(key_b);
+    check_hash_val(dict, key, 98);
+    VariantClear(&key);
+
+    V_VT(&key) = VT_BSTR;
+    V_BSTR(&key) = SysAllocString(key_aa);
+    check_hash_val(dict, key, 545);
+    VariantClear(&key);
+
+    V_VT(&key) = VT_BSTR;
+    V_BSTR(&key) = SysAllocString(key_11);
+    check_hash_val(dict, key, 882);
+    VariantClear(&key);
+
+    V_VT(&key) = VT_I4;
+    V_I4(&key) = 1;
+    check_hash_val(dict, key, 161);
+    VariantClear(&key);
+
+    V_VT(&key) = VT_I4;
+    V_I4(&key) = 2;
+    check_hash_val(dict, key, 985);
+    VariantClear(&key);
+
+    V_VT(&key) = VT_I4;
+    V_I4(&key) = 3;
+    check_hash_val(dict, key, 196);
+    VariantClear(&key);
+
+    V_VT(&key) = VT_I4;
+    V_I4(&key) = 11;
+    check_hash_val(dict, key, 540);
+    VariantClear(&key);
+
+    V_VT(&key) = VT_R8;
+    V_R8(&key) = 11.0f;
+    check_hash_val(dict, key, 540);
+    VariantClear(&key);
+
+    V_VT(&key) = VT_R8;
+    V_R8(&key) = 11.1f;
+    check_hash_val(dict, key, 911);
+    VariantClear(&key);
+
+    IDictionary_Release(dict);
+    IDispatch_Release(disp);
+}
+
 static void test_interfaces(void)
 {
     static const WCHAR key_add[] = {'a', 0};
@@ -96,6 +192,7 @@ START_TEST(dictionary)
     CoInitialize(NULL);
 
     test_interfaces();
+    test_hash();
 
 
     CoUninitialize();
-- 
1.7.9.5



More information about the wine-patches mailing list