/*************************************************************************
 * OLE Automation
 * SafeArray Implementation
 *
 * This file contains the implementation of the SafeArray interface.
 *
 * Copyright 1999 Sylvain St-Germain
 */

#include <stdio.h>
#include <string.h>
#include "windef.h"
#include "winerror.h"
#include "winbase.h"
#include "oleauto.h"
#include "wine/obj_base.h"
#include "debug.h"

DEFAULT_DEBUG_CHANNEL(ole)

/* Localy used methods */
static INT  
endOfDim(LONG *coor, SAFEARRAYBOUND *mat, LONG dim, LONG realDim);

static ULONG   
calcDisplacement(LONG *coor, SAFEARRAYBOUND *mat, LONG dim);

static BOOL  
isPointer(USHORT feature);

static INT   
getFeatures(VARTYPE vt);

static BOOL  
validCoordinate(LONG *coor, SAFEARRAY *psa);

static BOOL  
resizeSafeArray(SAFEARRAY *psa, LONG lDelta);

static BOOL  
validArg(SAFEARRAY *psa);

static ULONG   
getArraySize(SAFEARRAY *psa);

static HRESULT 
duplicateData(SAFEARRAY *psa, SAFEARRAY **ppsaOut);

/* Association between VARTYPE and their size.
   A size of zero is defined for the unsupported types.  */

#define VARTYPE_NOT_SUPPORTED 0
const static ULONG VARTYPE_SIZE[] =
{
  /* this is taken from wtypes.h.  Only [S]es are supported by the SafeArray */
VARTYPE_NOT_SUPPORTED,	/* VT_EMPTY    [V]   [P]    nothing			*/
VARTYPE_NOT_SUPPORTED,	/* VT_NULL     [V]   [P]    SQL style Nul	*/
2,	                    /* VT_I2       [V][T][P][S] 2 byte signed int */
4, 	                    /* VT_I4       [V][T][P][S] 4 byte signed int */
4, 	                    /* VT_R4       [V][T][P][S] 4 byte real	*/
8,	                    /* VT_R8       [V][T][P][S] 8 byte real	*/
8,                      /* VT_CY       [V][T][P][S] currency */
8,	                    /* VT_DATE     [V][T][P][S] date */
4,	                    /* VT_BSTR     [V][T][P][S] OLE Automation string*/
4,	                    /* VT_DISPATCH [V][T][P][S] IDispatch *	*/
4,                      /* VT_ERROR    [V][T]   [S] SCODE	*/
4,	                    /* VT_BOOL     [V][T][P][S] True=-1, False=0*/
24,                     /* VT_VARIANT  [V][T][P][S] VARIANT *	*/
4,	                    /* VT_UNKNOWN  [V][T]   [S] IUnknown * */
16,	                    /* VT_DECIMAL  [V][T]   [S] 16 byte fixed point	*/
VARTYPE_NOT_SUPPORTED,                         /* no VARTYPE here..... */
VARTYPE_NOT_SUPPORTED,	/* VT_I1          [T]       signed char	*/
1,	                    /* VT_UI1      [V][T][P][S] unsigned char			*/
VARTYPE_NOT_SUPPORTED,	/* VT_UI2         [T][P]    unsigned short	*/
VARTYPE_NOT_SUPPORTED,	/* VT_UI4         [T][P]    unsigned short	*/
VARTYPE_NOT_SUPPORTED,	/* VT_I8          [T][P]    signed 64-bit int			*/
VARTYPE_NOT_SUPPORTED,	/* VT_UI8         [T][P]    unsigned 64-bit int		*/
VARTYPE_NOT_SUPPORTED,	/* VT_INT         [T]       signed machine int		*/
VARTYPE_NOT_SUPPORTED,	/* VT_UINT        [T]       unsigned machine int	*/
VARTYPE_NOT_SUPPORTED,	/* VT_VOID        [T]       C style void			*/
VARTYPE_NOT_SUPPORTED,	/* VT_HRESULT     [T]       Standard return type	*/
VARTYPE_NOT_SUPPORTED,	/* VT_PTR         [T]       pointer type			*/
VARTYPE_NOT_SUPPORTED,	/* VT_SAFEARRAY   [T]       (use VT_ARRAY in VARIANT)*/
VARTYPE_NOT_SUPPORTED,	/* VT_CARRAY      [T]       C style array			*/
VARTYPE_NOT_SUPPORTED,	/* VT_USERDEFINED [T]       user defined type			*/
VARTYPE_NOT_SUPPORTED,	/* VT_LPSTR       [T][P]    null terminated string	*/
VARTYPE_NOT_SUPPORTED,	/* VT_LPWSTR      [T][P]    wide null term string		*/
VARTYPE_NOT_SUPPORTED,	/* VT_FILETIME       [P]    FILETIME			*/
VARTYPE_NOT_SUPPORTED,	/* VT_BLOB           [P]    Length prefixed bytes */
VARTYPE_NOT_SUPPORTED,	/* VT_STREAM         [P]    Name of stream follows		*/
VARTYPE_NOT_SUPPORTED,	/* VT_STORAGE        [P]    Name of storage follows	*/
VARTYPE_NOT_SUPPORTED,	/* VT_STREAMED_OBJECT[P]    Stream contains an object*/
VARTYPE_NOT_SUPPORTED,	/* VT_STORED_OBJECT  [P]    Storage contains object*/
VARTYPE_NOT_SUPPORTED,	/* VT_BLOB_OBJECT    [P]    Blob contains an object*/
VARTYPE_NOT_SUPPORTED,	/* VT_CF             [P]    Clipboard format			*/
VARTYPE_NOT_SUPPORTED,	/* VT_CLSID          [P]    A Class ID			*/
VARTYPE_NOT_SUPPORTED,	/* VT_VECTOR         [P]    simple counted array		*/
VARTYPE_NOT_SUPPORTED,	/* VT_ARRAY    [V]          SAFEARRAY*			*/
VARTYPE_NOT_SUPPORTED 	/* VT_BYREF    [V]          void* for local use	*/
};

const static int LAST_VARTYPE = sizeof(VARTYPE_SIZE)/sizeof(ULONG);


/*************************************************************************
 * Allocate the appropriate amount of memory for the SafeArray descriptor
 */
HRESULT WINAPI SafeArrayAllocDescriptor( 
  UINT    cDims, 
  SAFEARRAY **ppsaOut) 
{
  SAFEARRAYBOUND *sab;
  LONG allocSize = 0;

  /* SAFEARRAY + SAFEARRAYBOUND * (cDims -1) ( -1 because there is already one
                                             ( in SAFEARRAY struct */
  allocSize = sizeof(**ppsaOut) + (sizeof(*sab) * (cDims-1));

  /* Allocate memory for SAFEARRAY struc */
  if(( (*ppsaOut)=HeapAlloc( 
        GetProcessHeap(), HEAP_ZERO_MEMORY, allocSize)) == NULL){
    return(E_UNEXPECTED);
  }
  TRACE(ole,"SafeArray: %lu bytes allocated for descriptor.\n", allocSize);

  return(S_OK);
}

/*************************************************************************
 * Allocate the appropriate amount of data for the SafeArray data
 */
HRESULT WINAPI SafeArrayAllocData(
  SAFEARRAY *psa) 
{
  ULONG  ulWholeArraySize;   /* to store the size of the whole thing */

  if(! validArg(psa)) 
    return E_INVALIDARG;

  ulWholeArraySize = getArraySize(psa);

  /* Allocate memory for the data itself */
  if((psa->pvData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 
        psa->cbElements*ulWholeArraySize)) == NULL)
    return(E_UNEXPECTED);

  TRACE(ole, "SafeArray: %lu bytes allocated for data at %p (%lu objects).\n", 
    psa->cbElements*ulWholeArraySize, psa->pvData, ulWholeArraySize);

  return(S_OK);
}

/*************************************************************************
 * Create a SafeArray object by encapsulating AllocDescriptor and AllocData 
 */
SAFEARRAY* WINAPI SafeArrayCreate(
  VARTYPE        vt, 
  UINT         cDims, 
  SAFEARRAYBOUND *rgsabound)
{
  SAFEARRAY *psa;
  HRESULT   hRes;
  USHORT    cDim;

  /* Validate supported VARTYPE */
  if ( (vt >= LAST_VARTYPE) ||
       ( VARTYPE_SIZE[vt] == VARTYPE_NOT_SUPPORTED ) )
    return NULL;

  /* Allocate memory for the array descriptor */
  if( FAILED( hRes = SafeArrayAllocDescriptor(cDims, &psa)))
    return NULL;

  /* setup data members... */ 
  psa->cDims     = cDims;
  psa->fFeatures = getFeatures(vt);
  psa->cLocks    = 0;
  psa->pvData    = NULL;
  psa->cbElements= VARTYPE_SIZE[vt];

  /* Invert the bounds ... */
  for(cDim=0; cDim < psa->cDims; cDim++) {
    psa->rgsabound[cDim].cElements = rgsabound[psa->cDims-cDim-1].cElements;
    psa->rgsabound[cDim].lLbound   = rgsabound[psa->cDims-cDim-1].lLbound;
  }

  /* allocate memory for the data... */ 
  if( FAILED( hRes = SafeArrayAllocData(psa))) {
    SafeArrayDestroyDescriptor(psa); 
    ERR(ole,"() : Failed to allocate the Safe Array data\n");
    return NULL;
  }

  return(psa); 
}

/*************************************************************************
 * Frees the memory associated with the descriptor.
 */
HRESULT WINAPI SafeArrayDestroyDescriptor(
  SAFEARRAY *psa)
{
  /* Check for lockness before to free... */
  if(psa->cLocks > 0) 
    return DISP_E_ARRAYISLOCKED;

  /* The array is unlocked, then, deallocate memory */
  if(HeapFree( GetProcessHeap(), 0, psa) == FALSE) 
    return E_UNEXPECTED;
  
  return(S_OK);
}


/*************************************************************************
 * Increment the lock counter
 *
 * Doc says (MSDN Library ) that psa->pvData should be made available (!= NULL)
 * only when psa->cLocks is > 0... I don't get it since pvData is allocated 
 * before the array is locked, therefore  
 */
HRESULT WINAPI SafeArrayLock(
  SAFEARRAY *psa)
{
  if(! validArg(psa))     
    return E_INVALIDARG;

  psa->cLocks++;

  return(S_OK);
}

/*************************************************************************
 * Decrement the lock counter
 */
HRESULT WINAPI SafeArrayUnlock(
  SAFEARRAY *psa)
{
  if(! validArg(psa)) 
    return E_INVALIDARG;

  if (psa->cLocks > 0) 
    psa->cLocks--;

  return(S_OK);
}


/*************************************************************************
 * Set the data at the given coordinate
 */
HRESULT WINAPI SafeArrayPutElement(
  SAFEARRAY *psa, 
  LONG      *rgIndices, 
  void      *pv)
{
  ULONG stepCountInSAData     = 0;    /* Number of array item to skip to get to 
                                         the desired one... */
  PVOID elementStorageAddress = NULL; /* Adress to store the data */
  BSTR  pbstrReAllocStr     = NULL; /* BSTR reallocated */

  /* Validate the index given */
  if(! validCoordinate(rgIndices, psa)) 
    return DISP_E_BADINDEX;
  if(! validArg(psa))
    return E_INVALIDARG;

  if( SafeArrayLock(psa) == S_OK) {

    /* Figure out the number of items to skip */
    stepCountInSAData = calcDisplacement(rgIndices, psa->rgsabound, psa->cDims);
  
    /* Figure out the number of byte to skip ... */
    elementStorageAddress = (char *) psa->pvData+(stepCountInSAData*psa->cbElements);
  
    if(isPointer(psa->fFeatures)) { /* increment ref count for this pointer */

      *((VOID**)elementStorageAddress) = *(VOID**)pv; 
      IUnknown_AddRef( *(IUnknown**)pv);

    } else { 

      if(psa->fFeatures == FADF_BSTR) { /* Create a new object */

        if((pbstrReAllocStr = SysAllocString( (OLECHAR*)pv )) == NULL) {
          SafeArrayUnlock(psa);  
          return E_OUTOFMEMORY;
        } else 
          *((BSTR*)elementStorageAddress) = pbstrReAllocStr;

      } else /* dupplicate the memory */
        memcpy(elementStorageAddress, pv, SafeArrayGetElemsize(psa) );
    }

  } else {
    ERR(ole, "SafeArray: Cannot lock array....\n");
    return E_UNEXPECTED; /* UNDOC error condition */
  }

  TRACE(ole,"SafeArray: item put at adress %p.\n",elementStorageAddress);
  return SafeArrayUnlock(psa);  
}


/*************************************************************************
 * Return the data element corresponding the the given coordinate
 */
HRESULT WINAPI SafeArrayGetElement(
  SAFEARRAY *psa, 
  LONG      *rgIndices, 
  void      *pv)
{
  ULONG stepCountInSAData     = 0;    /* Number of array item to skip to get to 
                                         the desired one... */
  PVOID elementStorageAddress = NULL; /* Adress to store the data */
  BSTR  pbstrReturnedStr    = NULL; /* BSTR reallocated */

  if(! validArg(psa)) 
    return E_INVALIDARG;
  
  if(! validCoordinate(rgIndices, psa)) /* Validate the index given */
    return(DISP_E_BADINDEX);

  if( SafeArrayLock(psa) == S_OK) {

    /* Figure out the number of items to skip */
    stepCountInSAData = calcDisplacement(rgIndices, psa->rgsabound, psa->cDims);
  
    /* Figure out the number of byte to skip ... */
    elementStorageAddress = (char *) psa->pvData+(stepCountInSAData*psa->cbElements);
  
    if( psa->fFeatures == FADF_BSTR) {           /* reallocate the obj */
      if( (pbstrReturnedStr = 
          SysAllocString( *(OLECHAR**)elementStorageAddress )) == NULL) {
        SafeArrayUnlock(psa);
        return E_OUTOFMEMORY;
      } else 
        *((BSTR*)pv) = pbstrReturnedStr; 
        
    } else if( isPointer(psa->fFeatures) )       /* simply copy the pointer */
       pv = *((PVOID*)elementStorageAddress); 
    else                                         /* copy the bytes */
      memcpy(pv, elementStorageAddress, SafeArrayGetElemsize(psa) );

  } else {
    ERR(ole, "SafeArray: Cannot lock array....\n");
    return E_UNEXPECTED; /* UNDOC error condition */
  }

  return( SafeArrayUnlock(psa) );  
}

/*************************************************************************
 * return the UP bound for a given array dimension
 */
HRESULT WINAPI SafeArrayGetUBound(
  SAFEARRAY *psa, 
  UINT    nDim,
  LONG      *plUbound)
{
  if(! validArg(psa))   
    return E_INVALIDARG;

  if(nDim > psa->cDims) 
    return DISP_E_BADINDEX;

  *plUbound = psa->rgsabound[nDim-1].lLbound + 
              psa->rgsabound[nDim-1].cElements - 1;

  return S_OK;
}

/*************************************************************************
 * Return the LO bound for a given array dimension 
 */
HRESULT WINAPI SafeArrayGetLBound(
  SAFEARRAY *psa,
  UINT    nDim, 
  LONG      *plLbound)
{
  if(! validArg(psa))   
    return E_INVALIDARG;

  if(nDim > psa->cDims) 
    return DISP_E_BADINDEX;

  *plLbound = psa->rgsabound[nDim-1].lLbound;
  return S_OK;
}

/*************************************************************************
 * returns the number of dimension in the array
 */
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;
}

/*************************************************************************
 * Return the size of the element in the array
 */
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;
}

/*************************************************************************
 * increment the access count and return the data 
 */
HRESULT WINAPI SafeArrayAccessData(
  SAFEARRAY *psa, 
  void      **ppvData)
{ 
  HRESULT hRes;

  if(! validArg(psa)) 
    return E_INVALIDARG;

  hRes = SafeArrayLock(psa);

  switch (hRes) {
    case S_OK: 
      (*ppvData) = psa->pvData;
      break;
    case E_INVALIDARG:
      (*ppvData) = NULL;
      return E_INVALIDARG;
  }
  
  return S_OK;
}


/*************************************************************************
 * Decrement the access count
 */
HRESULT WINAPI SafeArrayUnaccessData(
  SAFEARRAY * psa)
{ 
  if(! validArg(psa)) 
    return E_INVALIDARG;

  return(SafeArrayUnlock(psa));
}

/************************************************************************ 
 * Return a pointer to the element at rgIndices
 */
HRESULT WINAPI SafeArrayPtrOfIndex(
  SAFEARRAY *psa, 
  LONG      *rgIndices, 
  void      **ppvData)
{ 
  ULONG stepCountInSAData     = 0;    /* Number of array item to skip to get to 
                                         the desired one... */

  if(! validArg(psa))                   
    return E_INVALIDARG;

  if(! validCoordinate(rgIndices, psa)) 
    return DISP_E_BADINDEX;

  /* Figure out the number of items to skip */
  stepCountInSAData = calcDisplacement(rgIndices, psa->rgsabound, psa->cDims);
  
  *ppvData = (char *) psa->pvData+(stepCountInSAData*psa->cbElements);

  return S_OK;
}

/************************************************************************ 
 * Frees the memory data bloc
 */
HRESULT WINAPI SafeArrayDestroyData(
  SAFEARRAY *psa)
{ 
  HRESULT  hRes;
  ULONG    ulWholeArraySize; /* count spot in array  */
  ULONG    ulDataIter;       /* to iterate the data space */
  IUnknown *punk;
  BSTR   bstr;

  if(! validArg(psa)) 
    return E_INVALIDARG;

  if(psa->cLocks > 0) 
    return DISP_E_ARRAYISLOCKED;

  ulWholeArraySize = getArraySize(psa);

  if(isPointer(psa->fFeatures)) {           /* release the pointers */

    for(ulDataIter=0; ulDataIter < ulWholeArraySize; ulDataIter++) {
      punk = *(IUnknown**)((char *) psa->pvData+(ulDataIter*(psa->cbElements)));	

      if( punk != NULL) 
        IUnknown_Release(punk);
    }

  } else if(psa->fFeatures & FADF_BSTR) {  /* deallocate the obj */

    for(ulDataIter=0; ulDataIter < ulWholeArraySize; ulDataIter++) {
      bstr = *(BSTR*)((char *) psa->pvData+(ulDataIter*(psa->cbElements)));

      if( bstr != NULL) 
        SysFreeString( bstr );
    }
  }
      
  /* check if this array is a Vector, in which case do not free the data 
     block since it has been allocated by AllocDescriptor and therefore
     deserve to be freed by DestroyDescriptor */
  if(!(psa->fFeatures & FADF_FIXEDSIZE)) { /* Set when we do CreateVector */

    /* free the whole chunk */
    if((hRes = HeapFree( GetProcessHeap(), 0, psa->pvData)) == 0) /*falied*/
      return E_UNEXPECTED; /* UNDOC error condition */

    psa->pvData = NULL;
  }
  
  return S_OK;
}

/************************************************************************ 
 * Copy the psaSource's data block into psaTarget if dimension and size
 * permits it.
 */
HRESULT WINAPI SafeArrayCopyData(
  SAFEARRAY *psaSource,
  SAFEARRAY **psaTarget)
{ 
  USHORT   cDimCount;        /* looper */
  LONG     lDelta;           /* looper */
  IUnknown *punk;   
  ULONG    ulWholeArraySize; /* Number of item in SA */
  BSTR   bstr;

  if(! (validArg(psaSource) && validArg(*psaTarget)) ) 
    return E_INVALIDARG;

  if(SafeArrayGetDim(psaSource) != SafeArrayGetDim(*psaTarget))
    return E_INVALIDARG;

  ulWholeArraySize = getArraySize(psaSource); 

  /* The two arrays boundaries must be of same lenght */
  for(cDimCount=0;cDimCount < psaSource->cDims; cDimCount++)
    if( psaSource->rgsabound[cDimCount].cElements != 
      (*psaTarget)->rgsabound[cDimCount].cElements)
      return E_INVALIDARG;

  if( isPointer((*psaTarget)->fFeatures) ) {         /* the target contains ptr 
                                                        that must be released */
    for(lDelta=0;lDelta < ulWholeArraySize; lDelta++) {
      punk = *(IUnknown**)
        ((char *) (*psaTarget)->pvData + (lDelta * (*psaTarget)->cbElements));

      if( punk != NULL) 
        IUnknown_Release(punk);
    }

  } else if( (*psaTarget)->fFeatures & FADF_BSTR) {  /* the target contain BSTR
                                                        that must be freed */ 
    for(lDelta=0;lDelta < ulWholeArraySize; lDelta++) {
      bstr = 
        *(BSTR*)((char *) (*psaTarget)->pvData + (lDelta * (*psaTarget)->cbElements));

      if( bstr != NULL) 
        SysFreeString( bstr );
    }
  }

  return duplicateData(psaSource, psaTarget);
}

/************************************************************************ 
 * Deallocates all memory reserved for the SafeArray
 */
HRESULT WINAPI SafeArrayDestroy(
  SAFEARRAY * psa)
{ 
  HRESULT hRes;

  if(! validArg(psa)) 
    return E_INVALIDARG;

  if(psa->cLocks > 0) 
    return DISP_E_ARRAYISLOCKED;

  if((hRes = SafeArrayDestroyData( psa )) == S_OK)
    if((hRes = SafeArrayDestroyDescriptor( psa )) == S_OK)
      return S_OK;

  return E_UNEXPECTED; /* UNDOC error condition */
}

/************************************************************************ 
 * Make a dupplicate of a SafeArray
 */
HRESULT WINAPI SafeArrayCopy(
  SAFEARRAY *psa, 
  SAFEARRAY **ppsaOut)
{ 
  HRESULT hRes;
  DWORD   dAllocSize;

  if(! validArg(psa)) 
    return E_INVALIDARG;

  if((hRes=SafeArrayAllocDescriptor(psa->cDims, ppsaOut)) == S_OK){

    /* Duplicate the SAFEARRAY struc */
    memcpy(*ppsaOut, psa, 
            sizeof(*psa)+(sizeof(*(psa->rgsabound))*(psa->cDims-1)));

    (*ppsaOut)->pvData = NULL; /* do not point to the same data area */
  
    /* Get the allocated memory size for source and allocate it for target */ 
    dAllocSize = HeapSize(GetProcessHeap(), 0, psa->pvData);
    (*ppsaOut)->pvData = 
      HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dAllocSize);

    if( (*ppsaOut)->pvData != NULL) {   /* HeapAlloc succeed */

      if( (hRes=duplicateData(psa, ppsaOut)) != S_OK) { /* E_OUTOFMEMORY */
        HeapFree(GetProcessHeap(), 0, (*ppsaOut)->pvData);
        (*ppsaOut)->pvData = NULL;
        SafeArrayDestroyDescriptor(*ppsaOut);
        return hRes;
      }
        
    } else { /* failed to allocate or dupplicate... */
      SafeArrayDestroyDescriptor(*ppsaOut);
      return E_UNEXPECTED; /* UNDOC error condition */
    }
  } else { /* failed to allocate mem for descriptor */
    return E_OUTOFMEMORY; /* UNDOC error condiftion */
  }

  return S_OK;
}

/************************************************************************ 
 * Creates a one dimension safearray where the data is next to the 
 * SAFEARRAY structure.
 */
SAFEARRAY* WINAPI SafeArrayCreateVector(
  VARTYPE vt, 
  LONG    lLbound, 
  ULONG   cElements) 
{ 
  SAFEARRAY *psa;

  /* Validate supported VARTYPE */
  if ( (vt >= LAST_VARTYPE) ||
       ( VARTYPE_SIZE[vt] == VARTYPE_NOT_SUPPORTED ) )
    return NULL;

  /* Allocate memory for the array descriptor and data contiguously  */
  if( FAILED( psa = HeapAlloc( GetProcessHeap(), 
                      HEAP_ZERO_MEMORY, 
                      (sizeof(*psa) + (VARTYPE_SIZE[vt] * cElements))))) {
    return NULL;
  }

  /* setup data members... */ 
  psa->cDims      = 1; /* always and forever */
  psa->fFeatures  = getFeatures(vt) | FADF_FIXEDSIZE;
  psa->cLocks     = 0;
  psa->pvData     = psa+sizeof(*psa);
  psa->cbElements = VARTYPE_SIZE[vt];

  psa->rgsabound[0].cElements = cElements;
  psa->rgsabound[0].lLbound   = lLbound;
  
  return(psa); 
} 

/************************************************************************ 
 * Changes the caracteristics of the last dimension of the SafeArray
 */
HRESULT WINAPI SafeArrayRedim(
  SAFEARRAY      *psa, 
  SAFEARRAYBOUND *psaboundNew)
{ 
  LONG   lDelta;  /* hold difference in size */
  USHORT cDims=1; /* dims counter */

  if( !validArg(psa) )                    
    return E_INVALIDARG;

  if( psa->cLocks > 0 )                    
    return DISP_E_ARRAYISLOCKED;

  if( psa->fFeatures & FADF_FIXEDSIZE )    
    return E_INVALIDARG;

  if( SafeArrayLock(psa)==E_UNEXPECTED ) 
    return E_UNEXPECTED;/* UNDOC error condition */

  /* find the delta in number of array spot to apply to the new array */
  lDelta = psaboundNew->cElements - psa->rgsabound[0].cElements;
  for(; cDims < psa->cDims; cDims++)
    /* delta in number of spot implied by modifying the last dimension */
    lDelta *= psa->rgsabound[cDims].cElements;

  if (lDelta == 0) { ;/* same size, maybe a change of lLbound, just set it */

  } else /* need to enlarge (lDelta +) reduce (lDelta -) */
    if(! resizeSafeArray(psa, lDelta)) 
      return E_UNEXPECTED; /* UNDOC error condition */

  /* the only modifyable dimension sits in [0] as the dimensions were reversed  
     at array creation time... */
  psa->rgsabound[0].cElements = psaboundNew->cElements;
  psa->rgsabound[0].lLbound   = psaboundNew->lLbound;

  return SafeArrayUnlock(psa);
}

/************************************************************************
 * NOT WINDOWS API - SafeArray* Utility functions
 ************************************************************************/

/************************************************************************ 
 * Used to validate the SAFEARRAY type of arg
 */
static BOOL validArg(
  SAFEARRAY *psa) 
{
  SAFEARRAYBOUND *sab;
  LONG psaSize  = 0;
  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... */

  psaSize   = HeapSize(GetProcessHeap(), 0, psa);

  /* size of the descriptor when the SA is not created with CreateVector */
  descSize = sizeof(*psa) + (sizeof(*sab) * (psa->cDims-1));

  /* size of the descriptor + data when created with CreateVector */
  fullSize = sizeof(*psa) + (psa->cbElements * psa->rgsabound[0].cElements);

  return((psaSize >= descSize) || (psaSize >= fullSize));
}

/************************************************************************ 
 * Used to reallocate memory
 */
static BOOL resizeSafeArray(
  SAFEARRAY *psa, 
  LONG lDelta)
{
  ULONG    ulWholeArraySize;  /* use as multiplicator */
  PVOID    pvNewBlock = NULL;  
  IUnknown *punk;
  BSTR   bstr;

  ulWholeArraySize = getArraySize(psa);

  if(lDelta < 0) {                    /* array needs to be shorthen  */
    if( isPointer(psa->fFeatures))    /* ptr that need to be released */
	    for(;lDelta < 0; lDelta++) {
	      punk = *(IUnknown**)
          ((char *) psa->pvData+((ulWholeArraySize+lDelta)*psa->cbElements));
	
        if( punk != NULL )
          IUnknown_Release(punk);
	    }

    else if(psa->fFeatures & FADF_BSTR)  /* BSTR that need to be freed */
	    for(;lDelta < 0; lDelta++) {
        bstr = *(BSTR*)
          ((char *) psa->pvData+((ulWholeArraySize+lDelta)*psa->cbElements));

        if( bstr != NULL )
          SysFreeString( bstr );
      }
  }

  /* Ok now, if we are enlarging the array, we *MUST* move the whole block 
     pointed to by pvData.   If we are shorthening the array, this move is
     optional but we do it anyway becuase the benefit is that we are 
     releasing to the system the unused memory */
  
  if((pvNewBlock = HeapReAlloc(GetProcessHeap(), 0, psa->pvData, 
     (ulWholeArraySize + lDelta) * psa->cbElements)) == NULL) 
      return FALSE; /* TODO If we get here it means:
                       SHRINK situation :  we've deleted the undesired
                                           data and did not release the memory
                       GROWING situation:  we've been unable to grow the array
                    */

  /* reassign to the new block of data */
  psa->pvData = pvNewBlock;
  return TRUE;
}

/************************************************************************ 
 * Used to set the fFeatures data member of the SAFEARRAY structure. 
 */
static INT getFeatures(
  VARTYPE vt) 
{
  switch(vt) {
    case VT_UNKNOWN:   return FADF_UNKNOWN;
    case VT_DISPATCH:  return FADF_DISPATCH;
    case VT_BSTR:      return FADF_BSTR;
  }
  return 0;
}

/************************************************************************ 
 * Used to figure out if the fFeatures data member of the SAFEARRAY 
 * structure contain any information about the type of data stored... 
 */
static BOOL isPointer(
  USHORT feature) 
{
  switch(feature) {
    case FADF_UNKNOWN:  return TRUE; /* those are pointers */
    case FADF_DISPATCH: return TRUE;
  }
  return FALSE;
}

/************************************************************************ 
 * Used to calculate the displacement when accessing or modifying 
 * safearray data set.
 *
 *  Parameters: - LONG *coor is the desired location in the multidimension
 *              table.  Ex for a 3 dim table: coor[] = {1,2,3};
 *              - ULONG *mat is the format of the table.  Ex for a 3 dim
 *              table mat[] = {4,4,4};
 *              - USHORT dim is the number of dimension of the SafeArray
 */
static ULONG calcDisplacement(
  LONG           *coor, 
  SAFEARRAYBOUND *mat, 
  LONG           dim) 
{
  ULONG res = 0;
  LONG  iterDim;

  for(iterDim=0; iterDim<dim; iterDim++) 
    /* the -mat[dim] bring coor[dim] relative to 0 for calculation */
    res += ((coor[iterDim]-mat[iterDim].lLbound) * 
            endOfDim(coor, mat, iterDim+1, dim));

  TRACE(ole, "SafeArray: calculated displacement is %lu.\n", res);
  return(res);
}

/************************************************************************ 
 * Recursivity agent for calcDisplacement method.  Used within Put and 
 * Get methods.
 */
static INT endOfDim(
  LONG           *coor, 
  SAFEARRAYBOUND *mat, 
  LONG           dim, 
  LONG           realDim) 
{
  if(dim==realDim) 
    return 1;
  else 
    return (endOfDim(coor, mat, dim+1, realDim) * mat[dim].cElements);
}


/************************************************************************ 
 * Method used to validate the coordinate received in Put and Get 
 * methods.
 */
static BOOL validCoordinate(
  LONG      *coor, 
  SAFEARRAY *psa) 
{
  INT   iter=0;
  LONG    lUBound;
  LONG    lLBound;
  HRESULT hRes;

  for(; iter<psa->cDims; iter++) {
    if((hRes = SafeArrayGetLBound(psa, iter, &lLBound)) != S_OK)
      return FALSE;
    if((hRes = SafeArrayGetUBound(psa, iter, &lUBound)) != S_OK)
      return FALSE;
 
    if(lLBound == lUBound) 
      return FALSE; 
   
    if((coor[iter] >= lLBound) && (coor[iter] <= lUBound))
      return TRUE;
    else
      return FALSE;
  }
  return FALSE;
}  

/************************************************************************ 
 * Method used to calculate the number of cells of the SA
 */
static ULONG getArraySize(
  SAFEARRAY *psa) 
{
  USHORT cCount; 
  ULONG  ulWholeArraySize = 1;

  for(cCount=0; cCount < psa->cDims; cCount++) /* foreach dimensions... */
    ulWholeArraySize *= psa->rgsabound[cCount].cElements;

  return ulWholeArraySize;  
}


/************************************************************************ 
 * Method used to handle data space dupplication for Copy32 and CopyData32
 */
static HRESULT duplicateData(
  SAFEARRAY *psa, 
  SAFEARRAY **ppsaOut) 
{
  ULONG    ulWholeArraySize; /* size of the thing */
  LONG     lDelta;
  IUnknown *punk;
  BSTR   pbstrReAllocStr = NULL; /* BSTR reallocated */

  ulWholeArraySize = getArraySize(psa); /* Number of item in SA */
  
  SafeArrayLock(*ppsaOut);

  if( isPointer(psa->fFeatures) ) {  /* If datatype is object increment 
                                        object's reference count */

    for(lDelta=0; lDelta < ulWholeArraySize; lDelta++) {
      punk = *(IUnknown**)((char *) psa->pvData+(lDelta * psa->cbElements));

      if( punk != NULL)
        IUnknown_AddRef(punk);
    }

    /* Copy the source array data into target array */
    memcpy((*ppsaOut)->pvData, psa->pvData, 
      ulWholeArraySize*psa->cbElements);

  } else if( psa->fFeatures & FADF_BSTR ) { /* if datatype is BSTR allocate 
                                               the BSTR in the new array */

    for(lDelta=0; lDelta < ulWholeArraySize; lDelta++) {
      if(( pbstrReAllocStr = SysAllocString(
            *(BSTR*)((char *) psa->pvData+(lDelta * psa->cbElements)))) == NULL) {

        SafeArrayUnlock(*ppsaOut);
        return E_OUTOFMEMORY;
      }

      *((BSTR*)((char *) (*ppsaOut)->pvData+(lDelta * psa->cbElements))) = 
        pbstrReAllocStr;
    }

  } else { /* Simply copy the source array data into target array */

    memcpy((*ppsaOut)->pvData, psa->pvData, 
      ulWholeArraySize*psa->cbElements);
  }

  SafeArrayUnlock(*ppsaOut);

  return S_OK;
}

