00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00026 #ifndef OW32_SafeArray_h
00027 #define OW32_SafeArray_h
00028
00029 #include <oaidl.h>
00030 #include <OW32/OW32Libs.h>
00031
00032 namespace OW32
00033 {
00034
00036 class OW32_LIB_EXPORT CSafeArray
00037 {
00038 public:
00043 CSafeArray(SAFEARRAY* psa, bool bTakeOwn = false) :
00044 m_psa(psa),
00045 m_bOwn(bTakeOwn),
00046 m_bAccessed(false)
00047 {
00048 }
00049
00051 CSafeArray() :
00052 m_psa(0),
00053 m_bOwn(false),
00054 m_bAccessed(false)
00055 {
00056 }
00057
00059 ~CSafeArray()
00060 {
00061 Clear();
00062 }
00063
00067 SAFEARRAY* Copy()
00068 {
00069 if (m_bAccessed)
00070 UnaccessData();
00071
00072 SAFEARRAY* psaout=0;
00073 if (FAILED(SafeArrayCopy(m_psa, &psaout))) {
00074 return NULL;
00075 }
00076 return psaout;
00077 }
00078
00082 SAFEARRAY* Detach()
00083 {
00084 if (m_bAccessed)
00085 UnaccessData();
00086
00087 SAFEARRAY* psa=m_psa;
00088 m_psa=0;
00089 m_bOwn=false;
00090 return psa;
00091 }
00092
00097 void Attach(SAFEARRAY* psa, bool bTakeOwn = true)
00098 {
00099 Clear();
00100 m_bOwn = bTakeOwn;
00101 m_psa = psa;
00102 }
00103
00106 void Clear()
00107 {
00108 if (m_psa) {
00109 if (m_bAccessed)
00110 UnaccessData();
00111
00112 if (m_bOwn) {
00113 SafeArrayDestroy(m_psa);
00114 m_bOwn = false;
00115 }
00116 m_psa=0;
00117 }
00118 }
00119
00125 HRESULT CreateVector(VARTYPE vt, ULONG cElements, LONG lBound=0)
00126 {
00127 Clear();
00128 m_psa = SafeArrayCreateVector(vt, lBound, cElements);
00129 if (!m_psa)
00130 return E_OUTOFMEMORY;
00131 m_bOwn = true;
00132 return S_OK;
00133 }
00134
00141 HRESULT Create(VARTYPE vt, UINT cDims, SAFEARRAYBOUND *rgsabound)
00142 {
00143 Clear();
00144 m_psa = SafeArrayCreate(vt, cDims, rgsabound);
00145 if (!m_psa)
00146 return E_OUTOFMEMORY;
00147 m_bOwn = true;
00148 return S_OK;
00149 }
00150
00155 HRESULT Redim(ULONG cElements, LONG lBound = 0)
00156 {
00157 SAFEARRAYBOUND sabound;
00158 sabound.cElements = cElements;
00159 sabound.lLbound = (long)lBound;
00160 return SafeArrayRedim(m_psa, &sabound);
00161 }
00162
00165 UINT Dimensions() const
00166 {
00167 if (m_psa)
00168 return m_psa->cDims;
00169 return 0;
00170 }
00171
00176 LONG UBound(UINT dim) const
00177 {
00178 if (!isValidDim(dim))
00179 return -1;
00180 return m_psa->rgsabound[dim].lLbound + m_psa->rgsabound[0].cElements-1;
00181 }
00182
00187 LONG LBound(UINT dim) const
00188 {
00189 if (!isValidDim(dim))
00190 return -1;
00191 return m_psa->rgsabound[dim].lLbound;
00192 }
00193
00198 ULONG Count(UINT dim) const
00199 {
00200 if (!isValidDim(dim))
00201 return 0;
00202 return m_psa->rgsabound[dim].cElements;
00203 }
00204
00210 HRESULT PutElement(LONG *rgIndexes, void *elt)
00211 {
00212 if (!m_psa)
00213 return E_POINTER;
00214 return SafeArrayPutElement(m_psa, rgIndexes, elt);
00215 }
00216
00222 HRESULT GetElement(LONG *rgIndexes, void *elt)
00223 {
00224 if (!m_psa)
00225 return E_POINTER;
00226 return SafeArrayGetElement(m_psa, rgIndexes, elt);
00227 }
00228
00231 ULONG ElementSize() const
00232 {
00233 return m_psa->cbElements;
00234 }
00235
00239 template <class T>
00240 HRESULT AccessData(T** pbData)
00241 {
00242 void *pvData;
00243 HRESULT hr = SafeArrayAccessData(m_psa, &pvData);
00244 if (FAILED(hr))
00245 return hr;
00246 *pbData = (T *)pvData;
00247 m_bAccessed = true;
00248 return hr;
00249 }
00250
00254 #define DECLARE_ACCESSOR(T) \
00255 T* Access##T() \
00256 { \
00257 T* pData; \
00258 HRESULT hr; \
00259 if (FAILED(hr = AccessData(&pData))) \
00260 { \
00261 ::SetLastError(hr); \
00262 return (T *)0; \
00263 } \
00264 return (T *)pData; \
00265 }
00266
00270 DECLARE_ACCESSOR(CHAR);
00274 DECLARE_ACCESSOR(BYTE);
00278 DECLARE_ACCESSOR(SHORT);
00282 DECLARE_ACCESSOR(USHORT);
00286 DECLARE_ACCESSOR(LONG);
00290 DECLARE_ACCESSOR(ULONG);
00294 DECLARE_ACCESSOR(VARIANT);
00298 DECLARE_ACCESSOR(BSTR);
00302 IDispatch** AccessIDispatch()
00303 {
00304 IDispatch** pData;
00305 AccessData(&pData);
00306 return (IDispatch **)pData;
00307 }
00311 IUnknown** AccessIUnknown()
00312 {
00313 IUnknown** pData;
00314 AccessData(&pData);
00315 return (IUnknown **)pData;
00316 }
00317
00318 #undef DECLARE_ACCESSOR
00319
00324 HRESULT UnaccessData()
00325 {
00326 HRESULT hr = SafeArrayUnaccessData(m_psa);
00327 m_bAccessed = false;
00328 return hr;
00329 }
00330
00333 operator SAFEARRAY* () { return m_psa; }
00334
00335 private:
00336 bool isValidDim(UINT dim) const
00337 {
00338 return m_psa && dim < m_psa->cDims;
00339 }
00340
00341 SAFEARRAY* m_psa;
00342 bool m_bOwn;
00343 bool m_bAccessed;
00344 };
00345
00346 }
00347
00348 #endif // OW32_SafeArray_h