#include "config.h"
-#ifdef HAVE_STRING_H
-# include <string.h>
-#endif
-#ifdef HAVE_STDLIB_H
-# include <stdlib.h>
-#endif
+#include <string.h>
+#include <stdlib.h>
#include <stdarg.h>
#define NONAMELESSUNION
#include "winerror.h"
#include "variant.h"
-
WINE_DEFAULT_DEBUG_CHANNEL(ole);
const char* wine_vtypes[VT_CLSID] =
#define GET_NUMBER_TEXT(fld,name) \
buff[0] = 0; \
- if (!GetLocaleInfoW(lcid, lctype|fld, buff, sizeof(WCHAR) * 2)) \
+ if (!GetLocaleInfoW(lcid, lctype|fld, buff, 2)) \
WARN("buffer too small for " #fld "\n"); \
else \
if (buff[0]) lpChars->name = buff[0]; \
/* Local currency symbols are often 2 characters */
lpChars->cCurrencyLocal2 = '\0';
- switch(GetLocaleInfoW(lcid, lctype|LOCALE_SCURRENCY, buff, sizeof(WCHAR) * 4))
+ switch(GetLocaleInfoW(lcid, lctype|LOCALE_SCURRENCY, buff, sizeof(buff)/sizeof(WCHAR)))
{
case 3: lpChars->cCurrencyLocal2 = buff[1]; /* Fall through */
case 2: lpChars->cCurrencyLocal = buff[0];
case VT_UI2 : lVal = V_UNION(left,uiVal); resT=VT_I4; break;
case VT_UI4 : lVal = V_UNION(left,ulVal); resT=VT_I4; break;
case VT_UINT : lVal = V_UNION(left,ulVal); resT=VT_I4; break;
+ case VT_BOOL : rVal = V_UNION(left,boolVal); resT=VT_I4; break;
default: lOk = FALSE;
}
case VT_UI2 : rVal = V_UNION(right,uiVal); resT=VT_I4; break;
case VT_UI4 : rVal = V_UNION(right,ulVal); resT=VT_I4; break;
case VT_UINT : rVal = V_UNION(right,ulVal); resT=VT_I4; break;
+ case VT_BOOL : rVal = V_UNION(right,boolVal); resT=VT_I4; break;
default: rOk = FALSE;
}
case VT_UI2 : lVal = V_UNION(left,uiVal); resT=VT_I4; break;
case VT_UI4 : lVal = V_UNION(left,ulVal); resT=VT_I4; break;
case VT_UINT : lVal = V_UNION(left,ulVal); resT=VT_I4; break;
+ case VT_BOOL : lVal = V_UNION(left,boolVal); resT=VT_I4; break;
default: lOk = FALSE;
}
case VT_UI2 : rVal = V_UNION(right,uiVal); resT=VT_I4; break;
case VT_UI4 : rVal = V_UNION(right,ulVal); resT=VT_I4; break;
case VT_UINT : rVal = V_UNION(right,ulVal); resT=VT_I4; break;
+ case VT_BOOL : rVal = V_UNION(right,boolVal); resT=VT_I4; break;
default: rOk = FALSE;
}
return hRet;
}
+/**********************************************************************
+ * VarRound [OLEAUT32.175]
+ *
+ * Perform a round operation on a variant.
+ *
+ * PARAMS
+ * pVarIn [I] Source variant
+ * deci [I] Number of decimals to round to
+ * pVarOut [O] Destination for converted value
+ *
+ * RETURNS
+ * Success: S_OK. pVarOut contains the converted value.
+ * Failure: An HRESULT error code indicating the error.
+ *
+ * NOTES
+ * - Floating point values are rounded to the desired number of decimals.
+ * - Some integer types are just copied to the return variable.
+ * - Some other integer types are not handled and fail.
+ */
+HRESULT WINAPI VarRound(LPVARIANT pVarIn, int deci, LPVARIANT pVarOut)
+{
+ VARIANT varIn;
+ HRESULT hRet = S_OK;
+ float factor;
+
+ TRACE("(%p->(%s%s),%d)\n", pVarIn, debugstr_VT(pVarIn), debugstr_VF(pVarIn), deci);
+
+ switch (V_VT(pVarIn))
+ {
+ /* cases that fail on windows */
+ case VT_I1:
+ case VT_I8:
+ case VT_UI2:
+ case VT_UI4:
+ hRet = DISP_E_BADVARTYPE;
+ break;
+
+ /* cases just copying in to out */
+ case VT_UI1:
+ V_VT(pVarOut) = V_VT(pVarIn);
+ V_UI1(pVarOut) = V_UI1(pVarIn);
+ break;
+ case VT_I2:
+ V_VT(pVarOut) = V_VT(pVarIn);
+ V_I2(pVarOut) = V_I2(pVarIn);
+ break;
+ case VT_I4:
+ V_VT(pVarOut) = V_VT(pVarIn);
+ V_I4(pVarOut) = V_I4(pVarIn);
+ break;
+ case VT_NULL:
+ V_VT(pVarOut) = V_VT(pVarIn);
+ /* value unchanged */
+ break;
+
+ /* cases that change type */
+ case VT_EMPTY:
+ V_VT(pVarOut) = VT_I2;
+ V_I2(pVarOut) = 0;
+ break;
+ case VT_BOOL:
+ V_VT(pVarOut) = VT_I2;
+ V_I2(pVarOut) = V_BOOL(pVarIn);
+ break;
+ case VT_BSTR:
+ hRet = VarR8FromStr(V_BSTR(pVarIn), LOCALE_USER_DEFAULT, 0, &V_R8(&varIn));
+ if (FAILED(hRet))
+ break;
+ V_VT(&varIn)=VT_R8;
+ pVarIn = &varIn;
+ /* Fall through ... */
+
+ /* cases we need to do math */
+ case VT_R8:
+ if (V_R8(pVarIn)>0) {
+ V_R8(pVarOut)=floor(V_R8(pVarIn)*pow(10, deci)+0.5)/pow(10, deci);
+ } else {
+ V_R8(pVarOut)=ceil(V_R8(pVarIn)*pow(10, deci)-0.5)/pow(10, deci);
+ }
+ V_VT(pVarOut) = V_VT(pVarIn);
+ break;
+ case VT_R4:
+ if (V_R4(pVarIn)>0) {
+ V_R4(pVarOut)=floor(V_R4(pVarIn)*pow(10, deci)+0.5)/pow(10, deci);
+ } else {
+ V_R4(pVarOut)=ceil(V_R4(pVarIn)*pow(10, deci)-0.5)/pow(10, deci);
+ }
+ V_VT(pVarOut) = V_VT(pVarIn);
+ break;
+ case VT_DATE:
+ if (V_DATE(pVarIn)>0) {
+ V_DATE(pVarOut)=floor(V_DATE(pVarIn)*pow(10, deci)+0.5)/pow(10, deci);
+ } else {
+ V_DATE(pVarOut)=ceil(V_DATE(pVarIn)*pow(10, deci)-0.5)/pow(10, deci);
+ }
+ V_VT(pVarOut) = V_VT(pVarIn);
+ break;
+ case VT_CY:
+ if (deci>3)
+ factor=1;
+ else
+ factor=pow(10, 4-deci);
+
+ if (V_CY(pVarIn).int64>0) {
+ V_CY(pVarOut).int64=floor(V_CY(pVarIn).int64/factor)*factor;
+ } else {
+ V_CY(pVarOut).int64=ceil(V_CY(pVarIn).int64/factor)*factor;
+ }
+ V_VT(pVarOut) = V_VT(pVarIn);
+ break;
+
+ /* cases we don't know yet */
+ default:
+ FIXME("unimplemented part, V_VT(pVarIn) == 0x%X, deci == %d\n",
+ V_VT(pVarIn) & VT_TYPEMASK, deci);
+ hRet = DISP_E_BADVARTYPE;
+ }
+
+ if (FAILED(hRet))
+ V_VT(pVarOut) = VT_EMPTY;
+
+ TRACE("returning 0x%08lx (%s%s),%f\n", hRet, debugstr_VT(pVarOut),
+ debugstr_VF(pVarOut), (V_VT(pVarOut) == VT_R4) ? V_R4(pVarOut) :
+ (V_VT(pVarOut) == VT_R8) ? V_R8(pVarOut) : 0);
+
+ return hRet;
+}
+
+
/**********************************************************************
* VarMod [OLEAUT32.154]
*
WINE_DEFAULT_DEBUG_CHANNEL(ole);
-
extern HMODULE OLEAUT32_hModule;
static const WCHAR szFloatFormatW[] = { '%','.','7','G','\0' };
case VT_UI1: memcpy(pOut, &V_UI1(srcVar), sizeof(BYTE)); break;
case VT_BOOL:
case VT_I2:
- case VT_UI2: memcpy(pOut, &V_UI2(srcVar), sizeof(SHORT));
- break;
+ case VT_UI2: memcpy(pOut, &V_UI2(srcVar), sizeof(SHORT)); break;
case VT_R4:
case VT_INT:
case VT_I4:
case VT_UINT:
- case VT_UI4: memcpy(pOut, &V_UI4(srcVar), sizeof (LONG));
- break;
+ case VT_UI4: memcpy(pOut, &V_UI4(srcVar), sizeof (LONG)); break;
case VT_R8:
case VT_DATE:
case VT_CY:
case VT_I8:
- case VT_UI8: memcpy(pOut, &V_UI8(srcVar), sizeof (LONG64));
- break;
+ case VT_UI8: memcpy(pOut, &V_UI8(srcVar), sizeof (LONG64)); break;
case VT_INT_PTR: memcpy(pOut, &V_INT_PTR(srcVar), sizeof (INT_PTR)); break;
case VT_DECIMAL: memcpy(pOut, &V_DECIMAL(srcVar), sizeof (DECIMAL)); break;
default:
return _VarUI4FromR8(d, pulOut);
}
-
/************************************************************************
* VarUI4FromStr (OLEAUT32.277)
*
return S_OK;
}
-
/************************************************************************
* VarI8FromCy (OLEAUT32.337)
*
return S_OK;
}
-
/************************************************************************
* VarR4FromI8 (OLEAUT32.360)
*
return _VarCyFromDisp(pdispIn, lcid, pCyOut);
}
-
/************************************************************************
* VarCyFromBool (OLEAUT32.106)
*
return S_OK;
}
-
/************************************************************************
* VarDecFromStr (OLEAUT32.197)
*
return hRet;
}
-
/************************************************************************
* VarDecCmpR8 (OLEAUT32.298)
*
if (lIn < 0)
{
- ul64 = -lIn;
+ ul64 = (ULONG)-lIn;
dwFlags |= VAR_NEGATIVE;
}
return VARIANT_BstrFromUInt(ul64, lcid, dwFlags, pbstrOut);