Nikolay Sivov : scrrun: Implement HashVal property for VT_BSTR case.
Module: wine Branch: master Commit: 37120e758216504276c6e44f08fa78748e38b74e URL: http://source.winehq.org/git/wine.git/?a=commit;h=37120e758216504276c6e44f08... Author: Nikolay Sivov <nsivov(a)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(); }
participants (1)
-
Alexandre Julliard