Implement VarXor and simplify VarEqv to use it.

This commit is contained in:
Jon Griffiths 2004-03-22 20:39:27 +00:00 committed by Alexandre Julliard
parent b74750c1b5
commit 743b75ab44
2 changed files with 73 additions and 60 deletions

View File

@ -162,7 +162,7 @@
164 stdcall QueryPathOfRegTypeLib(ptr long long long ptr) 164 stdcall QueryPathOfRegTypeLib(ptr long long long ptr)
165 stdcall LHashValOfNameSys(long long wstr) 165 stdcall LHashValOfNameSys(long long wstr)
166 stdcall LHashValOfNameSysA(long long str) 166 stdcall LHashValOfNameSysA(long long str)
167 stub VarXor # stdcall (ptr ptr ptr) 167 stdcall VarXor(ptr ptr ptr)
168 stdcall VarAbs(ptr ptr) 168 stdcall VarAbs(ptr ptr)
169 stdcall VarFix(ptr ptr) 169 stdcall VarFix(ptr ptr)
170 stdcall OaBuildVersion() 170 stdcall OaBuildVersion()

View File

@ -3370,26 +3370,21 @@ HRESULT WINAPI VarInt(LPVARIANT pVarIn, LPVARIANT pVarOut)
} }
/********************************************************************** /**********************************************************************
* VarEqv [OLEAUT32.172] * VarXor [OLEAUT32.167]
* *
* Determine if two variants contain the same value. * Perform a logical exclusive-or (XOR) operation on two variants.
* *
* PARAMS * PARAMS
* pVarLeft [I] First variant to compare * pVarLeft [I] First variant
* pVarRight [I] Variant to compare to pVarLeft * pVarRight [I] Variant to XOR with pVarLeft
* pVarOut [O] Destination for comparason result * pVarOut [O] Destination for XOR result
* *
* RETURNS * RETURNS
* Success: S_OK. pVarOut contains the result of the comparason (VARIANT_TRUE * Success: S_OK. pVarOut contains the result of the operation with its type
* if equivalent or VARIANT_FALSE or -2 otherwise, with type from the * taken from the table below).
* table below).
* Failure: An HRESULT error code indicating the error. * Failure: An HRESULT error code indicating the error.
* *
* NOTES * NOTES
* - Equvalence is defined as containing the same value if one variant is
* converted to the other.
* - Any value in pVarLeft or pVarRight that will not fit in a VT_I4 will
* cause overflow (This is compatable with the native implementation).
* - The result stored in pVarOut depends on the types of pVarLeft/pVarRight * - The result stored in pVarOut depends on the types of pVarLeft/pVarRight
* according to the following table: * according to the following table:
*| Type 1 Type 2 Result Type *| Type 1 Type 2 Result Type
@ -3412,9 +3407,9 @@ HRESULT WINAPI VarInt(LPVARIANT pVarIn, LPVARIANT pVarOut)
*| VT_BOOL VT_I2 *| VT_BOOL VT_I2
*| All Other Combinations VT_UI4 *| All Other Combinations VT_UI4
*/ */
HRESULT WINAPI VarEqv(LPVARIANT pVarLeft, LPVARIANT pVarRight, LPVARIANT pVarOut) HRESULT WINAPI VarXor(LPVARIANT pVarLeft, LPVARIANT pVarRight, LPVARIANT pVarOut)
{ {
VARTYPE vt = VT_UI4; VARTYPE vt = VT_I4;
VARIANT varLeft, varRight; VARIANT varLeft, varRight;
HRESULT hRet; HRESULT hRet;
@ -3469,10 +3464,14 @@ HRESULT WINAPI VarEqv(LPVARIANT pVarLeft, LPVARIANT pVarRight, LPVARIANT pVarOut
/* Fall Through ... */ /* Fall Through ... */
case VT_DATE: case VT_CY: case VT_DECIMAL: case VT_R4: case VT_R8: case VT_DATE: case VT_CY: case VT_DECIMAL: case VT_R4: case VT_R8:
case VT_I1: case VT_UI2: case VT_I4: case VT_UI4: case VT_I1: case VT_UI2: case VT_I4: case VT_UI4:
case VT_INT: case VT_UINT: case VT_I8: case VT_UI8: case VT_INT: case VT_UINT: case VT_UI8:
V_VT(pVarOut) = VT_I4; V_VT(pVarOut) = VT_I4;
V_I4(pVarOut) = VARIANT_FALSE; V_I4(pVarOut) = VARIANT_FALSE;
return S_OK; return S_OK;
case VT_I8:
V_VT(pVarOut) = VT_I8;
V_I4(pVarOut) = VARIANT_FALSE;
return S_OK;
default: default:
return DISP_E_BADVARTYPE; return DISP_E_BADVARTYPE;
} }
@ -3481,26 +3480,14 @@ HRESULT WINAPI VarEqv(LPVARIANT pVarLeft, LPVARIANT pVarRight, LPVARIANT pVarOut
if (V_VT(pVarLeft) == VT_BOOL && V_VT(pVarRight) == VT_BOOL) if (V_VT(pVarLeft) == VT_BOOL && V_VT(pVarRight) == VT_BOOL)
{ {
V_VT(pVarOut) = VT_BOOL; V_VT(pVarOut) = VT_BOOL;
if (V_BOOL(pVarLeft) == V_BOOL(pVarRight)) V_BOOL(pVarOut) = V_BOOL(pVarLeft) ^ V_BOOL(pVarRight);
V_BOOL(pVarOut) = VARIANT_TRUE;
else if (V_BOOL(pVarLeft) == VARIANT_TRUE && V_BOOL(pVarRight) == VARIANT_FALSE)
{
V_BOOL(pVarOut) = VARIANT_FALSE;
}
else if (V_BOOL(pVarLeft) == VARIANT_FALSE && V_BOOL(pVarRight) == VARIANT_TRUE)
{
V_BOOL(pVarOut) = VARIANT_FALSE;
}
else
V_BOOL(pVarOut) = -2; /* Go Figure; this matches native */
return S_OK; return S_OK;
} }
if (V_VT(pVarLeft) == VT_UI1 && V_VT(pVarRight) == VT_UI1) if (V_VT(pVarLeft) == VT_UI1 && V_VT(pVarRight) == VT_UI1)
{ {
V_VT(pVarOut) = VT_UI1; V_VT(pVarOut) = VT_UI1;
V_UI1(pVarOut) = V_UI1(pVarLeft) == V_UI1(pVarRight) ? 0xff : 0xfe; V_UI1(pVarOut) = V_UI1(pVarLeft) ^ V_UI1(pVarRight);
return S_OK; return S_OK;
} }
@ -3509,62 +3496,88 @@ HRESULT WINAPI VarEqv(LPVARIANT pVarLeft, LPVARIANT pVarRight, LPVARIANT pVarOut
(V_VT(pVarRight) == VT_BOOL || V_VT(pVarRight) == VT_UI1 || (V_VT(pVarRight) == VT_BOOL || V_VT(pVarRight) == VT_UI1 ||
V_VT(pVarRight) == VT_I2)) V_VT(pVarRight) == VT_I2))
vt = VT_I2; vt = VT_I2;
else if (V_VT(pVarLeft) == VT_I8 || V_VT(pVarRight) == VT_I8)
{
if (V_VT(pVarLeft) == VT_INT || V_VT(pVarRight) == VT_INT)
return DISP_E_TYPEMISMATCH;
vt = VT_I8;
}
V_VT(&varLeft) = V_VT(&varRight) = VT_EMPTY; V_VT(&varLeft) = V_VT(&varRight) = VT_EMPTY;
hRet = VariantCopy(&varLeft, pVarLeft); hRet = VariantCopy(&varLeft, pVarLeft);
if (FAILED(hRet)) if (FAILED(hRet))
goto VarEqv_Exit; goto VarXor_Exit;
hRet = VariantCopy(&varRight, pVarRight); hRet = VariantCopy(&varRight, pVarRight);
if (FAILED(hRet)) if (FAILED(hRet))
goto VarEqv_Exit; goto VarXor_Exit;
hRet = VariantChangeTypeEx(&varLeft, pVarLeft, LOCALE_USER_DEFAULT, 0, vt); hRet = VariantChangeTypeEx(&varLeft, pVarLeft, LOCALE_USER_DEFAULT, 0, vt);
if (FAILED(hRet)) if (FAILED(hRet))
goto VarEqv_Exit; goto VarXor_Exit;
hRet = VariantChangeTypeEx(&varRight, pVarRight, LOCALE_USER_DEFAULT, 0, vt); hRet = VariantChangeTypeEx(&varRight, pVarRight, LOCALE_USER_DEFAULT, 0, vt);
if (FAILED(hRet)) if (FAILED(hRet))
goto VarEqv_Exit; goto VarXor_Exit;
V_VT(pVarOut) = vt; V_VT(pVarOut) = vt;
if (vt == VT_UI4) if (vt == VT_I8)
{ {
if (V_UI4(&varLeft) == V_UI4(&varRight)) V_I8(pVarOut) = V_I8(&varLeft) ^ V_I8(&varRight);
V_UI4(pVarOut) = VARIANT_TRUE;
else if (V_UI4(&varLeft) == VARIANT_TRUE && V_UI4(&varRight) == VARIANT_FALSE)
{
V_UI4(pVarOut) = VARIANT_FALSE;
} }
else if (V_UI4(&varLeft) == VARIANT_FALSE && V_UI4(&varRight) == VARIANT_TRUE) else if (vt == VT_UI4)
{ {
V_UI4(pVarOut) = VARIANT_FALSE; V_I4(pVarOut) = V_I4(&varLeft) ^ V_I4(&varRight);
}
else
V_UI4(pVarOut) = -2;
} }
else else
{ {
if (V_I2(&varLeft) == V_I2(&varRight)) V_I2(pVarOut) = V_I2(&varLeft) ^ V_I2(&varRight);
V_I2(pVarOut) = VARIANT_TRUE;
else if (V_I2(&varLeft) == VARIANT_TRUE && V_I2(&varRight) == VARIANT_FALSE)
{
V_I2(pVarOut) = VARIANT_FALSE;
}
else if (V_I2(&varLeft) == VARIANT_FALSE && V_I2(&varRight) == VARIANT_TRUE)
{
V_I2(pVarOut) = VARIANT_FALSE;
}
else
V_I2(pVarOut) = -2;
} }
VarEqv_Exit: VarXor_Exit:
VariantClear(&varLeft); VariantClear(&varLeft);
VariantClear(&varRight); VariantClear(&varRight);
return hRet; return hRet;
} }
/**********************************************************************
* VarEqv [OLEAUT32.172]
*
* Determine if two variants contain the same value.
*
* PARAMS
* pVarLeft [I] First variant to compare
* pVarRight [I] Variant to compare to pVarLeft
* pVarOut [O] Destination for comparison result
*
* RETURNS
* Success: S_OK. pVarOut contains the result of the comparason (VARIANT_TRUE
* if equivalent or non-zero otherwise.
* Failure: An HRESULT error code indicating the error.
*
* NOTES
* - This function simply calls VarXor() on pVarLeft and pVarRight and inverts
* the result.
*/
HRESULT WINAPI VarEqv(LPVARIANT pVarLeft, LPVARIANT pVarRight, LPVARIANT pVarOut)
{
HRESULT hRet;
TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", pVarLeft, debugstr_VT(pVarLeft),
debugstr_VF(pVarLeft), pVarRight, debugstr_VT(pVarRight),
debugstr_VF(pVarRight), pVarOut);
hRet = VarXor(pVarLeft, pVarRight, pVarOut);
if (SUCCEEDED(hRet))
{
if (V_VT(pVarOut) == VT_I8)
V_I8(pVarOut) = ~V_I8(pVarOut);
else
V_UI4(pVarOut) = ~V_UI4(pVarOut);
}
return hRet;
}
/********************************************************************** /**********************************************************************
* VarNeg [OLEAUT32.173] * VarNeg [OLEAUT32.173]
* *