Nikolay Sivov : scrrun: Implement HashVal property for VT_BSTR case.

Alexandre Julliard julliard at wine.codeweavers.com
Wed Feb 25 09:57:01 CST 2015


Module: wine
Branch: master
Commit: 37120e758216504276c6e44f08fa78748e38b74e
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=37120e758216504276c6e44f08fa78748e38b74e

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Tue Feb 24 23:27:17 2015 +0300

scrrun: Implement HashVal property for VT_BSTR case.

---

 dlls/scrrun/dictionary.c       | 37 ++++++++++++++--
 dlls/scrrun/tests/Makefile.in  |  2 +-
 dlls/scrrun/tests/dictionary.c | 97 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 131 insertions(+), 5 deletions(-)

diff --git a/dlls/scrrun/dictionary.c b/dlls/scrrun/dictionary.c
index c1122fa..d615426 100644
--- a/dlls/scrrun/dictionary.c
+++ b/dlls/scrrun/dictionary.c
@@ -28,6 +28,7 @@
 #include "scrrun_private.h"
 
 #include "wine/debug.h"
+#include "wine/unicode.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(scrrun);
 
@@ -290,15 +291,43 @@ static HRESULT WINAPI dictionary__NewEnum(IDictionary *iface, IUnknown **ppunk)
     return E_NOTIMPL;
 }
 
-static HRESULT WINAPI dictionary_get_HashVal(IDictionary *iface, VARIANT *Key, VARIANT *HashVal)
+static DWORD get_str_hash(const WCHAR *str, CompareMethod method)
 {
-    dictionary *This = impl_from_IDictionary(iface);
+    DWORD hash = 0;
 
-    FIXME("(%p)->(%p %p)\n", This, Key, HashVal);
+    if (str) {
+        while (*str) {
+            WCHAR ch;
 
-    return E_NOTIMPL;
+            ch = (method == TextCompare || method == DatabaseCompare) ? tolowerW(*str) : *str;
+
+            hash += (hash << 4) + ch;
+            str++;
+        }
+    }
+
+    return hash % 1201;
 }
 
+static HRESULT WINAPI dictionary_get_HashVal(IDictionary *iface, VARIANT *key, VARIANT *hash)
+{
+    dictionary *This = impl_from_IDictionary(iface);
+
+    TRACE("(%p)->(%s %p)\n", This, debugstr_variant(key), hash);
+
+    V_VT(hash) = VT_I4;
+    switch (V_VT(key))
+    {
+    case VT_BSTR:
+        V_I4(hash) = get_str_hash(V_BSTR(key), This->method);
+        break;
+    default:
+        FIXME("not implemented for type %d\n", V_VT(key));
+        return E_NOTIMPL;
+    }
+
+    return S_OK;
+}
 
 static const struct IDictionaryVtbl dictionary_vtbl =
 {
diff --git a/dlls/scrrun/tests/Makefile.in b/dlls/scrrun/tests/Makefile.in
index 5460fa4..e9eccb6 100644
--- a/dlls/scrrun/tests/Makefile.in
+++ b/dlls/scrrun/tests/Makefile.in
@@ -1,5 +1,5 @@
 TESTDLL   = scrrun.dll
-IMPORTS   = ole32 shlwapi uuid oleaut32
+IMPORTS   = ole32 shlwapi uuid oleaut32 user32
 
 C_SRCS = \
 	dictionary.c \
diff --git a/dlls/scrrun/tests/dictionary.c b/dlls/scrrun/tests/dictionary.c
index cad387d..1cb60b6 100644
--- a/dlls/scrrun/tests/dictionary.c
+++ b/dlls/scrrun/tests/dictionary.c
@@ -124,6 +124,102 @@ if (0) /* crashes on native */
     IDictionary_Release(dict);
 }
 
+static DWORD get_str_hash(const WCHAR *str, CompareMethod method)
+{
+    DWORD hash = 0;
+
+    while (*str) {
+        WCHAR ch;
+
+        if (method == TextCompare || method == DatabaseCompare)
+            ch = PtrToInt(CharLowerW(IntToPtr(*str)));
+        else
+            ch = *str;
+
+        hash += (hash << 4) + ch;
+        str++;
+    }
+
+    return hash % 1201;
+}
+
+static void test_hash_value(void)
+{
+    /* string test data */
+    static const WCHAR str_hash_tests[][10] = {
+        {'a','b','c','d',0},
+        {'a','B','C','d','1',0},
+        {'1','2','3',0},
+        {'A',0},
+        {'a',0},
+        { 0 }
+    };
+
+    IDictionary *dict;
+    VARIANT key, hash;
+    HRESULT hr;
+    unsigned i;
+
+    hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
+            &IID_IDictionary, (void**)&dict);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    V_VT(&key) = VT_BSTR;
+    V_BSTR(&key) = NULL;
+    VariantInit(&hash);
+    hr = IDictionary_get_HashVal(dict, &key, &hash);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
+    ok(V_I4(&hash) == 0, "got %d\n", V_I4(&hash));
+
+    for (i = 0; i < sizeof(str_hash_tests)/sizeof(str_hash_tests[0]); i++) {
+        DWORD expected = get_str_hash(str_hash_tests[i], BinaryCompare);
+
+        hr = IDictionary_put_CompareMode(dict, BinaryCompare);
+        ok(hr == S_OK, "got 0x%08x\n", hr);
+
+        V_VT(&key) = VT_BSTR;
+        V_BSTR(&key) = SysAllocString(str_hash_tests[i]);
+        VariantInit(&hash);
+        hr = IDictionary_get_HashVal(dict, &key, &hash);
+        ok(hr == S_OK, "got 0x%08x\n", hr);
+        ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
+        ok(V_I4(&hash) == expected, "%d: binary mode: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
+            expected);
+        VariantClear(&key);
+
+        expected = get_str_hash(str_hash_tests[i], TextCompare);
+        hr = IDictionary_put_CompareMode(dict, TextCompare);
+        ok(hr == S_OK, "got 0x%08x\n", hr);
+
+        V_VT(&key) = VT_BSTR;
+        V_BSTR(&key) = SysAllocString(str_hash_tests[i]);
+        VariantInit(&hash);
+        hr = IDictionary_get_HashVal(dict, &key, &hash);
+        ok(hr == S_OK, "got 0x%08x\n", hr);
+        ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
+        ok(V_I4(&hash) == expected, "%d: text mode: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
+            expected);
+        VariantClear(&key);
+
+        expected = get_str_hash(str_hash_tests[i], DatabaseCompare);
+        hr = IDictionary_put_CompareMode(dict, DatabaseCompare);
+        ok(hr == S_OK, "got 0x%08x\n", hr);
+
+        V_VT(&key) = VT_BSTR;
+        V_BSTR(&key) = SysAllocString(str_hash_tests[i]);
+        VariantInit(&hash);
+        hr = IDictionary_get_HashVal(dict, &key, &hash);
+        ok(hr == S_OK, "got 0x%08x\n", hr);
+        ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
+        ok(V_I4(&hash) == expected, "%d: db mode: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
+            expected);
+        VariantClear(&key);
+    }
+
+    IDictionary_Release(dict);
+}
+
 START_TEST(dictionary)
 {
     IDispatch *disp;
@@ -142,6 +238,7 @@ START_TEST(dictionary)
 
     test_interfaces();
     test_comparemode();
+    test_hash_value();
 
     CoUninitialize();
 }




More information about the wine-cvs mailing list