// Copyright (c) 1992 - 1997 Microsoft Corporation. All Rights Reserved. /* Dynamic arrays */ #ifndef __AMUTIL_H__ #define __AMUTIL_H__ /* Dynamic array support */ template class CDynamicArray { public: CDynamicArray(int iIncrement) : m_pArray(NULL), m_nElements(0), m_iIncrement(iIncrement), m_nSize(0) {} CDynamicArray() : m_pArray(NULL), m_nElements(0), m_iIncrement(4), m_nSize(0) {} ~CDynamicArray() { delete [] m_pArray; } _TInterface Element(int i) const { _ASSERTE(i < m_nElements); return m_pArray[i]; } _TInterface operator [] (int i) { return m_pArray[i]; } int Size() const { return m_nElements; } BOOL Add(_TInterface Element) { _ASSERTE(m_nSize >= m_nElements); if (m_nSize == m_nElements) { _TArray *pNewArray = new _TArray[m_nSize + m_iIncrement]; if (pNewArray == NULL) { return FALSE; } for (int i = 0; i < m_nElements; i++) { pNewArray[i] = m_pArray[i]; } delete [] m_pArray; m_pArray = pNewArray; m_nSize = m_nSize + m_iIncrement; } m_pArray[m_nElements++] = Element; return TRUE; } BOOL Remove(_TInterface Element) { for (int i = 0; m_pArray[i] != Element; i++ ) { if (i >= m_nElements) { return FALSE; } } Remove(i); return TRUE; } void Remove(int i) { _ASSERTE(i < m_nElements); m_nElements--; for (; i < m_nElements; i++) { m_pArray[i] = m_pArray[i + 1]; } m_pArray[m_nElements] = NULL; } void RemoveAll() { for (int i = 0; i < m_nElements; i++) { m_pArray[i] = NULL; } m_nElements = 0; } private: _TArray *m_pArray; int m_nSize; int m_nElements; const int m_iIncrement; }; template class CAMEnumInterfaceImpl : public Base, public CDynamicArray > { public: CAMEnumInterfaceImpl() : m_iter(0) {} /* The actual interface we support */ STDMETHOD(Next)(ULONG celt, T** rgelt, ULONG* pceltFetched); STDMETHOD(Skip)(ULONG celt); STDMETHOD(Reset)(void){m_iter = 0;return S_OK;} STDMETHOD(Clone)(Base** ppEnum); int m_iter; }; template STDMETHODIMP CAMEnumInterfaceImpl::Next(ULONG celt, T** rgelt, ULONG* pceltFetched) { if (rgelt == NULL || (celt != 1 && pceltFetched == NULL)) return E_POINTER; ULONG nRem = (ULONG)(Size() - m_iter); HRESULT hRes = S_OK; if (nRem < celt) hRes = S_FALSE; ULONG nMin = min(celt, nRem); if (pceltFetched != NULL) *pceltFetched = nMin; while(nMin--) { Element(m_iter)->AddRef(); *(rgelt++) = Element(m_iter++); } return hRes; } template STDMETHODIMP CAMEnumInterfaceImpl::Skip(ULONG celt) { m_iter += celt; if (m_iter < Size()) return S_OK; m_iter = Size(); return S_FALSE; } template STDMETHODIMP CAMEnumInterfaceImpl::Clone(Base** ppEnum) { typedef CComObject > _class; HRESULT hRes = E_POINTER; if (ppEnum != NULL) { _class* p = NULL; ATLTRY(p = new _class) if (p == NULL) { *ppEnum = NULL; hRes = E_OUTOFMEMORY; } else { for (int i = 0; i < Size(); i++) { if (!p->Add(Element(i))) { break; } } if (i != Size()) { delete p; hRes = E_OUTOFMEMORY; *ppEnum = NULL; } else { p->m_iter = m_iter; hRes = p->_InternalQueryInterface(*piid, (void**)ppEnum); if (FAILED(hRes)) delete p; } } } return hRes; } template class CAMEnumInterface : public CAMEnumInterfaceImpl, public CComObjectRoot { public: typedef CComObjectRoot _BaseClass ; typedef CAMEnumInterface _CComEnum; typedef CAMEnumInterfaceImpl _CComEnumBase; #ifdef DEBUG ULONG InternalAddRef() { return _BaseClass::InternalAddRef(); } ULONG InternalRelease() { return _BaseClass::InternalRelease(); } #endif BEGIN_COM_MAP(_CComEnum) COM_INTERFACE_ENTRY_IID(*piid, _CComEnumBase) END_COM_MAP() }; #ifndef __WXUTIL__ // wrapper for whatever critical section we have class CCritSec { // make copy constructor and assignment operator inaccessible CCritSec(const CCritSec &refCritSec); CCritSec &operator=(const CCritSec &refCritSec); CRITICAL_SECTION m_CritSec; public: CCritSec() { InitializeCriticalSection(&m_CritSec); }; ~CCritSec() { DeleteCriticalSection(&m_CritSec); }; void Lock() { EnterCriticalSection(&m_CritSec); }; void Unlock() { LeaveCriticalSection(&m_CritSec); }; }; // locks a critical section, and unlocks it automatically // when the lock goes out of scope class CAutoLock { // make copy constructor and assignment operator inaccessible CAutoLock(const CAutoLock &refAutoLock); CAutoLock &operator=(const CAutoLock &refAutoLock); protected: CCritSec * m_pLock; public: CAutoLock(CCritSec * plock) { m_pLock = plock; m_pLock->Lock(); }; ~CAutoLock() { m_pLock->Unlock(); }; }; // locks a critical section, and unlocks it automatically // when the lock goes out of scope class CAutoObjectLock { // make copy constructor and assignment operator inaccessible CAutoObjectLock(const CAutoObjectLock &refAutoLock); CAutoObjectLock &operator=(const CAutoObjectLock &refAutoLock); protected: CComObjectRoot * m_pObject; public: CAutoObjectLock(CComObjectRoot * pobject) { m_pObject = pobject; m_pObject->Lock(); }; ~CAutoObjectLock() { m_pObject->Unlock(); }; }; #define AUTO_CRIT_LOCK CAutoObjectLock lck(this); #ifdef _DEBUG #define EXECUTE_ASSERT(_x_) _ASSERTE(_x_) #else #define EXECUTE_ASSERT(_x_) _x_ #endif #endif #endif // __AMUTIL_H__