/*************************************************************************
 * OLE Automation
 * SafeArray Implementation
 *
 * This file contains the implementation of the SafeArray interface.
 *
 * Copyright 1999 Sylvain St-Germain
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

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

WINE_DEFAULT_DEBUG_CHANNEL(ole);

#define SYSDUPSTRING(str) SysAllocStringLen((str), SysStringLen(str))

/* Locally 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
static const 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 */
sizeof(BSTR),           /* VT_BSTR     [V][T][P][S] OLE Automation string*/
sizeof(LPDISPATCH),     /* 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*/
sizeof(VARIANT),        /* VT_VARIANT  [V][T][P][S] VARIANT *	*/
sizeof(LPUNKNOWN),      /* VT_UNKNOWN  [V][T]   [S] IUnknown * */
sizeof(DECIMAL),        /* 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	*/
};

static const int LAST_VARTYPE = sizeof(VARTYPE_SIZE)/sizeof(VARTYPE_SIZE[0]);


/*************************************************************************
 *		SafeArrayAllocDescriptor (OLEAUT32.36)
 * 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("SafeArray: %lu bytes allocated for descriptor.\n", allocSize);

  return(S_OK);
}

/*************************************************************************
 *		SafeArrayAllocDescriptorEx (OLEAUT32.429)
 * Allocate the appropriate amount of memory for the SafeArray descriptor
 *
 * This is a minimal implementation just to get things moving.
 *
 * The MSDN documentation on this doesn't tell us much.
 */
HRESULT WINAPI SafeArrayAllocDescriptorEx( 
  VARTYPE vt,
  UINT    cDims, 
  SAFEARRAY **ppsaOut) 
{
  if ( (vt >= LAST_VARTYPE) ||
       ( VARTYPE_SIZE[vt] == VARTYPE_NOT_SUPPORTED ) )
    return E_UNEXPECTED;

  return SafeArrayAllocDescriptor (cDims, ppsaOut);
}

/*************************************************************************
 *		SafeArrayAllocData (OLEAUT32.37)
 * 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("SafeArray: %lu bytes allocated for data at %p (%lu objects).\n", 
    psa->cbElements*ulWholeArraySize, psa->pvData, ulWholeArraySize);

  return(S_OK);
}

/*************************************************************************
 *		SafeArrayCreate (OLEAUT32.15)
 * 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("() : Failed to allocate the Safe Array data\n");
    return NULL;
  }

  return(psa); 
}

/*************************************************************************
 *		SafeArrayDestroyDescriptor (OLEAUT32.38)
 * 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);
}


/*************************************************************************
 *		SafeArrayLock (OLEAUT32.21)
 * 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);
}

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

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

  return(S_OK);
}


/*************************************************************************
 *		SafeArrayPutElement (OLEAUT32.26)
 * 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 */

  /* 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 */

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

    } else { 

      if(psa->fFeatures == FADF_BSTR) { /* Create a new object */
        BSTR pbstrReAllocStr = NULL;
        if(pv &&
           ((pbstrReAllocStr = SYSDUPSTRING( (OLECHAR*)pv )) == NULL)) {
          SafeArrayUnlock(psa);  
          return E_OUTOFMEMORY;
        } else 
          *((BSTR*)elementStorageAddress) = pbstrReAllocStr;
      }
      else if(psa->fFeatures == FADF_VARIANT) {
        HRESULT hr = VariantCopy(elementStorageAddress, pv);
        if (FAILED(hr)) {
          SafeArrayUnlock(psa);
          return hr;
        }
      }
      else /* duplicate the memory */
        memcpy(elementStorageAddress, pv, SafeArrayGetElemsize(psa) );
    }

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

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


/*************************************************************************
 *		SafeArrayGetElement (OLEAUT32.25)
 * 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 */

  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 */
      BSTR pbstrStoredStr = *(OLECHAR**)elementStorageAddress;
      BSTR pbstrReturnedStr = NULL;
      if( pbstrStoredStr &&
          ((pbstrReturnedStr = SYSDUPSTRING( pbstrStoredStr )) == NULL) ) {
        SafeArrayUnlock(psa);
        return E_OUTOFMEMORY;
      } else 
        *((BSTR*)pv) = pbstrReturnedStr; 
    }
    else if( psa->fFeatures == FADF_VARIANT) {
      HRESULT hr;
      VariantInit(pv);
      hr = VariantCopy(pv, elementStorageAddress);
      if (FAILED(hr)) {
        SafeArrayUnlock(psa);
        return hr;
      }
    }
    else if( isPointer(psa->fFeatures) )         /* simply copy the pointer */
      *(PVOID*)pv = *((PVOID*)elementStorageAddress); 
    else                                         /* copy the bytes */
      memcpy(pv, elementStorageAddress, psa->cbElements );

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

  return( SafeArrayUnlock(psa) );  
}

/*************************************************************************
 *		SafeArrayGetUBound (OLEAUT32.19)
 * 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;

  if(0 == nDim)
    return DISP_E_BADINDEX;

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

  return S_OK;
}

/*************************************************************************
 *		SafeArrayGetLBound (OLEAUT32.20)
 * 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;

  if(0 == nDim)
    return DISP_E_BADINDEX;
  
  *plLbound = psa->rgsabound[nDim-1].lLbound;
  return S_OK;
}

/*************************************************************************
 *		SafeArrayGetDim (OLEAUT32.17)
 * 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;
}

/*************************************************************************
 *		SafeArrayGetElemsize (OLEAUT32.18)
 * 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;
}

/*************************************************************************
 *		SafeArrayAccessData (OLEAUT32.23)
 * 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;
}


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

  return(SafeArrayUnlock(psa));
}

/************************************************************************ 
 *		SafeArrayPtrOfIndex (OLEAUT32.148)
 * 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;

  /* Although it is dangerous to do this without having a lock, it is not
   * illegal.  Microsoft do warn of the danger.
   */

  /* 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;
}

/************************************************************************ 
 *		SafeArrayDestroyData (OLEAUT32.39)
 * 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 */

  if(! validArg(psa)) 
    return E_INVALIDARG;

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

  ulWholeArraySize = getArraySize(psa);

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

    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 */
    BSTR bstr;

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

      if( bstr != NULL) 
        SysFreeString( bstr );
    }
  }
  else if(psa->fFeatures & FADF_VARIANT) {  /* deallocate the obj */

    for(ulDataIter=0; ulDataIter < ulWholeArraySize; ulDataIter++) {
      VariantClear((VARIANT*)((char *) psa->pvData+(ulDataIter*(psa->cbElements))));
    }
  }
      
  /* 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_CREATEVECTOR)) { /* 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;
}

/************************************************************************ 
 *		SafeArrayCopyData (OLEAUT32.412)
 * 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 );
    }
  }
  else if( (*psaTarget)->fFeatures & FADF_VARIANT) {

    for(lDelta=0;lDelta < ulWholeArraySize; lDelta++) {
      VariantClear((VARIANT*)((char *) (*psaTarget)->pvData + (lDelta * (*psaTarget)->cbElements)));
    }
  }

  return duplicateData(psaSource, psaTarget);
}

/************************************************************************ 
 *		SafeArrayDestroy (OLEAUT32.16)
 * 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 */
}

/************************************************************************ 
 *		SafeArrayCopy (OLEAUT32.27)
 * Make a dupplicate of a SafeArray
 */
HRESULT WINAPI SafeArrayCopy(
  SAFEARRAY *psa, 
  SAFEARRAY **ppsaOut)
{ 
  HRESULT hRes;
  DWORD   dAllocSize;
  ULONG   ulWholeArraySize; /* size of the thing */

  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 */

    /* make sure the new safe array doesn't have the FADF_CREATEVECTOR flag,
       because the data has not been allocated with the descriptor. */
    (*ppsaOut)->fFeatures &= ~FADF_CREATEVECTOR;  
 
    /* Get the allocated memory size for source and allocate it for target */ 
    ulWholeArraySize = getArraySize(psa); /* Number of item in SA */
    dAllocSize = ulWholeArraySize*psa->cbElements;

    (*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;
}

/************************************************************************ 
 *		SafeArrayCreateVector (OLEAUT32.411)
 * 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_CREATEVECTOR;  /* undocumented flag used by Microsoft */
  psa->cLocks     = 0;
  psa->pvData     = (BYTE*)psa + sizeof(*psa);
  psa->cbElements = VARTYPE_SIZE[vt];

  psa->rgsabound[0].cElements = cElements;
  psa->rgsabound[0].lLbound   = lLbound;

  return(psa); 				  
} 

/************************************************************************ 
 *		SafeArrayRedim (OLEAUT32.40)
 * 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;

  TRACE("elements=%ld, Lbound=%ld (delta=%ld)\n", psaboundNew->cElements, psaboundNew->lLbound, lDelta);

  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 makes sense... That's the only thing
     I can think of now... */

  psaSize = HeapSize(GetProcessHeap(), 0, psa);
  if (psaSize == -1)
    /* uh, foreign heap. Better don't mess with it ! */
    return TRUE;

  /* 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 );
      }
    else if(psa->fFeatures & FADF_VARIANT)
      for(;lDelta < 0; lDelta++) {
        VariantClear((VARIANT*)((char *) psa->pvData+((ulWholeArraySize+lDelta)*psa->cbElements)));
      }
  }

  if (!(psa->fFeatures & FADF_CREATEVECTOR))
  {
    /* 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(), HEAP_ZERO_MEMORY, 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
                      */
  }
  else
  {
    /* Allocate a new block, because the previous data has been allocated with 
       the descriptor in SafeArrayCreateVector function. */

    if((pvNewBlock = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
       ulWholeArraySize * psa->cbElements)) == NULL) 
        return FALSE;

    psa->fFeatures &= ~FADF_CREATEVECTOR;
  }
  /* 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_BSTR:      return FADF_BSTR;
    case VT_UNKNOWN:   return FADF_UNKNOWN;
    case VT_DISPATCH:  return FADF_DISPATCH;
    case VT_VARIANT:   return FADF_VARIANT;
  }
  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("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;

  if (!psa->cDims) return FALSE;
  for(; iter<psa->cDims; iter++) {
    TRACE("coor[%d]=%ld\n", iter, coor[iter]);
    if((hRes = SafeArrayGetLBound(psa, (iter+1), &lLBound)) != S_OK)
      return FALSE;
    if((hRes = SafeArrayGetUBound(psa, (iter+1), &lUBound)) != S_OK)
      return FALSE;
 
    if(lLBound > lUBound) 
      return FALSE; 

    if((coor[iter] < lLBound) || (coor[iter] > lUBound))
      return FALSE;
  }
  return TRUE;
}  

/************************************************************************ 
 * 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;

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

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

    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 */
    BSTR   pbstrReAllocStr = NULL;

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

        SafeArrayUnlock(*ppsaOut);
        return E_OUTOFMEMORY;
      }

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

  }
  else if( psa->fFeatures & FADF_VARIANT ) {

    for(lDelta=0; lDelta < ulWholeArraySize; lDelta++) {
      VariantCopy((VARIANT*)((char *) (*ppsaOut)->pvData+(lDelta * psa->cbElements)),
                  (VARIANT*)((char *) psa->pvData+(lDelta * psa->cbElements)));
    }

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

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

  SafeArrayUnlock(*ppsaOut);

  return S_OK;
}


/************************************************************************ 
 *		SafeArrayGetVarType (OLEAUT32.77)
 * Returns the VARTYPE stored in the given safearray
 */
HRESULT WINAPI SafeArrayGetVarType(
  SAFEARRAY* psa,
  VARTYPE*   pvt)
{
  HRESULT hr = E_INVALIDARG;
  VARTYPE vt = VT_EMPTY;

  /* const short VARTYPE_OFFSET = -4; */

  if (psa->fFeatures & FADF_HAVEVARTYPE)
  {
    /* VT tag @ negative offset 4 in the array descriptor */
    FIXME("Returning VT_BSTR instead of VT_...\n");
    vt = VT_BSTR;
  }
  else if (psa->fFeatures & FADF_RECORD)
  {
    vt = VT_RECORD;
  }
  else if (psa->fFeatures & FADF_BSTR)
  {
    vt = VT_BSTR;
  }
  else if (psa->fFeatures & FADF_UNKNOWN)
  {
    vt = VT_UNKNOWN;
  }
  else if (psa->fFeatures & FADF_DISPATCH)
  {
    vt = VT_DISPATCH;
  }
  else if (psa->fFeatures & FADF_VARIANT)
  {
    vt = VT_VARIANT;
  }

  if (vt != VT_EMPTY)
  {
    *pvt = vt;
    hr = S_OK;
  }

  TRACE("HRESULT = %08lx\n", hr);
  return hr;
}
