Implemented support for arrays and safe arrays in VARIANT data

structures. Also moved the SAFEARRAY definition (yet again) to the
obj_oleaut.h file.
This commit is contained in:
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 */ /* the following depend only on obj_base.h */
#include "wine/obj_oleaut.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 { typedef enum tagCALLCONV {
CC_CDECL = 1, CC_CDECL = 1,
CC_MSCPASCAL = CC_CDECL + 1, CC_MSCPASCAL = CC_CDECL + 1,

View File

@ -65,6 +65,37 @@ typedef struct ISupportErrorInfo ISupportErrorInfo,*LPSUPPORTERRORINFO;
* Automation data types * 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. * Data types for Variants.
*/ */
@ -175,8 +206,8 @@ struct tagVARIANT {
DECIMAL decVal; DECIMAL decVal;
IUnknown* punkVal; IUnknown* punkVal;
IDispatch* pdispVal; IDispatch* pdispVal;
SAFEARRAY* parray;
*/ */
SAFEARRAY* parray;
/* By reference /* By reference
*/ */
@ -201,8 +232,8 @@ struct tagVARIANT {
DECIMAL* pdecVal; DECIMAL* pdecVal;
IUnknown** ppunkVal; IUnknown** ppunkVal;
IDispatch** ppdispVal; IDispatch** ppdispVal;
SAFEARRAY** pparray;
*/ */
SAFEARRAY** pparray;
} _wine_tagVARIANT_UNION_NAME; } _wine_tagVARIANT_UNION_NAME;
}; };

View File

@ -387,6 +387,13 @@ HRESULT WINAPI SafeArrayGetLBound(
UINT WINAPI SafeArrayGetDim( UINT WINAPI SafeArrayGetDim(
SAFEARRAY * psa) 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; return psa->cDims;
} }
@ -396,6 +403,13 @@ UINT WINAPI SafeArrayGetDim(
UINT WINAPI SafeArrayGetElemsize( UINT WINAPI SafeArrayGetElemsize(
SAFEARRAY * psa) 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; return psa->cbElements;
} }
@ -728,6 +742,12 @@ static BOOL validArg(
LONG descSize = 0; LONG descSize = 0;
LONG fullSize = 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 /* Check whether the size of the chunk make sens... That's the only thing
I can think of now... */ I can think of now... */

View File

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