propsys: Implement prop variant integer conversions with tests.

This commit is contained in:
Vincent Povirk 2012-09-13 16:10:35 -05:00 committed by Alexandre Julliard
parent 6d52262e56
commit c66b5ac4c3
4 changed files with 279 additions and 6 deletions

View File

@ -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

View File

@ -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.@)
*/

View File

@ -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();
}

View File

@ -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