|
|
/*****************************************************************************\
FILE: EnumUnknown.cpp
DESCRIPTION: This code will implement IEnumUnknown for an HDPA.
BryanSt 5/30/2000 Updated and Converted to C++
Copyright (C) Microsoft Corp 2000-2000. All rights reserved. \*****************************************************************************/
#include "priv.h"
#include "EnumUnknown.h"
class CEnumUnknown : public IEnumUnknown { public: //////////////////////////////////////////////////////
// Public Interfaces
//////////////////////////////////////////////////////
// *** IUnknown ***
virtual STDMETHODIMP QueryInterface(REFIID riid, LPVOID * ppvObj); virtual STDMETHODIMP_(ULONG) AddRef(void); virtual STDMETHODIMP_(ULONG) Release(void);
// *** IEnumUnknown ***
virtual STDMETHODIMP Next(IN ULONG celt, IN IUnknown ** rgelt, IN ULONG * pceltFetched); virtual STDMETHODIMP Skip(IN ULONG celt); virtual STDMETHODIMP Reset(void); virtual STDMETHODIMP Clone(OUT IEnumUnknown ** ppenum);
protected: HRESULT _Initialize(void);
private: CEnumUnknown(IN IUnknown * punkOwner, IN IUnknown ** ppArray, IN int nArraySize, IN int nIndex); virtual ~CEnumUnknown(void);
// Private Member Variables
long m_cRef;
IUnknown * m_punkOwner; // The owner of m_pUnknownArray. We hold a ref on this guy to keep m_pUnknownArray valid.
IUnknown ** m_pUnknownArray; // The array of IUnknowns
int m_nArraySize; // The size of m_pUnknownArray
int m_nIndex; // The current index during enum.
// Private Member Functions
// Friend Functions
friend HRESULT CEnumUnknown_CreateInstance(IN IUnknown * punkOwner, IN IUnknown ** ppArray, IN int nArraySize, IN int nIndex, OUT IEnumUnknown ** ppEnumUnknown); };
//===========================
// *** Class Internals & Helpers ***
//===========================
//===========================
// *** IEnumUnknown Interface ***
//===========================
HRESULT CEnumUnknown::Next(IN ULONG celt, IN IUnknown ** rgelt, IN ULONG * pceltFetched) { HRESULT hr = E_INVALIDARG;
if (rgelt && pceltFetched) { ULONG nIndex;
hr = S_OK;
*pceltFetched = 0; for (nIndex = 0; nIndex < celt; nIndex++,m_nIndex++) { if ((m_nIndex < m_nArraySize) && m_pUnknownArray[m_nIndex]) { rgelt[nIndex] = NULL;
IUnknown_Set(&(rgelt[nIndex]), m_pUnknownArray[m_nIndex]); (*pceltFetched)++; } else { rgelt[nIndex] = NULL; } } }
return hr; }
HRESULT CEnumUnknown::Skip(IN ULONG celt) { m_nIndex += celt; return S_OK; }
HRESULT CEnumUnknown::Reset(void) { m_nIndex = 0; return S_OK; }
HRESULT CEnumUnknown::Clone(OUT IEnumUnknown ** ppenum) { HRESULT hr = E_INVALIDARG;
if (ppenum) { hr = CEnumUnknown_CreateInstance(SAFECAST(this, IEnumUnknown *), m_pUnknownArray, m_nArraySize, m_nIndex, ppenum); }
return hr; }
//===========================
// *** IUnknown Interface ***
//===========================
ULONG CEnumUnknown::AddRef() { return InterlockedIncrement(&m_cRef); }
ULONG CEnumUnknown::Release() { ASSERT( 0 != m_cRef ); ULONG cRef = InterlockedDecrement(&m_cRef); if ( 0 == cRef ) { delete this; } return cRef; }
HRESULT CEnumUnknown::QueryInterface(REFIID riid, void **ppvObj) { static const QITAB qit[] = { QITABENT(CEnumUnknown, IEnumUnknown), { 0 }, };
return QISearch(this, qit, riid, ppvObj); }
//===========================
// *** Class Methods ***
//===========================
CEnumUnknown::CEnumUnknown(IN IUnknown * punkOwner, IN IUnknown ** ppArray, IN int nArraySize, IN int nIndex) : m_cRef(1) { DllAddRef();
// This needs to be allocated in Zero Inited Memory.
// Assert that all Member Variables are inited to Zero.
ASSERT(!m_punkOwner);
IUnknown_Set(&m_punkOwner, punkOwner); m_pUnknownArray = ppArray; m_nArraySize = nArraySize; m_nIndex = nIndex; }
CEnumUnknown::~CEnumUnknown() { IUnknown_Set(&m_punkOwner, NULL);
DllRelease(); }
HRESULT CEnumUnknown_CreateInstance(IN IUnknown * punkOwner, IN IUnknown ** ppArray, IN int nArraySize, IN int nIndex, OUT IEnumUnknown ** ppEnumUnknown) { HRESULT hr = E_INVALIDARG;
if (punkOwner && ppArray && ppEnumUnknown) { CEnumUnknown * pObject = new CEnumUnknown(punkOwner, ppArray, nArraySize, nIndex);
*ppEnumUnknown = NULL; if (pObject) { hr = pObject->QueryInterface(IID_PPV_ARG(IEnumUnknown, ppEnumUnknown)); pObject->Release(); } else { hr = E_OUTOFMEMORY; } }
return hr; }
|