[4/5] propsys: Implement prop variant integer conversions with tests.
Vincent Povirk
madewokherd at gmail.com
Thu Sep 13 17:27:32 CDT 2012
-------------- next part --------------
From 7764559ef81974a0fa8c3cb0b73623c9ce19537c Mon Sep 17 00:00:00 2001
From: Vincent Povirk <vincent at codeweavers.com>
Date: Thu, 13 Sep 2012 16:10:35 -0500
Subject: [PATCH 4/5] propsys: Implement prop variant integer conversions with
tests.
---
dlls/propsys/propsys.spec | 12 ++--
dlls/propsys/propvar.c | 141 ++++++++++++++++++++++++++++++++++++++++++
dlls/propsys/tests/propsys.c | 126 +++++++++++++++++++++++++++++++++++++
include/propvarutil.h | 6 ++
4 files changed, 279 insertions(+), 6 deletions(-)
diff --git a/dlls/propsys/propsys.spec b/dlls/propsys/propsys.spec
index fefc5f0..15386d7 100644
--- a/dlls/propsys/propsys.spec
+++ b/dlls/propsys/propsys.spec
@@ -120,15 +120,15 @@
@ stub PropVariantToFileTimeVector
@ stub PropVariantToFileTimeVectorAlloc
@ stdcall PropVariantToGUID(ptr ptr)
-@ stub PropVariantToInt16
+@ stdcall PropVariantToInt16(ptr ptr)
@ stub PropVariantToInt16Vector
@ stub PropVariantToInt16VectorAlloc
@ stub PropVariantToInt16WithDefault
-@ stub PropVariantToInt32
+@ stdcall PropVariantToInt32(ptr ptr)
@ stub PropVariantToInt32Vector
@ stub PropVariantToInt32VectorAlloc
@ stub PropVariantToInt32WithDefault
-@ stub PropVariantToInt64
+@ stdcall PropVariantToInt64(ptr ptr)
@ stub PropVariantToInt64Vector
@ stub PropVariantToInt64VectorAlloc
@ stub PropVariantToInt64WithDefault
@@ -138,15 +138,15 @@
@ stub PropVariantToStringVector
@ stub PropVariantToStringVectorAlloc
@ stub PropVariantToStringWithDefault
-@ stub PropVariantToUInt16
+@ stdcall PropVariantToUInt16(ptr ptr)
@ stub PropVariantToUInt16Vector
@ stub PropVariantToUInt16VectorAlloc
@ stub PropVariantToUInt16WithDefault
-@ stub PropVariantToUInt32
+@ stdcall PropVariantToUInt32(ptr ptr)
@ stub PropVariantToUInt32Vector
@ stub PropVariantToUInt32VectorAlloc
@ stub PropVariantToUInt32WithDefault
-@ stub PropVariantToUInt64
+@ stdcall PropVariantToUInt64(ptr ptr)
@ stub PropVariantToUInt64Vector
@ stub PropVariantToUInt64VectorAlloc
@ stub PropVariantToUInt64WithDefault
diff --git a/dlls/propsys/propvar.c b/dlls/propsys/propvar.c
index bbfe8ca..28100a0 100644
--- a/dlls/propsys/propvar.c
+++ b/dlls/propsys/propvar.c
@@ -68,6 +68,147 @@ static HRESULT PROPVAR_ConvertFILETIME(PROPVARIANT *ppropvarDest,
return E_FAIL;
}
+static HRESULT PROPVAR_ConvertNumber(REFPROPVARIANT pv, int dest_bits,
+ int dest_signed, LONGLONG *res)
+{
+ int src_signed;
+
+ switch (pv->vt)
+ {
+ case VT_I1:
+ src_signed = 1;
+ *res = pv->u.cVal;
+ break;
+ case VT_UI1:
+ src_signed = 0;
+ *res = pv->u.bVal;
+ break;
+ case VT_I2:
+ src_signed = 1;
+ *res = pv->u.iVal;
+ break;
+ case VT_UI2:
+ src_signed = 0;
+ *res = pv->u.uiVal;
+ break;
+ case VT_I4:
+ src_signed = 1;
+ *res = pv->u.lVal;
+ break;
+ case VT_UI4:
+ src_signed = 0;
+ *res = pv->u.ulVal;
+ break;
+ case VT_I8:
+ src_signed = 1;
+ *res = pv->u.hVal.QuadPart;
+ break;
+ case VT_UI8:
+ src_signed = 0;
+ *res = pv->u.uhVal.QuadPart;
+ break;
+ case VT_EMPTY:
+ src_signed = 0;
+ *res = 0;
+ break;
+ default:
+ FIXME("unhandled vt %d\n", pv->vt);
+ return E_NOTIMPL;
+ }
+
+ if (*res < 0 && src_signed != dest_signed)
+ return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
+
+ if (dest_bits < 64)
+ {
+ if (dest_signed)
+ {
+ if (*res >= ((LONGLONG)1 << (dest_bits-1)) ||
+ *res < ((LONGLONG)-1 << (dest_bits-1)))
+ return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
+ }
+ else
+ {
+ if ((ULONGLONG)(*res) >= ((ULONGLONG)1 << dest_bits))
+ return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
+ }
+ }
+
+ return S_OK;
+}
+
+HRESULT WINAPI PropVariantToInt16(REFPROPVARIANT propvarIn, SHORT *ret)
+{
+ LONGLONG res;
+ HRESULT hr;
+
+ TRACE("%p,%p\n", propvarIn, ret);
+
+ hr = PROPVAR_ConvertNumber(propvarIn, 16, 1, &res);
+ if (SUCCEEDED(hr)) *ret = (SHORT)res;
+ return hr;
+}
+
+HRESULT WINAPI PropVariantToInt32(REFPROPVARIANT propvarIn, LONG *ret)
+{
+ LONGLONG res;
+ HRESULT hr;
+
+ TRACE("%p,%p\n", propvarIn, ret);
+
+ hr = PROPVAR_ConvertNumber(propvarIn, 32, 1, &res);
+ if (SUCCEEDED(hr)) *ret = (LONG)res;
+ return hr;
+}
+
+HRESULT WINAPI PropVariantToInt64(REFPROPVARIANT propvarIn, LONGLONG *ret)
+{
+ LONGLONG res;
+ HRESULT hr;
+
+ TRACE("%p,%p\n", propvarIn, ret);
+
+ hr = PROPVAR_ConvertNumber(propvarIn, 64, 1, &res);
+ if (SUCCEEDED(hr)) *ret = (LONGLONG)res;
+ return hr;
+}
+
+HRESULT WINAPI PropVariantToUInt16(REFPROPVARIANT propvarIn, USHORT *ret)
+{
+ LONGLONG res;
+ HRESULT hr;
+
+ TRACE("%p,%p\n", propvarIn, ret);
+
+ hr = PROPVAR_ConvertNumber(propvarIn, 16, 0, &res);
+ if (SUCCEEDED(hr)) *ret = (USHORT)res;
+ return hr;
+}
+
+HRESULT WINAPI PropVariantToUInt32(REFPROPVARIANT propvarIn, ULONG *ret)
+{
+ LONGLONG res;
+ HRESULT hr;
+
+ TRACE("%p,%p\n", propvarIn, ret);
+
+ hr = PROPVAR_ConvertNumber(propvarIn, 32, 0, &res);
+ if (SUCCEEDED(hr)) *ret = (ULONG)res;
+ return hr;
+}
+
+HRESULT WINAPI PropVariantToUInt64(REFPROPVARIANT propvarIn, ULONGLONG *ret)
+{
+ LONGLONG res;
+ HRESULT hr;
+
+ TRACE("%p,%p\n", propvarIn, ret);
+
+ hr = PROPVAR_ConvertNumber(propvarIn, 64, 0, &res);
+ if (SUCCEEDED(hr)) *ret = (ULONGLONG)res;
+ return hr;
+}
+
/******************************************************************
* PropVariantChangeType (PROPSYS.@)
*/
diff --git a/dlls/propsys/tests/propsys.c b/dlls/propsys/tests/propsys.c
index 789eee8..c9df1c9 100644
--- a/dlls/propsys/tests/propsys.c
+++ b/dlls/propsys/tests/propsys.c
@@ -753,6 +753,131 @@ static void test_PropVariantCompare(void)
SysFreeString(str_b.u.bstrVal);
}
+static inline const char* debugstr_longlong(ULONGLONG ll)
+{
+ static char string[17];
+ if (sizeof(ll) > sizeof(unsigned long) && ll >> 32)
+ sprintf(string, "%lx%08lx", (unsigned long)(ll >> 32), (unsigned long)ll);
+ else
+ sprintf(string, "%lx", (unsigned long)ll);
+ return string;
+}
+
+static void test_intconversions(void)
+{
+ PROPVARIANT propvar;
+ SHORT sval;
+ USHORT usval;
+ LONG lval;
+ ULONG ulval;
+ LONGLONG llval;
+ ULONGLONG ullval;
+ HRESULT hr;
+
+ PropVariantClear(&propvar);
+
+ propvar.vt = VT_I8;
+ propvar.u.hVal.QuadPart = (LONGLONG)1 << 63;
+
+ hr = PropVariantToInt64(&propvar, &llval);
+ ok(hr == S_OK, "hr=%x\n", hr);
+ ok(llval == (LONGLONG)1 << 63, "got wrong value %s\n", debugstr_longlong(llval));
+
+ hr = PropVariantToUInt64(&propvar, &ullval);
+ ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr);
+
+ hr = PropVariantToInt32(&propvar, &lval);
+ ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr);
+
+ hr = PropVariantToUInt32(&propvar, &ulval);
+ ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr);
+
+ hr = PropVariantToInt16(&propvar, &sval);
+ ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr);
+
+ hr = PropVariantToUInt16(&propvar, &usval);
+ ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr);
+
+ propvar.vt = VT_UI8;
+ propvar.u.uhVal.QuadPart = 5;
+
+ hr = PropVariantToInt64(&propvar, &llval);
+ ok(hr == S_OK, "hr=%x\n", hr);
+ ok(llval == 5, "got wrong value %s\n", debugstr_longlong(llval));
+
+ hr = PropVariantToUInt64(&propvar, &ullval);
+ ok(hr == S_OK, "hr=%x\n", hr);
+ ok(ullval == 5, "got wrong value %s\n", debugstr_longlong(ullval));
+
+ hr = PropVariantToInt32(&propvar, &lval);
+ ok(hr == S_OK, "hr=%x\n", hr);
+ ok(lval == 5, "got wrong value %d\n", lval);
+
+ hr = PropVariantToUInt32(&propvar, &ulval);
+ ok(hr == S_OK, "hr=%x\n", hr);
+ ok(ulval == 5, "got wrong value %d\n", ulval);
+
+ hr = PropVariantToInt16(&propvar, &sval);
+ ok(hr == S_OK, "hr=%x\n", hr);
+ ok(sval == 5, "got wrong value %d\n", sval);
+
+ hr = PropVariantToUInt16(&propvar, &usval);
+ ok(hr == S_OK, "hr=%x\n", hr);
+ ok(usval == 5, "got wrong value %d\n", usval);
+
+ propvar.vt = VT_I8;
+ propvar.u.hVal.QuadPart = -5;
+
+ hr = PropVariantToInt64(&propvar, &llval);
+ ok(hr == S_OK, "hr=%x\n", hr);
+ ok(llval == -5, "got wrong value %s\n", debugstr_longlong(llval));
+
+ hr = PropVariantToUInt64(&propvar, &ullval);
+ ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr);
+
+ hr = PropVariantToInt32(&propvar, &lval);
+ ok(hr == S_OK, "hr=%x\n", hr);
+ ok(lval == -5, "got wrong value %d\n", lval);
+
+ hr = PropVariantToUInt32(&propvar, &ulval);
+ ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr);
+
+ hr = PropVariantToInt16(&propvar, &sval);
+ ok(hr == S_OK, "hr=%x\n", hr);
+ ok(sval == -5, "got wrong value %d\n", sval);
+
+ hr = PropVariantToUInt16(&propvar, &usval);
+ ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr);
+
+ propvar.vt = VT_UI4;
+ propvar.u.ulVal = 6;
+
+ hr = PropVariantToInt64(&propvar, &llval);
+ ok(hr == S_OK, "hr=%x\n", hr);
+ ok(llval == 6, "got wrong value %s\n", debugstr_longlong(llval));
+
+ propvar.vt = VT_I4;
+ propvar.u.lVal = -6;
+
+ hr = PropVariantToInt64(&propvar, &llval);
+ ok(hr == S_OK, "hr=%x\n", hr);
+ ok(llval == -6, "got wrong value %s\n", debugstr_longlong(llval));
+
+ propvar.vt = VT_UI2;
+ propvar.u.uiVal = 7;
+
+ hr = PropVariantToInt64(&propvar, &llval);
+ ok(hr == S_OK, "hr=%x\n", hr);
+ ok(llval == 7, "got wrong value %s\n", debugstr_longlong(llval));
+
+ propvar.vt = VT_I2;
+ propvar.u.iVal = -7;
+
+ hr = PropVariantToInt64(&propvar, &llval);
+ ok(hr == S_OK, "hr=%x\n", hr);
+ ok(llval == -7, "got wrong value %s\n", debugstr_longlong(llval));
+}
+
START_TEST(propsys)
{
test_PSStringFromPropertyKey();
@@ -762,4 +887,5 @@ START_TEST(propsys)
test_InitPropVariantFromBuffer();
test_PropVariantToGUID();
test_PropVariantCompare();
+ test_intconversions();
}
diff --git a/include/propvarutil.h b/include/propvarutil.h
index 94a80b4..4618efe 100644
--- a/include/propvarutil.h
+++ b/include/propvarutil.h
@@ -70,6 +70,12 @@ HRESULT WINAPI VariantToGUID(const VARIANT *pvar, GUID *guid);
INT WINAPI PropVariantCompareEx(REFPROPVARIANT propvar1, REFPROPVARIANT propvar2,
PROPVAR_COMPARE_UNIT uint, PROPVAR_COMPARE_FLAGS flags);
+HRESULT WINAPI PropVariantToInt16(REFPROPVARIANT propvarIn, SHORT *ret);
+HRESULT WINAPI PropVariantToInt32(REFPROPVARIANT propvarIn, LONG *ret);
+HRESULT WINAPI PropVariantToInt64(REFPROPVARIANT propvarIn, LONGLONG *ret);
+HRESULT WINAPI PropVariantToUInt16(REFPROPVARIANT propvarIn, USHORT *ret);
+HRESULT WINAPI PropVariantToUInt32(REFPROPVARIANT propvarIn, ULONG *ret);
+HRESULT WINAPI PropVariantToUInt64(REFPROPVARIANT propvarIn, ULONGLONG *ret);
#ifdef __cplusplus
--
1.7.9.5
More information about the wine-patches
mailing list