Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
5189dc41
Commit
5189dc41
authored
Mar 21, 2015
by
Nikolay Sivov
Committed by
Alexandre Julliard
Mar 23, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
scrrun: Added support for interface pointers as keys for dictionary.
parent
c5dda71c
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
242 additions
and
6 deletions
+242
-6
dictionary.c
dlls/scrrun/dictionary.c
+31
-3
dictionary.c
dlls/scrrun/tests/dictionary.c
+211
-3
No files found.
dlls/scrrun/dictionary.c
View file @
5189dc41
...
@@ -37,7 +37,8 @@
...
@@ -37,7 +37,8 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
scrrun
);
WINE_DEFAULT_DEBUG_CHANNEL
(
scrrun
);
#define BUCKET_COUNT 509
#define BUCKET_COUNT 509
#define DICT_HASH_MOD 1201
/* Implementation details
/* Implementation details
...
@@ -752,12 +753,17 @@ static DWORD get_str_hash(const WCHAR *str, CompareMethod method)
...
@@ -752,12 +753,17 @@ static DWORD get_str_hash(const WCHAR *str, CompareMethod method)
}
}
}
}
return
hash
%
1201
;
return
hash
%
DICT_HASH_MOD
;
}
}
static
DWORD
get_num_hash
(
FLOAT
num
)
static
DWORD
get_num_hash
(
FLOAT
num
)
{
{
return
(
*
((
DWORD
*
)
&
num
))
%
1201
;
return
(
*
((
DWORD
*
)
&
num
))
%
DICT_HASH_MOD
;
}
static
DWORD
get_ptr_hash
(
void
*
ptr
)
{
return
PtrToUlong
(
ptr
)
%
DICT_HASH_MOD
;
}
}
static
HRESULT
WINAPI
dictionary_get_HashVal
(
IDictionary
*
iface
,
VARIANT
*
key
,
VARIANT
*
hash
)
static
HRESULT
WINAPI
dictionary_get_HashVal
(
IDictionary
*
iface
,
VARIANT
*
key
,
VARIANT
*
hash
)
...
@@ -782,6 +788,28 @@ static HRESULT WINAPI dictionary_get_HashVal(IDictionary *iface, VARIANT *key, V
...
@@ -782,6 +788,28 @@ static HRESULT WINAPI dictionary_get_HashVal(IDictionary *iface, VARIANT *key, V
case
VT_I4
:
case
VT_I4
:
V_I4
(
hash
)
=
get_num_hash
(
V_I4
(
key
));
V_I4
(
hash
)
=
get_num_hash
(
V_I4
(
key
));
break
;
break
;
case
VT_UNKNOWN
|
VT_BYREF
:
case
VT_DISPATCH
|
VT_BYREF
:
case
VT_UNKNOWN
:
case
VT_DISPATCH
:
{
IUnknown
*
src
=
(
V_VT
(
key
)
&
VT_BYREF
)
?
*
V_UNKNOWNREF
(
key
)
:
V_UNKNOWN
(
key
);
IUnknown
*
unk
=
NULL
;
if
(
!
src
)
{
V_I4
(
hash
)
=
0
;
return
S_OK
;
}
IUnknown_QueryInterface
(
src
,
&
IID_IUnknown
,
(
void
**
)
&
unk
);
if
(
!
unk
)
{
V_I4
(
hash
)
=
~
0u
;
return
CTL_E_ILLEGALFUNCTIONCALL
;
}
V_I4
(
hash
)
=
get_ptr_hash
(
unk
);
IUnknown_Release
(
unk
);
break
;
}
case
VT_R4
:
case
VT_R4
:
case
VT_R8
:
case
VT_R8
:
{
{
...
...
dlls/scrrun/tests/dictionary.c
View file @
5189dc41
/*
/*
* Copyright (C) 2012 Alistair Leslie-Hughes
* Copyright (C) 2012 Alistair Leslie-Hughes
* Copyright 2015 Nikolay Sivov for CodeWeavers
*
*
* This library is free software; you can redistribute it and/or
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* modify it under the terms of the GNU Lesser General Public
...
@@ -160,6 +161,11 @@ static DWORD get_num_hash(FLOAT num)
...
@@ -160,6 +161,11 @@ static DWORD get_num_hash(FLOAT num)
return
(
*
((
DWORD
*
)
&
num
))
%
1201
;
return
(
*
((
DWORD
*
)
&
num
))
%
1201
;
}
}
static
DWORD
get_ptr_hash
(
void
*
ptr
)
{
return
PtrToUlong
(
ptr
)
%
1201
;
}
typedef
union
typedef
union
{
{
struct
struct
...
@@ -183,6 +189,110 @@ typedef union
...
@@ -183,6 +189,110 @@ typedef union
double
d
;
double
d
;
}
R8_FIELDS
;
}
R8_FIELDS
;
static
HRESULT
WINAPI
test_unk_QI
(
IUnknown
*
iface
,
REFIID
riid
,
void
**
obj
)
{
if
(
IsEqualIID
(
riid
,
&
IID_IUnknown
))
{
*
obj
=
iface
;
return
S_OK
;
}
ok
(
0
,
"unexpected %s
\n
"
,
wine_dbgstr_guid
(
riid
));
*
obj
=
NULL
;
return
E_NOINTERFACE
;
}
static
HRESULT
WINAPI
test_unk_no_QI
(
IUnknown
*
iface
,
REFIID
riid
,
void
**
obj
)
{
*
obj
=
NULL
;
return
E_NOINTERFACE
;
}
static
ULONG
WINAPI
test_unk_AddRef
(
IUnknown
*
iface
)
{
ok
(
0
,
"unxpected
\n
"
);
return
2
;
}
static
ULONG
WINAPI
test_unk_Release
(
IUnknown
*
iface
)
{
return
1
;
}
static
const
IUnknownVtbl
test_unk_vtbl
=
{
test_unk_QI
,
test_unk_AddRef
,
test_unk_Release
};
static
const
IUnknownVtbl
test_unk_no_vtbl
=
{
test_unk_no_QI
,
test_unk_AddRef
,
test_unk_Release
};
static
HRESULT
WINAPI
test_disp_QI
(
IDispatch
*
iface
,
REFIID
riid
,
void
**
obj
)
{
if
(
IsEqualIID
(
riid
,
&
IID_IDispatch
)
||
IsEqualIID
(
riid
,
&
IID_IUnknown
))
{
*
obj
=
iface
;
return
S_OK
;
}
ok
(
0
,
"unexpected %s
\n
"
,
wine_dbgstr_guid
(
riid
));
*
obj
=
NULL
;
return
E_NOINTERFACE
;
}
static
ULONG
WINAPI
test_disp_AddRef
(
IDispatch
*
iface
)
{
ok
(
0
,
"unxpected
\n
"
);
return
2
;
}
static
ULONG
WINAPI
test_disp_Release
(
IDispatch
*
iface
)
{
return
1
;
}
static
HRESULT
WINAPI
test_disp_GetTypeInfoCount
(
IDispatch
*
iface
,
UINT
*
count
)
{
ok
(
0
,
"unexpected call
\n
"
);
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
test_disp_GetTypeInfo
(
IDispatch
*
iface
,
UINT
index
,
LCID
lcid
,
ITypeInfo
**
ti
)
{
ok
(
0
,
"unexpected call
\n
"
);
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
test_disp_GetIDsOfNames
(
IDispatch
*
iface
,
REFIID
riid
,
LPOLESTR
*
names
,
UINT
name_count
,
LCID
lcid
,
DISPID
*
dispid
)
{
ok
(
0
,
"unexpected call
\n
"
);
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
test_disp_Invoke
(
IDispatch
*
iface
,
DISPID
dispid
,
REFIID
riid
,
LCID
lcid
,
WORD
flags
,
DISPPARAMS
*
params
,
VARIANT
*
result
,
EXCEPINFO
*
excepinfo
,
UINT
*
arg_err
)
{
ok
(
0
,
"unexpected call
\n
"
);
return
E_NOTIMPL
;
}
static
const
IDispatchVtbl
test_disp_vtbl
=
{
test_disp_QI
,
test_disp_AddRef
,
test_disp_Release
,
test_disp_GetTypeInfoCount
,
test_disp_GetTypeInfo
,
test_disp_GetIDsOfNames
,
test_disp_Invoke
};
static
IUnknown
test_unk
=
{
&
test_unk_vtbl
};
static
IUnknown
test_unk2
=
{
&
test_unk_no_vtbl
};
static
IDispatch
test_disp
=
{
&
test_disp_vtbl
};
static
void
test_hash_value
(
void
)
static
void
test_hash_value
(
void
)
{
{
/* string test data */
/* string test data */
...
@@ -205,6 +315,9 @@ static void test_hash_value(void)
...
@@ -205,6 +315,9 @@ static void test_hash_value(void)
IDictionary
*
dict
;
IDictionary
*
dict
;
VARIANT
key
,
hash
;
VARIANT
key
,
hash
;
IDispatch
*
disp
;
DWORD
expected
;
IUnknown
*
unk
;
R8_FIELDS
fx8
;
R8_FIELDS
fx8
;
R4_FIELDS
fx4
;
R4_FIELDS
fx4
;
HRESULT
hr
;
HRESULT
hr
;
...
@@ -223,7 +336,7 @@ static void test_hash_value(void)
...
@@ -223,7 +336,7 @@ static void test_hash_value(void)
ok
(
V_I4
(
&
hash
)
==
0
,
"got %d
\n
"
,
V_I4
(
&
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
++
)
{
for
(
i
=
0
;
i
<
sizeof
(
str_hash_tests
)
/
sizeof
(
str_hash_tests
[
0
]);
i
++
)
{
DWORD
expected
=
get_str_hash
(
str_hash_tests
[
i
],
BinaryCompare
);
expected
=
get_str_hash
(
str_hash_tests
[
i
],
BinaryCompare
);
hr
=
IDictionary_put_CompareMode
(
dict
,
BinaryCompare
);
hr
=
IDictionary_put_CompareMode
(
dict
,
BinaryCompare
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
...
@@ -316,7 +429,7 @@ static void test_hash_value(void)
...
@@ -316,7 +429,7 @@ static void test_hash_value(void)
ok
(
V_I4
(
&
hash
)
==
~
0u
,
"got hash 0x%08x
\n
"
,
V_I4
(
&
hash
));
ok
(
V_I4
(
&
hash
)
==
~
0u
,
"got hash 0x%08x
\n
"
,
V_I4
(
&
hash
));
for
(
i
=
0
;
i
<
sizeof
(
int_hash_tests
)
/
sizeof
(
int_hash_tests
[
0
]);
i
++
)
{
for
(
i
=
0
;
i
<
sizeof
(
int_hash_tests
)
/
sizeof
(
int_hash_tests
[
0
]);
i
++
)
{
DWORD
expected
=
get_num_hash
(
int_hash_tests
[
i
]);
expected
=
get_num_hash
(
int_hash_tests
[
i
]);
V_VT
(
&
key
)
=
VT_I2
;
V_VT
(
&
key
)
=
VT_I2
;
V_I2
(
&
key
)
=
int_hash_tests
[
i
];
V_I2
(
&
key
)
=
int_hash_tests
[
i
];
...
@@ -401,7 +514,7 @@ static void test_hash_value(void)
...
@@ -401,7 +514,7 @@ static void test_hash_value(void)
ok
(
V_I4
(
&
hash
)
==
0
,
"got hash 0x%08x
\n
"
,
V_I4
(
&
hash
));
ok
(
V_I4
(
&
hash
)
==
0
,
"got hash 0x%08x
\n
"
,
V_I4
(
&
hash
));
for
(
i
=
0
;
i
<
sizeof
(
float_hash_tests
)
/
sizeof
(
float_hash_tests
[
0
]);
i
++
)
{
for
(
i
=
0
;
i
<
sizeof
(
float_hash_tests
)
/
sizeof
(
float_hash_tests
[
0
]);
i
++
)
{
DWORD
expected
=
get_num_hash
(
float_hash_tests
[
i
]);
expected
=
get_num_hash
(
float_hash_tests
[
i
]);
V_VT
(
&
key
)
=
VT_R4
;
V_VT
(
&
key
)
=
VT_R4
;
V_R4
(
&
key
)
=
float_hash_tests
[
i
];
V_R4
(
&
key
)
=
float_hash_tests
[
i
];
...
@@ -422,6 +535,101 @@ static void test_hash_value(void)
...
@@ -422,6 +535,101 @@ static void test_hash_value(void)
expected
);
expected
);
}
}
/* interface pointers as keys */
V_VT
(
&
key
)
=
VT_UNKNOWN
;
V_UNKNOWN
(
&
key
)
=
0
;
VariantInit
(
&
hash
);
V_I4
(
&
hash
)
=
1
;
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 hash 0x%08x, expected 0
\n
"
,
V_I4
(
&
hash
));
/* QI doesn't work */
V_VT
(
&
key
)
=
VT_UNKNOWN
;
V_UNKNOWN
(
&
key
)
=
&
test_unk2
;
VariantInit
(
&
hash
);
expected
=
get_ptr_hash
(
&
test_unk2
);
hr
=
IDictionary_get_HashVal
(
dict
,
&
key
,
&
hash
);
ok
(
hr
==
CTL_E_ILLEGALFUNCTIONCALL
||
broken
(
hr
==
S_OK
)
/* win2k */
,
"got 0x%08x
\n
"
,
hr
);
ok
(
V_VT
(
&
hash
)
==
VT_I4
,
"got %d
\n
"
,
V_VT
(
&
hash
));
ok
(
V_I4
(
&
hash
)
==
~
0u
,
"got hash 0x%08x, expected 0x%08x
\n
"
,
V_I4
(
&
hash
),
expected
);
V_VT
(
&
key
)
=
VT_UNKNOWN
;
V_UNKNOWN
(
&
key
)
=
&
test_unk
;
VariantInit
(
&
hash
);
expected
=
get_ptr_hash
(
&
test_unk
);
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
,
"got hash 0x%08x, expected 0x%08x
\n
"
,
V_I4
(
&
hash
),
expected
);
/* interface without IDispatch support */
V_VT
(
&
key
)
=
VT_DISPATCH
;
V_DISPATCH
(
&
key
)
=
(
IDispatch
*
)
&
test_unk
;
VariantInit
(
&
hash
);
expected
=
get_ptr_hash
(
&
test_unk
);
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
,
"got hash 0x%08x, expected 0x%08x
\n
"
,
V_I4
(
&
hash
),
expected
);
V_VT
(
&
key
)
=
VT_DISPATCH
;
V_DISPATCH
(
&
key
)
=
&
test_disp
;
VariantInit
(
&
hash
);
expected
=
get_ptr_hash
(
&
test_disp
);
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
,
"got hash 0x%08x, expected 0x%08x
\n
"
,
V_I4
(
&
hash
),
expected
);
/* same with BYREF */
if
(
0
)
{
/* crashes on native */
V_VT
(
&
key
)
=
VT_UNKNOWN
|
VT_BYREF
;
V_UNKNOWNREF
(
&
key
)
=
0
;
hr
=
IDictionary_get_HashVal
(
dict
,
&
key
,
&
hash
);
}
unk
=
NULL
;
V_VT
(
&
key
)
=
VT_UNKNOWN
|
VT_BYREF
;
V_UNKNOWNREF
(
&
key
)
=
&
unk
;
VariantInit
(
&
hash
);
V_I4
(
&
hash
)
=
1
;
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 hash 0x%08x, expected 0
\n
"
,
V_I4
(
&
hash
));
V_VT
(
&
key
)
=
VT_UNKNOWN
|
VT_BYREF
;
unk
=
&
test_unk
;
V_UNKNOWNREF
(
&
key
)
=
&
unk
;
VariantInit
(
&
hash
);
expected
=
get_ptr_hash
(
&
test_unk
);
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
,
"got hash 0x%08x, expected 0x%08x
\n
"
,
V_I4
(
&
hash
),
expected
);
/* interface without IDispatch support */
V_VT
(
&
key
)
=
VT_DISPATCH
|
VT_BYREF
;
unk
=
&
test_unk
;
V_DISPATCHREF
(
&
key
)
=
(
IDispatch
**
)
&
unk
;
VariantInit
(
&
hash
);
expected
=
get_ptr_hash
(
&
test_unk
);
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
,
"got hash 0x%08x, expected 0x%08x
\n
"
,
V_I4
(
&
hash
),
expected
);
V_VT
(
&
key
)
=
VT_DISPATCH
|
VT_BYREF
;
disp
=
&
test_disp
;
V_DISPATCHREF
(
&
key
)
=
&
disp
;
VariantInit
(
&
hash
);
expected
=
get_ptr_hash
(
&
test_disp
);
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
,
"got hash 0x%08x, expected 0x%08x
\n
"
,
V_I4
(
&
hash
),
expected
);
IDictionary_Release
(
dict
);
IDictionary_Release
(
dict
);
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment