#ifndef _COM_SAFEARRAY_HPP_ #define _COM_SAFEARRAY_HPP_ #ifndef _COMMON_SMARTPOINTER_HPP_ #include #endif #ifndef _COMMON_ARRAY_HPP_ #include #endif #ifndef _COM_RESULT_HPP_ #include #endif #ifndef _COM_OLEAUTO_HPP_ #include #endif #ifndef _COM_VARIANT_HPP_ #include #endif #ifndef _COM_ARRAYBOUND_HPP_ #include #endif class SafeArrayFeature { public: enum{Auto=FADF_AUTO,Static=FADF_STATIC,Embedded=FADF_EMBEDDED,FixedSize=FADF_FIXEDSIZE,BString=FADF_BSTR,Unknown=FADF_UNKNOWN, Dispatch=FADF_DISPATCH,Variant=FADF_VARIANT,Reserved=FADF_RESERVED}; }; class SafeArray { public: enum Disposition{Assume,Delete}; class SafeArrayNullPointerException{}; SafeArray(void); virtual ~SafeArray(); SafeArray &operator=(const SafeArray &safeArray); bool create(VariantType varType,Array &arrayBounds); bool create(VariantType varType,ArrayBound &arrayBounds); bool destroy(void); long getUpperBound(unsigned int dimension=1); long getLowerBound(unsigned int dimension=1); UINT getDimensions(void); long getLockCount(void); bool lock(void); bool unlock(void); bool accessData(void **ppvData); bool unaccessData(void); bool setAt(Array &indices,void *pData); bool getAt(Array &indices,void *pData); UINT getAllocationBytes(void); bool getPtrOfIndex(Array &indices,void **ppvData); bool isOkay(void)const; Disposition disposition(void)const; void disposition(Disposition disposition); SAFEARRAY *getSAFEARRAY(void); void setSAFEARRAY(SAFEARRAY *pSafeArray); const ComResult &getLastResult(void)const; private: long getUpperBound(unsigned int dimension,const tagSAFEARRAY &safeArray); long getLowerBound(unsigned int dimension,const tagSAFEARRAY &safeArray); SmartPointer mSafeArray; Disposition mDisposition; ComResult mLastResult; }; inline SafeArray::SafeArray(void) : mDisposition(Delete) { } inline SafeArray::~SafeArray() { destroy(); } inline SafeArray &SafeArray::operator=(const SafeArray &safeArray) { if(!isOkay())return *this; mLastResult=::SafeArrayCopyData(((SafeArray&)safeArray).mSafeArray,mSafeArray); return *this; } inline long SafeArray::getUpperBound(unsigned int dimension) { if(!isOkay())throw SafeArrayNullPointerException(); return getUpperBound(dimension,*mSafeArray); } inline long SafeArray::getUpperBound(unsigned int dimension,const tagSAFEARRAY &safeArray) { long upperBound; mLastResult=::SafeArrayGetUBound(&((tagSAFEARRAY&)safeArray),dimension,&upperBound); if(!mLastResult.success())return 0; return upperBound; } inline long SafeArray::getLowerBound(unsigned int dimension) { if(!isOkay())throw SafeArrayNullPointerException(); return getLowerBound(dimension,*mSafeArray); } inline UINT SafeArray::getDimensions(void) { if(!isOkay())return false; mLastResult=::SafeArrayGetDim(mSafeArray); return mLastResult.success()?true:false; } inline long SafeArray::getLockCount(void) { if(!isOkay())return 0; return mSafeArray->cLocks; } inline long SafeArray::getLowerBound(unsigned int dimension,const tagSAFEARRAY &safeArray) { long lowerBound; mLastResult=::SafeArrayGetLBound(&((tagSAFEARRAY&)safeArray),dimension,&lowerBound); if(!mLastResult.success())return 0; return lowerBound; } inline bool SafeArray::accessData(void **ppvData) { if(!isOkay())return false; mLastResult=::SafeArrayAccessData(mSafeArray,ppvData); return mLastResult.success()?true:false; } inline bool SafeArray::unaccessData(void) { if(!isOkay())return false; mLastResult=::SafeArrayUnaccessData(mSafeArray); return mLastResult.success()?true:false; } inline bool SafeArray::isOkay(void)const { return mSafeArray.isOkay(); } inline bool SafeArray::destroy(void) { if(!isOkay())return false; if(Assume==mDisposition) { mSafeArray.destroy(); return true; } while(getLockCount())unlock(); mLastResult=::SafeArrayDestroy(mSafeArray); mSafeArray.destroy(); if(S_OK==mLastResult.result())return true; return false; } inline bool SafeArray::create(VariantType type,Array &arrayBounds) { destroy(); if(!arrayBounds.size())return false; mSafeArray=::SafeArrayCreate(type,arrayBounds.size(),&arrayBounds[0]); if(!mSafeArray.isOkay())return false; mSafeArray.disposition(PointerDisposition::Assume); return true; } inline bool SafeArray::create(VariantType type,ArrayBound &arrayBound) { destroy(); mSafeArray=::SafeArrayCreate(type,1,&arrayBound); if(!mSafeArray.isOkay())return false; mSafeArray.disposition(PointerDisposition::Assume); return true; } inline bool SafeArray::unlock() { if(!isOkay())return false; mLastResult=::SafeArrayUnlock(mSafeArray); return mLastResult.success()?true:false; } inline bool SafeArray::lock(void) { if(!isOkay())return false; mLastResult=::SafeArrayLock(mSafeArray); return mLastResult.success()?true:false; } inline bool SafeArray::setAt(Array &indices,void *pData) { if(!isOkay())return false; mLastResult=::SafeArrayPutElement(mSafeArray,&indices[0],pData); return mLastResult.success()?true:false; } inline bool SafeArray::getAt(Array &indices,void *pData) { if(!isOkay())return false; mLastResult=::SafeArrayGetElement(mSafeArray,&indices[0],pData); return mLastResult.success()?true:false; } inline bool SafeArray::getPtrOfIndex(Array &indices,void **ppvData) { if(!isOkay())return false; mLastResult=::SafeArrayPtrOfIndex(mSafeArray,&indices[0],ppvData); return mLastResult.success()?true:false; } inline UINT SafeArray::getAllocationBytes(void) { if(!isOkay())return false; return ::SafeArrayGetElemsize(mSafeArray); } inline SAFEARRAY *SafeArray::getSAFEARRAY(void) { return (SAFEARRAY*)mSafeArray; } inline void SafeArray::setSAFEARRAY(SAFEARRAY *pSafeArray) { destroy(); if(!pSafeArray)throw SafeArrayNullPointerException(); mSafeArray=pSafeArray; mSafeArray.disposition(PointerDisposition::Assume); } inline const ComResult &SafeArray::getLastResult(void)const { return mLastResult; } inline SafeArray::Disposition SafeArray::disposition(void)const { return mDisposition; } inline void SafeArray::disposition(Disposition disposition) { mDisposition=disposition; } #endif