Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

SafeArray.h

Go to the documentation of this file.
00001 /*  SafeArray.h - SAFEARRAY wrapper class
00002     Copyright (C) 2001-2004 Mark Weaver
00003     Written by Mark Weaver <mark@npsl.co.uk>
00004 
00005     Part of the Open-Win32 library.
00006     This library is free software; you can redistribute it and/or
00007     modify it under the terms of the GNU Library General Public
00008     License as published by the Free Software Foundation; either
00009     version 2 of the License, or (at your option) any later version.
00010 
00011     This library is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014     Library General Public License for more details.
00015 
00016     You should have received a copy of the GNU Library General Public
00017     License along with this library; if not, write to the
00018     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00019     Boston, MA  02111-1307, USA.
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 } // namespace OW32
00347 
00348 #endif // OW32_SafeArray_h

Generated on Sun Jun 5 01:29:18 2005 for OW32 by  doxygen 1.3.9.1