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