windows-nt/Source/XPSP1/NT/multimedia/dshow/h/amutil.h
2020-09-26 16:20:57 +08:00

286 lines
6.6 KiB
C++

// Copyright (c) 1992 - 1997 Microsoft Corporation. All Rights Reserved.
/* Dynamic arrays */
#ifndef __AMUTIL_H__
#define __AMUTIL_H__
/* Dynamic array support */
template <class _TInterface, class _TArray>
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 Base, const IID *piid, class T>
class CAMEnumInterfaceImpl :
public Base,
public CDynamicArray<T*, CComPtr<T> >
{
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 <class Base, const IID* piid, class T>
STDMETHODIMP CAMEnumInterfaceImpl<Base, piid, T>::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 <class Base, const IID* piid, class T>
STDMETHODIMP CAMEnumInterfaceImpl<Base, piid, T>::Skip(ULONG celt)
{
m_iter += celt;
if (m_iter < Size())
return S_OK;
m_iter = Size();
return S_FALSE;
}
template <class Base, const IID* piid, class T>
STDMETHODIMP CAMEnumInterfaceImpl<Base, piid, T>::Clone(Base** ppEnum)
{
typedef CComObject<CAMEnumInterface<Base, piid, T> > _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 Base, const IID* piid, class T>
class CAMEnumInterface : public CAMEnumInterfaceImpl<Base, piid, T>, public CComObjectRoot
{
public:
typedef CComObjectRoot _BaseClass ;
typedef CAMEnumInterface<Base, piid, T> _CComEnum;
typedef CAMEnumInterfaceImpl<Base, piid, T> _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__