PATCH: VarChangeTypeEx
Marcus Meissner
marcus at jet.franken.de
Fri Dec 20 16:28:40 CST 2002
Hi,
VariantChangeTypeEx is not yet really caring about the modifiers.
This implements the VT_ARRAY modifier (not in combination!)
ATWin2k seems happier now.
Ciao, Marcus
Changelog:
VariantChangeTypeEx for VT_ARRAY | type style variants.
Index: dlls/oleaut32/variant.c
===================================================================
RCS file: /home/wine/wine/dlls/oleaut32/variant.c,v
retrieving revision 1.49
diff -u -u -r1.49 variant.c
--- dlls/oleaut32/variant.c 16 Dec 2002 22:08:48 -0000 1.49
+++ dlls/oleaut32/variant.c 20 Dec 2002 22:26:51 -0000
@@ -2114,6 +2114,61 @@
}
/******************************************************************************
+ * Coerces a full safearray. Not optimal code.
+ */
+static HRESULT
+coerce_array(
+ VARIANTARG* src, SAFEARRAY **narr, LCID lcid, USHORT wFlags, VARTYPE vt
+) {
+ int elems,i,j;
+ SAFEARRAY *darr, *sarr = V_ARRAY(src);
+ long *addr;
+ HRESULT hres;
+
+ hres = SafeArrayAllocDescriptor( sarr->cDims, &darr);
+ if (FAILED(hres)) return hres;
+ memcpy(
+ darr->rgsabound,
+ sarr->rgsabound,
+ sizeof(sarr->rgsabound[0])*sarr->cDims
+ );
+ hres = SafeArrayAllocData(darr);
+ if (FAILED(hres)) {
+ SafeArrayDestroyDescriptor(darr);
+ return hres;
+ }
+ elems = 1;
+ for (i=0;i<sarr->cDims;i++)
+ elems *= sarr->rgsabound[i].cElements;
+ addr = HeapAlloc(GetProcessHeap(),0,sizeof(long)*sarr->cDims);
+ for (i=0;i<elems;i++) {
+ VARIANT tmpvar,newvar;
+ int tmpi = i;
+ /* convert absolute value in array address */
+ for (j=0;j<sarr->cDims;j++) {
+ addr[j] = (tmpi % sarr->rgsabound[j].cElements) + sarr->rgsabound[j].lLbound;
+ tmpi /= sarr->rgsabound[j].cElements;
+ }
+ V_VT(&tmpvar) = V_VT(src) & VT_TYPEMASK;
+ hres = SafeArrayGetElement(sarr, addr, &V_UNION(&tmpvar,lVal));
+ if (FAILED(hres)) {
+ FIXME("Did not get element %d\n",i);
+ return E_FAIL;
+ }
+ hres = Coerce( &newvar, lcid, wFlags, &tmpvar, vt );
+ if (FAILED(hres)) return E_FAIL;
+ hres = SafeArrayPutElement( darr, addr, &V_UNION(&newvar,lVal));
+ if (FAILED(hres)) {
+ FIXME("SAPE failed for element %d, %lx\n",i,hres);
+ return E_FAIL;
+ }
+ }
+ HeapFree(GetProcessHeap(),0,addr);
+ *narr = darr;
+ return S_OK;
+}
+
+/******************************************************************************
* VariantChangeType [OLEAUT32.12]
*/
HRESULT WINAPI VariantChangeType(VARIANTARG* pvargDest, VARIANTARG* pvargSrc,
@@ -2169,6 +2224,12 @@
/* Convert the source variant to a "byvalue" variant.
*/
VARIANTARG Variant;
+
+ if ((V_VT(pvargSrc) & 0xf000) != VT_BYREF) {
+ FIXME("VT_TYPEMASK %x is unhandled.\n",V_VT(pvargSrc) & VT_TYPEMASK);
+ return E_FAIL;
+ }
+
VariantInit( &Variant );
res = VariantCopyInd( &Variant, pvargSrc );
if( res == S_OK )
@@ -2179,12 +2240,23 @@
VariantClear( &Variant );
}
- }
- else
- {
- /* Use the current "byvalue" source variant.
- */
- res = Coerce( pvargDest, lcid, wFlags, pvargSrc, vt );
+ } else {
+ if (V_VT(pvargSrc) & VT_ARRAY) {
+ if ((V_VT(pvargSrc) & 0xf000) != VT_ARRAY) {
+ FIXME("VT_TYPEMASK %x is unhandled in VT_ARRAY.\n",V_VT(pvargSrc) & VT_TYPEMASK);
+ return E_FAIL;
+ }
+ V_VT(pvargDest) = VT_ARRAY | vt;
+ res = coerce_array(pvargSrc, &V_ARRAY(pvargDest), lcid, wFlags, vt);
+ } else {
+ if ((V_VT(pvargSrc) & 0xf000)) {
+ FIXME("VT_TYPEMASK %x is unhandled in normal case.\n",V_VT(pvargSrc) & VT_TYPEMASK);
+ return E_FAIL;
+ }
+ /* Use the current "byvalue" source variant.
+ */
+ res = Coerce( pvargDest, lcid, wFlags, pvargSrc, vt );
+ }
}
}
/* this should not fail.
More information about the wine-patches
mailing list