scrrun: Implement IDictionary get_HashVal (try 3)
Alistair Leslie-Hughes
leslie_alistair at hotmail.com
Thu Nov 8 03:31:07 CST 2012
Hi,
Thanks Piotr for your help.
Changelog:
scrrun: Implement IDictionary get_HashVal
Best Regards
Alistair Leslie-Hughes
-------------- next part --------------
>From ef149db46bbee9d49d78fc77a22f94600dd24577 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 | 80 ++++++++++++++++++++++++++++++++-
dlls/scrrun/tests/dictionary.c | 97 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 175 insertions(+), 2 deletions(-)
diff --git a/dlls/scrrun/dictionary.c b/dlls/scrrun/dictionary.c
index b75d23c..c6240ee 100644
--- a/dlls/scrrun/dictionary.c
+++ b/dlls/scrrun/dictionary.c
@@ -18,7 +18,10 @@
#define COBJMACROS
#include "config.h"
+#include "wine/port.h"
+
#include <stdarg.h>
+#include <math.h>
#include "windef.h"
#include "winbase.h"
@@ -43,6 +46,59 @@ 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 LONG create_hash_val_float(float fval)
+{
+ TRACE("val = %f\n", fval);
+
+ if(isinf(fval))
+ return 0;
+
+ return (*((DWORD*)&fval)) % 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 +348,30 @@ 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;
+ V_VT(HashVal) = VT_I4;
+ V_I4(HashVal) = 0;
+
+ switch(V_VT(Key))
+ {
+ case VT_BSTR:
+ V_I4(HashVal) = create_hash_val(V_BSTR(Key));
+ break;
+ case VT_R8:
+ V_I4(HashVal) = create_hash_val_float(V_R8(Key));
+ break;
+ case VT_I4:
+ V_I4(HashVal) = create_hash_val_float(V_I4(Key));
+ break;
+ default:
+ FIXME("Unsuported type %s\n", debugstr_variant(Key));
+ hr = E_FAIL;
+ }
+
+ return hr;
}
diff --git a/dlls/scrrun/tests/dictionary.c b/dlls/scrrun/tests/dictionary.c
index e28bbb1..f7590e9 100644
--- a/dlls/scrrun/tests/dictionary.c
+++ b/dlls/scrrun/tests/dictionary.c
@@ -28,6 +28,102 @@
#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);
+
+ IDictionary_Release(dict);
+ IDispatch_Release(disp);
+}
+
static void test_interfaces(void)
{
static const WCHAR key_add[] = {'a', 0};
@@ -96,6 +192,7 @@ START_TEST(dictionary)
CoInitialize(NULL);
test_interfaces();
+ test_hash();
CoUninitialize();
--
1.7.9.5
More information about the wine-patches
mailing list