From 743b75ab4495ea8eb61fd70d24f90d0fa02ced9d Mon Sep 17 00:00:00 2001 From: Jon Griffiths Date: Mon, 22 Mar 2004 20:39:27 +0000 Subject: [PATCH] Implement VarXor and simplify VarEqv to use it. --- dlls/oleaut32/oleaut32.spec | 2 +- dlls/oleaut32/variant.c | 131 ++++++++++++++++++++---------------- 2 files changed, 73 insertions(+), 60 deletions(-) diff --git a/dlls/oleaut32/oleaut32.spec b/dlls/oleaut32/oleaut32.spec index 4516cfc324..136de5dbea 100644 --- a/dlls/oleaut32/oleaut32.spec +++ b/dlls/oleaut32/oleaut32.spec @@ -162,7 +162,7 @@ 164 stdcall QueryPathOfRegTypeLib(ptr long long long ptr) 165 stdcall LHashValOfNameSys(long long wstr) 166 stdcall LHashValOfNameSysA(long long str) -167 stub VarXor # stdcall (ptr ptr ptr) +167 stdcall VarXor(ptr ptr ptr) 168 stdcall VarAbs(ptr ptr) 169 stdcall VarFix(ptr ptr) 170 stdcall OaBuildVersion() diff --git a/dlls/oleaut32/variant.c b/dlls/oleaut32/variant.c index 76adf26df9..82f73b13a7 100644 --- a/dlls/oleaut32/variant.c +++ b/dlls/oleaut32/variant.c @@ -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 - * pVarLeft [I] First variant to compare - * pVarRight [I] Variant to compare to pVarLeft - * pVarOut [O] Destination for comparason result + * pVarLeft [I] First variant + * pVarRight [I] Variant to XOR with pVarLeft + * pVarOut [O] Destination for XOR result * * RETURNS - * Success: S_OK. pVarOut contains the result of the comparason (VARIANT_TRUE - * if equivalent or VARIANT_FALSE or -2 otherwise, with type from the - * table below). + * Success: S_OK. pVarOut contains the result of the operation with its type + * taken from the table below). * Failure: An HRESULT error code indicating the error. * * 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 * according to the following table: *| Type 1 Type 2 Result Type @@ -3412,9 +3407,9 @@ HRESULT WINAPI VarInt(LPVARIANT pVarIn, LPVARIANT pVarOut) *| VT_BOOL VT_I2 *| 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; HRESULT hRet; @@ -3469,10 +3464,14 @@ HRESULT WINAPI VarEqv(LPVARIANT pVarLeft, LPVARIANT pVarRight, LPVARIANT pVarOut /* Fall Through ... */ 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_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_I4(pVarOut) = VARIANT_FALSE; return S_OK; + case VT_I8: + V_VT(pVarOut) = VT_I8; + V_I4(pVarOut) = VARIANT_FALSE; + return S_OK; default: 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) { V_VT(pVarOut) = VT_BOOL; - if (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 */ - + V_BOOL(pVarOut) = V_BOOL(pVarLeft) ^ V_BOOL(pVarRight); return S_OK; } if (V_VT(pVarLeft) == VT_UI1 && V_VT(pVarRight) == 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; } @@ -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_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; hRet = VariantCopy(&varLeft, pVarLeft); if (FAILED(hRet)) - goto VarEqv_Exit; + goto VarXor_Exit; hRet = VariantCopy(&varRight, pVarRight); if (FAILED(hRet)) - goto VarEqv_Exit; + goto VarXor_Exit; hRet = VariantChangeTypeEx(&varLeft, pVarLeft, LOCALE_USER_DEFAULT, 0, vt); if (FAILED(hRet)) - goto VarEqv_Exit; + goto VarXor_Exit; hRet = VariantChangeTypeEx(&varRight, pVarRight, LOCALE_USER_DEFAULT, 0, vt); if (FAILED(hRet)) - goto VarEqv_Exit; + goto VarXor_Exit; V_VT(pVarOut) = vt; - if (vt == VT_UI4) + if (vt == VT_I8) { - if (V_UI4(&varLeft) == V_UI4(&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) - { - V_UI4(pVarOut) = VARIANT_FALSE; - } - else - V_UI4(pVarOut) = -2; + V_I8(pVarOut) = V_I8(&varLeft) ^ V_I8(&varRight); + } + else if (vt == VT_UI4) + { + V_I4(pVarOut) = V_I4(&varLeft) ^ V_I4(&varRight); } else { - if (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; + V_I2(pVarOut) = V_I2(&varLeft) ^ V_I2(&varRight); } -VarEqv_Exit: +VarXor_Exit: VariantClear(&varLeft); VariantClear(&varRight); 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] * -- 2.32.0.93.g670b81a890