scrrun: Implement IDictionary get_HashVal (try 2)

Alistair Leslie-Hughes leslie_alistair at hotmail.com
Fri Nov 2 04:49:59 CDT 2012


Hi,
Thanks Piotr for your help.

Changelog:
      scrrun: Implement IDictionary get_HashVal


Best Regards
   Alistair Leslie-Hughes

-------------- next part --------------
>From 63151b5232cad8ce4d911957c3684fa34f43a0a2 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       |   78 +++++++++++++++++++++++++++++-
 dlls/scrrun/tests/dictionary.c |  103 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 179 insertions(+), 2 deletions(-)
 mode change 100644 => 100755 dlls/scrrun/tests/dictionary.c

diff --git a/dlls/scrrun/dictionary.c b/dlls/scrrun/dictionary.c
index b75d23c..7880315 100644
--- a/dlls/scrrun/dictionary.c
+++ b/dlls/scrrun/dictionary.c
@@ -19,6 +19,7 @@
 
 #include "config.h"
 #include <stdarg.h>
+#include <math.h>
 
 #include "windef.h"
 #include "winbase.h"
@@ -43,6 +44,49 @@ 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 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 +336,40 @@ 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;
+    if(V_VT(Key) == VT_BSTR)
+    {
+        V_VT(HashVal) = VT_I4;
+        V_I4(HashVal) = create_hash_val(V_BSTR(Key));
+    }
+    else
+    {
+        VARIANT real;
+
+        real = *Key;
+        if(V_VT(Key) != VT_R8)
+           hr = VariantChangeType(&real, Key, 0, VT_R8);
+
+        if(SUCCEEDED(hr))
+        {
+            float fval = V_R8(&real);
+
+            V_VT(HashVal) = VT_I4;
+            V_I4(HashVal) = 0;
+
+            if(!isinf(fval))
+                V_I4(HashVal) = (*((DWORD*)&fval)) % 1201;
+        }
+        else
+        {
+             FIXME("Unsuported type %s\n", debugstr_variant(Key));
+        }
+    }
+
+    return hr;
 }
 
 
diff --git a/dlls/scrrun/tests/dictionary.c b/dlls/scrrun/tests/dictionary.c
old mode 100644
new mode 100755
index e28bbb1..e1a4ec4
--- a/dlls/scrrun/tests/dictionary.c
+++ b/dlls/scrrun/tests/dictionary.c
@@ -28,6 +28,108 @@
 
 #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);
+
+    V_VT(&key) = VT_R8;
+    V_R8(&key) = INFINITE;
+    check_hash_val(dict, key, 0);
+    VariantClear(&key);
+
+
+    IDictionary_Release(dict);
+    IDispatch_Release(disp);
+}
+
 static void test_interfaces(void)
 {
     static const WCHAR key_add[] = {'a', 0};
@@ -96,6 +198,7 @@ START_TEST(dictionary)
     CoInitialize(NULL);
 
     test_interfaces();
+    test_hash();
 
 
     CoUninitialize();
-- 
1.7.10.4



More information about the wine-patches mailing list