Module: wine Branch: master Commit: 37120e758216504276c6e44f08fa78748e38b74e URL: http://source.winehq.org/git/wine.git/?a=commit;h=37120e758216504276c6e44f08...
Author: Nikolay Sivov nsivov@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(); }