oleaut32: Simplify VarCat implementation.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2017-06-15 15:03:52 +02:00 committed by Alexandre Julliard
parent 191b81dbd3
commit 840ab7cd1c

View file

@ -2517,14 +2517,15 @@ VarNumFromParseNum_DecOverflow:
*/ */
HRESULT WINAPI VarCat(LPVARIANT left, LPVARIANT right, LPVARIANT out) HRESULT WINAPI VarCat(LPVARIANT left, LPVARIANT right, LPVARIANT out)
{ {
VARTYPE leftvt,rightvt,resultvt; BSTR left_str = NULL, right_str = NULL;
VARTYPE leftvt, rightvt;
HRESULT hres; HRESULT hres;
TRACE("%s,%s,%p)\n", debugstr_variant(left), debugstr_variant(right), out);
leftvt = V_VT(left); leftvt = V_VT(left);
rightvt = V_VT(right); rightvt = V_VT(right);
TRACE("%s,%s,%p)\n", debugstr_variant(left), debugstr_variant(right), out);
/* when both left and right are NULL the result is NULL */ /* when both left and right are NULL the result is NULL */
if (leftvt == VT_NULL && rightvt == VT_NULL) if (leftvt == VT_NULL && rightvt == VT_NULL)
{ {
@ -2532,9 +2533,6 @@ HRESULT WINAPI VarCat(LPVARIANT left, LPVARIANT right, LPVARIANT out)
return S_OK; return S_OK;
} }
hres = S_OK;
resultvt = VT_EMPTY;
/* There are many special case for errors and return types */ /* There are many special case for errors and return types */
if (leftvt == VT_VARIANT && (rightvt == VT_ERROR || if (leftvt == VT_VARIANT && (rightvt == VT_ERROR ||
rightvt == VT_DATE || rightvt == VT_DECIMAL)) rightvt == VT_DATE || rightvt == VT_DECIMAL))
@ -2560,7 +2558,7 @@ HRESULT WINAPI VarCat(LPVARIANT left, LPVARIANT right, LPVARIANT out)
rightvt == VT_UINT || rightvt == VT_EMPTY || rightvt == VT_UINT || rightvt == VT_EMPTY ||
rightvt == VT_NULL || rightvt == VT_DATE || rightvt == VT_NULL || rightvt == VT_DATE ||
rightvt == VT_DECIMAL || rightvt == VT_DISPATCH)) rightvt == VT_DECIMAL || rightvt == VT_DISPATCH))
resultvt = VT_BSTR; hres = S_OK;
else if (rightvt == VT_ERROR && leftvt < VT_VOID) else if (rightvt == VT_ERROR && leftvt < VT_VOID)
hres = DISP_E_TYPEMISMATCH; hres = DISP_E_TYPEMISMATCH;
else if (leftvt == VT_ERROR && (rightvt == VT_DATE || else if (leftvt == VT_ERROR && (rightvt == VT_DATE ||
@ -2590,87 +2588,72 @@ HRESULT WINAPI VarCat(LPVARIANT left, LPVARIANT right, LPVARIANT out)
/* if result type is not S_OK, then no need to go further */ /* if result type is not S_OK, then no need to go further */
if (hres != S_OK) if (hres != S_OK)
{ {
V_VT(out) = resultvt; V_VT(out) = VT_EMPTY;
return hres; return hres;
} }
/* Else proceed with formatting inputs to strings */
if (leftvt == VT_BSTR)
left_str = V_BSTR(left);
else else
{ {
VARIANT bstrvar_left, bstrvar_right; VARIANT converted, *tmp = left;
VARIANT *tmp;
VARIANT fetched;
V_VT(out) = VT_BSTR; VariantInit(&converted);
if(leftvt == VT_DISPATCH)
VariantInit(&bstrvar_left);
VariantInit(&bstrvar_right);
VariantInit(&fetched);
/* Convert left side variant to string */
if (leftvt != VT_BSTR)
{ {
tmp = left; hres = VARIANT_FetchDispatchValue(left, &converted);
if(FAILED(hres))
if(leftvt == VT_DISPATCH)
{
hres = VARIANT_FetchDispatchValue(left, &fetched);
if(FAILED(hres))
goto failed;
tmp = &fetched;
}
hres = VariantChangeTypeEx(&bstrvar_left,tmp,0,VARIANT_ALPHABOOL|VARIANT_LOCALBOOL,VT_BSTR);
VariantClear(&fetched);
if (hres == DISP_E_TYPEMISMATCH)
{
V_VT(&bstrvar_left) = VT_BSTR;
V_BSTR(&bstrvar_left) = SysAllocStringLen(NULL, 0);
}
else if(hres != S_OK)
goto failed; goto failed;
tmp = &converted;
} }
/* convert right side variant to string */ hres = VariantChangeTypeEx(&converted, tmp, 0, VARIANT_ALPHABOOL|VARIANT_LOCALBOOL, VT_BSTR);
if (rightvt != VT_BSTR) if (SUCCEEDED(hres))
left_str = V_BSTR(&converted);
else if (hres != DISP_E_TYPEMISMATCH)
{ {
tmp = right; VariantClear(&converted);
goto failed;
}
}
if(rightvt == VT_DISPATCH) if (rightvt == VT_BSTR)
{ right_str = V_BSTR(right);
hres = VARIANT_FetchDispatchValue(right, &fetched); else
if(FAILED(hres)) {
goto failed; VARIANT converted, *tmp = right;
tmp = &fetched; VariantInit(&converted);
} if(rightvt == VT_DISPATCH)
{
hres = VariantChangeTypeEx(&bstrvar_right,tmp,0,VARIANT_ALPHABOOL|VARIANT_LOCALBOOL,VT_BSTR); hres = VARIANT_FetchDispatchValue(right, &converted);
VariantClear(&fetched); if(FAILED(hres))
if (hres == DISP_E_TYPEMISMATCH)
{
V_VT(&bstrvar_right) = VT_BSTR;
V_BSTR(&bstrvar_right) = SysAllocStringLen(NULL, 0);
}
else if(hres != S_OK)
goto failed; goto failed;
tmp = &converted;
} }
/* Concat the resulting strings together */ hres = VariantChangeTypeEx(&converted, tmp, 0, VARIANT_ALPHABOOL|VARIANT_LOCALBOOL, VT_BSTR);
if (leftvt == VT_BSTR && rightvt == VT_BSTR) if (SUCCEEDED(hres))
hres = VarBstrCat (V_BSTR(left), V_BSTR(right), &V_BSTR(out)); right_str = V_BSTR(&converted);
else if (leftvt != VT_BSTR && rightvt != VT_BSTR) else if (hres != DISP_E_TYPEMISMATCH)
hres = VarBstrCat (V_BSTR(&bstrvar_left), V_BSTR(&bstrvar_right), &V_BSTR(out)); {
else if (leftvt != VT_BSTR && rightvt == VT_BSTR) VariantClear(&converted);
hres = VarBstrCat (V_BSTR(&bstrvar_left), V_BSTR(right), &V_BSTR(out)); goto failed;
else if (leftvt == VT_BSTR && rightvt != VT_BSTR) }
hres = VarBstrCat (V_BSTR(left), V_BSTR(&bstrvar_right), &V_BSTR(out)); }
V_VT(out) = VT_BSTR;
hres = VarBstrCat(left_str, right_str, &V_BSTR(out));
failed: failed:
VariantClear(&bstrvar_left); if(V_VT(left) != VT_BSTR)
VariantClear(&bstrvar_right); SysFreeString(left_str);
return hres; if(V_VT(right) != VT_BSTR)
} SysFreeString(right_str);
return hres;
} }