//
// © Copyright 1996 National Instruments
// 
// CCWSafeArray encapsulates OLE SafeArrays and Variants holding SafeArrays
// its primary purpose is to aid in constructing parameters to be passed 
// to ComponentWorks(tm) contorls.
//

#ifndef __CWSAFEARRAY_H__
#define __CWSAFEARRAY_H__
 
class CCWSafeArray {

// Constructors
public:
	// Constructors that create a CCWSafeArray with all element set to zero
	// The lbound of each dim will be 0.
	CCWSafeArray(VARTYPE vt, long lDim1, long lDim2 = -1, long lDim3 = -1);

	// Constructors that create a CCWSafeArray and initialize it with
	// existing data. The lbound of each dim will be 0.
	CCWSafeArray(unsigned char  *pbData, long lDim1, long lDim2 = -1, long lDim3 = -1);
	CCWSafeArray(signed char    *pbData, long lDim1, long lDim2 = -1, long lDim3 = -1);
	CCWSafeArray(short			*pwData, long lDim1, long lDim2 = -1, long lDim3 = -1);
	CCWSafeArray(unsigned short *pwData, long lDim1, long lDim2 = -1, long lDim3 = -1);
	CCWSafeArray(long			*plData, long lDim1, long lDim2 = -1, long lDim3 = -1);
	CCWSafeArray(float			*psData, long lDim1, long lDim2 = -1, long lDim3 = -1);
	CCWSafeArray(double			*pdData, long lDim1, long lDim2 = -1, long lDim3 = -1); 
		
	// Construct from an existing SAFEARRAY. 
	CCWSafeArray(SAFEARRAY *pSafeArray, VARTYPE vt);

	// Construct from an existing VARIANT that refers to a SafeArray.
	CCWSafeArray(VARIANT vVariant);

	~CCWSafeArray();

// Operators
public:
	operator	VARIANT();
	operator	LPVARIANT();
	operator	LPSAFEARRAY();
	operator	LPSAFEARRAY*();

// Implementation
public:
	long		GetDimSize(long lDim);	// Size of one dimension
	long		GetDimSize();			// Total number of elements
	long		GetEltSize();			// Size of one element in bytes
	long		GetNDims();				// Number of dimensions
	VARTYPE		GetVarType();			// The type of each element
	void*		AccessData();			// lock and get a pointer to the data
	void		UnaccessData();			// unlock ( pointer is no longer good) 
	void		Lock();
	void		Unlock();
	VARIANT		GetVARIANTTransferOwnership();		
	SAFEARRAY*	GetSAFEARRAYTransferOwnership();				
	void		Redim(long lDim1, long lDim2 = -1, long lDim3 = -1);

private:
	void		InitSafeArrayFromData(VARTYPE vt, void* pvData, long lDim1, long lDim2 = -1, long lDim3 = -1);
	void		AllocateSafeArray(VARTYPE vt, long lDim1, long lDim2 = -1, long lDim3 = -1); 
	void		CheckHRESULT(HRESULT hr);
	void		Preconstruct(); 
	void		Clear();
	VARIANT		m_vVariant;
	SAFEARRAY	*m_pSafeArray;
	BOOL		m_bCWSAOwnsData;
};

inline CCWSafeArray::operator VARIANT()
    {return m_vVariant;};

inline CCWSafeArray::operator LPVARIANT()
    {return &m_vVariant;};

inline CCWSafeArray::operator LPSAFEARRAY()
    {return m_pSafeArray;};

inline CCWSafeArray::operator LPSAFEARRAY*()
    {return &m_pSafeArray;};

#endif //__CWSAFEARRAY_H__




