Implemented support for arrays and safe arrays in VARIANT data

structures. Also moved the SAFEARRAY definition (yet again) to the
obj_oleaut.h file.
oldstable
Francis Beaudet 1999-02-28 10:07:12 +00:00 committed by Alexandre Julliard
parent 11db496578
commit bc5477f7d2
4 changed files with 270 additions and 209 deletions

View File

@ -7,38 +7,6 @@
/* the following depend only on obj_base.h */
#include "wine/obj_oleaut.h"
/*****************************************************************
* SafeArray defines and structs
*/
#define FADF_AUTO ( 0x1 )
#define FADF_STATIC ( 0x2 )
#define FADF_EMBEDDED ( 0x4 )
#define FADF_FIXEDSIZE ( 0x10 )
#define FADF_BSTR ( 0x100 )
#define FADF_UNKNOWN ( 0x200 )
#define FADF_DISPATCH ( 0x400 )
#define FADF_VARIANT ( 0x800 )
#define FADF_RESERVED ( 0xf0e8 )
typedef struct tagSAFEARRAYBOUND
{
ULONG cElements; /* Number of elements in dimension */
LONG lLbound; /* Lower bound of dimension */
} SAFEARRAYBOUND;
typedef struct tagSAFEARRAY
{
USHORT cDims; /* Count of array dimension */
USHORT fFeatures; /* Flags describing the array */
ULONG cbElements; /* Size of each element */
ULONG cLocks; /* Number of lock on array */
PVOID pvData; /* Pointer to data valid when cLocks > 0 */
SAFEARRAYBOUND rgsabound[ 1 ]; /* One bound for each dimension */
} SAFEARRAY, *LPSAFEARRAY;
typedef enum tagCALLCONV {
CC_CDECL = 1,
CC_MSCPASCAL = CC_CDECL + 1,

View File

@ -65,6 +65,37 @@ typedef struct ISupportErrorInfo ISupportErrorInfo,*LPSUPPORTERRORINFO;
* Automation data types
*/
/*****************************************************************
* SafeArray defines and structs
*/
#define FADF_AUTO ( 0x1 )
#define FADF_STATIC ( 0x2 )
#define FADF_EMBEDDED ( 0x4 )
#define FADF_FIXEDSIZE ( 0x10 )
#define FADF_BSTR ( 0x100 )
#define FADF_UNKNOWN ( 0x200 )
#define FADF_DISPATCH ( 0x400 )
#define FADF_VARIANT ( 0x800 )
#define FADF_RESERVED ( 0xf0e8 )
typedef struct tagSAFEARRAYBOUND
{
ULONG cElements; /* Number of elements in dimension */
LONG lLbound; /* Lower bound of dimension */
} SAFEARRAYBOUND;
typedef struct tagSAFEARRAY
{
USHORT cDims; /* Count of array dimension */
USHORT fFeatures; /* Flags describing the array */
ULONG cbElements; /* Size of each element */
ULONG cLocks; /* Number of lock on array */
PVOID pvData; /* Pointer to data valid when cLocks > 0 */
SAFEARRAYBOUND rgsabound[ 1 ]; /* One bound for each dimension */
} SAFEARRAY, *LPSAFEARRAY;
/*
* Data types for Variants.
*/
@ -175,8 +206,8 @@ struct tagVARIANT {
DECIMAL decVal;
IUnknown* punkVal;
IDispatch* pdispVal;
SAFEARRAY* parray;
*/
SAFEARRAY* parray;
/* By reference
*/
@ -201,8 +232,8 @@ struct tagVARIANT {
DECIMAL* pdecVal;
IUnknown** ppunkVal;
IDispatch** ppdispVal;
SAFEARRAY** pparray;
*/
SAFEARRAY** pparray;
} _wine_tagVARIANT_UNION_NAME;
};

View File

@ -387,6 +387,13 @@ HRESULT WINAPI SafeArrayGetLBound(
UINT WINAPI SafeArrayGetDim(
SAFEARRAY * psa)
{
/*
* A quick test in Windows shows that the behavior here for an invalid
* pointer is to return 0.
*/
if(! validArg(psa))
return 0;
return psa->cDims;
}
@ -396,6 +403,13 @@ UINT WINAPI SafeArrayGetDim(
UINT WINAPI SafeArrayGetElemsize(
SAFEARRAY * psa)
{
/*
* A quick test in Windows shows that the behavior here for an invalid
* pointer is to return 0.
*/
if(! validArg(psa))
return 0;
return psa->cbElements;
}
@ -728,6 +742,12 @@ static BOOL validArg(
LONG descSize = 0;
LONG fullSize = 0;
/*
* Let's check for the null pointer just in case.
*/
if (psa == NULL)
return FALSE;
/* Check whether the size of the chunk make sens... That's the only thing
I can think of now... */

View File

@ -1646,10 +1646,8 @@ void WINAPI VariantInit(VARIANTARG* pvarg)
{
TRACE(ole,"(%p),stub\n",pvarg);
memset(pvarg, 0, sizeof (VARIANTARG));
pvarg->vt = VT_EMPTY;
pvarg->wReserved1 = 0;
pvarg->wReserved2= 0;
pvarg->wReserved3= 0;
return;
}
@ -1665,12 +1663,21 @@ void WINAPI VariantInit(VARIANTARG* pvarg)
HRESULT WINAPI VariantClear(VARIANTARG* pvarg)
{
HRESULT res = S_OK;
TRACE(ole,"(%p),stub\n",pvarg);
TRACE(ole,"(%p)\n",pvarg);
res = ValidateVariantType( pvarg->vt );
if( res == S_OK )
{
if( !( pvarg->vt & VT_BYREF ) )
{
/*
* The VT_ARRAY flag is a special case of a safe array.
*/
if ( (pvarg->vt & VT_ARRAY) != 0)
{
SafeArrayDestroy(pvarg->u.parray);
}
else
{
switch( pvarg->vt & VT_TYPEMASK )
{
@ -1684,17 +1691,18 @@ HRESULT WINAPI VariantClear(VARIANTARG* pvarg)
case( VT_UNKNOWN ):
break;
case( VT_SAFEARRAY ):
SafeArrayDestroy(pvarg->u.parray);
break;
default:
break;
}
}
}
/* Set the fields to empty.
/*
* Empty all the fields and mark the type as empty.
*/
pvarg->wReserved1 = 0;
pvarg->wReserved2 = 0;
pvarg->wReserved3 = 0;
memset(pvarg, 0, sizeof (VARIANTARG));
pvarg->vt = VT_EMPTY;
}
@ -1709,9 +1717,11 @@ HRESULT WINAPI VariantClear(VARIANTARG* pvarg)
HRESULT WINAPI VariantCopy(VARIANTARG* pvargDest, VARIANTARG* pvargSrc)
{
HRESULT res = S_OK;
TRACE(ole,"(%p, %p),stub\n", pvargDest, pvargSrc);
TRACE(ole,"(%p, %p)\n", pvargDest, pvargSrc);
res = ValidateVariantType( pvargSrc->vt );
/* If the pointer are to the same variant we don't need
* to do anything.
*/
@ -1730,11 +1740,19 @@ HRESULT WINAPI VariantCopy(VARIANTARG* pvargDest, VARIANTARG* pvargSrc)
pvargDest->vt = pvargSrc->vt;
}
else
{
/*
* The VT_ARRAY flag is another way to designate a safe array.
*/
if (pvargSrc->vt & VT_ARRAY)
{
SafeArrayCopy(pvargSrc->u.parray, &pvargDest->u.parray);
}
else
{
/* In the case of by value we need to
* copy the actuall value. In the case of
* VT_BSTR a copy of the string is made,
* if VT_ARRAY the entire array is copied
* if VT_DISPATCH or VT_IUNKNOWN AddReff is
* called to increment the object's reference count.
*/
@ -1750,16 +1768,19 @@ HRESULT WINAPI VariantCopy(VARIANTARG* pvargDest, VARIANTARG* pvargSrc)
case( VT_UNKNOWN ):
break;
case( VT_SAFEARRAY ):
SafeArrayCopy(pvargSrc->u.parray, &pvargDest->u.parray);
break;
default:
pvargDest->u = pvargSrc->u;
break;
}
pvargDest->vt = pvargSrc->vt;
}
pvargDest->vt = pvargSrc->vt;
}
}
}
return res;
}
@ -1773,9 +1794,11 @@ HRESULT WINAPI VariantCopy(VARIANTARG* pvargDest, VARIANTARG* pvargSrc)
HRESULT WINAPI VariantCopyInd(VARIANT* pvargDest, VARIANTARG* pvargSrc)
{
HRESULT res = S_OK;
TRACE(ole,"(%p, %p),stub\n", pvargDest, pvargSrc);
TRACE(ole,"(%p, %p)\n", pvargDest, pvargSrc);
res = ValidateVariantType( pvargSrc->vt );
if( res != S_OK )
return res;
@ -1783,6 +1806,7 @@ HRESULT WINAPI VariantCopyInd(VARIANT* pvargDest, VARIANTARG* pvargSrc)
{
VARIANTARG varg;
VariantInit( &varg );
/* handle the in place copy.
*/
if( pvargDest == pvargSrc )
@ -1792,14 +1816,26 @@ HRESULT WINAPI VariantCopyInd(VARIANT* pvargDest, VARIANTARG* pvargSrc)
res = VariantCopy( &varg, pvargSrc );
pvargSrc = &varg;
}
if( res == S_OK )
{
res = VariantClear( pvargDest );
if( res == S_OK )
{
/*
* The VT_ARRAY flag is another way to designate a safearray variant.
*/
if ( pvargSrc->vt & VT_ARRAY)
{
SafeArrayCopy(*pvargSrc->u.pparray, &pvargDest->u.parray);
}
else
{
/* In the case of by reference we need
* to copy the date pointed to by the variant.
*/
/* Get the variant type.
*/
switch( pvargSrc->vt & VT_TYPEMASK )
@ -1833,6 +1869,7 @@ HRESULT WINAPI VariantCopyInd(VARIANT* pvargDest, VARIANTARG* pvargSrc)
* that will be passed to the VariantCopyInd function.
*/
(pvargSrc->u.pvarVal)->wReserved1 |= PROCESSING_INNER_VARIANT;
/* Dereference the inner variant.
*/
res = VariantCopyInd( pvargDest, pvargSrc->u.pvarVal );
@ -1842,6 +1879,7 @@ HRESULT WINAPI VariantCopyInd(VARIANT* pvargDest, VARIANTARG* pvargSrc)
case( VT_UNKNOWN ):
break;
case( VT_SAFEARRAY ):
SafeArrayCopy(*pvargSrc->u.pparray, &pvargDest->u.parray);
break;
default:
/* This is a by reference Variant which means that the union
@ -1855,9 +1893,12 @@ HRESULT WINAPI VariantCopyInd(VARIANT* pvargDest, VARIANTARG* pvargSrc)
memcpy( &pvargDest->u, pvargSrc->u.byref, SizeOfVariantData( pvargSrc ) );
break;
}
}
pvargDest->vt = pvargSrc->vt & VT_TYPEMASK;
}
}
/* this should not fail.
*/
VariantClear( &varg );
@ -1866,6 +1907,7 @@ HRESULT WINAPI VariantCopyInd(VARIANT* pvargDest, VARIANTARG* pvargSrc)
{
res = VariantCopy( pvargDest, pvargSrc );
}
return res;
}