Files
Work/com/SafeArray.hpp
2024-08-07 09:12:07 -04:00

276 lines
6.1 KiB
C++

#ifndef _COM_SAFEARRAY_HPP_
#define _COM_SAFEARRAY_HPP_
#ifndef _COMMON_SMARTPOINTER_HPP_
#include <common/pointer.hpp>
#endif
#ifndef _COMMON_ARRAY_HPP_
#include <common/array.hpp>
#endif
#ifndef _COM_RESULT_HPP_
#include <com/result.hpp>
#endif
#ifndef _COM_OLEAUTO_HPP_
#include <com/oleauto.hpp>
#endif
#ifndef _COM_VARIANT_HPP_
#include <com/variant.hpp>
#endif
#ifndef _COM_ARRAYBOUND_HPP_
#include <com/bound.hpp>
#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<ArrayBound> &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<long> &indices,void *pData);
bool getAt(Array<long> &indices,void *pData);
UINT getAllocationBytes(void);
bool getPtrOfIndex(Array<long> &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<SAFEARRAY> 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<ArrayBound> &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<long> &indices,void *pData)
{
if(!isOkay())return false;
mLastResult=::SafeArrayPutElement(mSafeArray,&indices[0],pData);
return mLastResult.success()?true:false;
}
inline
bool SafeArray::getAt(Array<long> &indices,void *pData)
{
if(!isOkay())return false;
mLastResult=::SafeArrayGetElement(mSafeArray,&indices[0],pData);
return mLastResult.success()?true:false;
}
inline
bool SafeArray::getPtrOfIndex(Array<long> &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