www.pudn.com > Ge_opc_Server_v1.rar > I_ENUMIA.CPP
// I_enumia.cpp
//
// This file contains an implementation of an IEnumOPCItemAttributes interface.
//
// Since the list of elements is buffered in the object
// It is appropriate for enumerations with a 'reasonable' number of elements
//
// Note that new/delete is used for local buffer storage
// while the global allocator is used for returned storage.
//
// See IEnumLHEpipeviewX::Next in Win32SDK\OLE\Reference\Interfaces\IEnumLHEpipeviewX
// for general guidelines for enumerators
//
// (c) COPYRIGHT 1996,1997 INTELLUTION INC.
// ALL RIGHTS RESERVED
//
// Original Author: Al Chisholm
//
// Modification Log:
// Vers Date By Notes
// ---- -------- --- -----
// 0.00 12/27/96 ACC Based on Brockschmidt (with improvements)
//
#define WIN32_LEAN_AND_MEAN
#include "OPCLHEpipeview.h"
/*
* ILHEpipeviewEnumIA::ILHEpipeviewEnumIA
* ILHEpipeviewEnumIA::~ILHEpipeviewEnumIA
*
* Parameters (Constructor):
* pUnkRef LPUNKNOWN to use for reference counting.
* cstr ULONG number of OPCITEMATTRIBTESs in pIA
* pIA ptr to IAs
* pmem IMalloc memory allocator to use for returned data
*/
ILHEpipeviewEnumIA::ILHEpipeviewEnumIA(LPUNKNOWN pUnkRef, ULONG cIA
, OPCITEMATTRIBUTES *pIA, IMalloc * pmem)
{
UINT i;
m_cRef = 0;
m_pUnkRef = pUnkRef;
m_iCur = 0;
m_cIA = cIA;
m_pIA = new OPCITEMATTRIBUTES[cIA]; // use local memory
m_pmem = pmem;
if (NULL != m_pIA)
{
// Make local copies of all the IAs
//
for (i=0; i < m_cIA; i++)
{
IAClone(&m_pIA[i], &pIA[i], NULL); // use local memory
}
}
return;
}
ILHEpipeviewEnumIA::~ILHEpipeviewEnumIA(void)
{
unsigned int i;
if (NULL!=m_pIA)
{
// Delete the local copies of all the IAs
//
for (i=0; i < m_cIA; i++)
{
IAFree(&m_pIA[i], NULL);
}
delete [] m_pIA;
}
return;
}
/*
* ILHEpipeviewEnumIA::QueryInterface
* ILHEpipeviewEnumIA::AddRef
* ILHEpipeviewEnumIA::Release
*
* Purpose:
* IUnknown members for ILHEpipeviewEnumIA object.
*/
STDMETHODIMP ILHEpipeviewEnumIA::QueryInterface(REFIID riid
, LPVOID *ppv)
{
*ppv=NULL;
if (IID_IUnknown==riid || IID_IEnumOPCItemAttributes==riid)
*ppv=(LPVOID)this;
if (NULL!=*ppv)
{
((LPUNKNOWN)*ppv)->AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
STDMETHODIMP_(ULONG) ILHEpipeviewEnumIA::AddRef(void)
{
// Addref this object and also the 'parent' if any
//
++m_cRef;
if(m_pUnkRef != NULL)
m_pUnkRef->AddRef();
return m_cRef;
}
STDMETHODIMP_(ULONG) ILHEpipeviewEnumIA::Release(void)
{
// Release this object and also the 'parent' if any
//
if(m_pUnkRef != NULL)
m_pUnkRef->Release();
if (0L!=--m_cRef)
return m_cRef;
delete this;
return 0;
}
/*
* ILHEpipeviewEnumIA::Next
*
* Purpose:
* Returns the next element in the enumeration.
*
* Parameters:
* cIA ULONG max number of OPCITEMATTRIBTESs to return.
* pIA OPCITEMATTRIBTES(s) in which to store the returned
* structures.
* pulstr ULONG * in which to return how many we
* actually returned.
*
* Return Value:
* HRESULT S_OK if successful, S_FALSE otherwise,
*/
STDMETHODIMP ILHEpipeviewEnumIA::Next(ULONG cIA, OPCITEMATTRIBUTES **pIA
, ULONG *pActual)
{
ULONG cReturn = 0L;
ULONG maxcount = cIA;
OPCITEMATTRIBUTES * temp;
*pActual = 0L; // default return count
*pIA = NULL;
// If this enumerator is empty - return FALSE (should never happen)
//
if (NULL == m_pIA)
return S_FALSE;
// If user passed null for count of items returned
// Then he is only allowed to ask for 1 item
//
if (NULL == pActual)
{
if (1L != cIA)
return E_POINTER;
}
// If we are at end of list return FALSE
//
if (m_iCur >= m_cIA)
return S_FALSE;
// Allocate the items to be returned
//
temp = (OPCITEMATTRIBUTES*)pIMalloc->Alloc(cIA * sizeof(OPCITEMATTRIBUTES));
if(temp == NULL) return S_FALSE;
// Return as many as we have left in list up to request count
//
while (m_iCur < m_cIA && cIA > 0)
{
// Fill in an IA to return to caller
IAClone(&temp[cReturn], &m_pIA[m_iCur], m_pmem); // Use global memory for strings
// And move on to the next one
//
m_iCur++;
cReturn++;
cIA--;
}
// Shorten the block to the size actually used
// and return the final pointer to the caller
//
*pIA = (OPCITEMATTRIBUTES*)pIMalloc->Realloc(temp, cReturn * sizeof(OPCITEMATTRIBUTES));
if (NULL != pActual)
*pActual = cReturn;
if (cReturn == maxcount) return S_OK;
return S_FALSE;
}
/*
* ILHEpipeviewEnumIA::Skip
*
* Purpose:
* Skips the next n elements in the enumeration.
*
* Parameters:
* cSkip ULONG number of elements to skip.
*
* Return Value:
* HRESULT S_OK if successful, S_FALSE if we could not
* skip the requested number.
*/
STDMETHODIMP ILHEpipeviewEnumIA::Skip(ULONG cSkip)
{
if (((m_iCur+cSkip) >= m_cIA) || NULL==m_pIA)
return S_FALSE;
m_iCur+=cSkip;
return S_OK;
}
/*
* ILHEpipeviewEnumIA::Reset
*
* Purpose:
* Resets the current element index in the enumeration to zero.
*
* Parameters:
* None
*/
STDMETHODIMP ILHEpipeviewEnumIA::Reset(void)
{
m_iCur=0;
return S_OK;
}
/*
* ILHEpipeviewEnumIA::Clone
*
* Purpose:
* Returns another IEnumIA with the same state as ourselves.
*
* Parameters:
* ppEnum ILHEpipeviewEnumIA * in which to return the
* new object.
*/
STDMETHODIMP ILHEpipeviewEnumIA::Clone(IEnumOPCItemAttributes **ppEnum)
{
ILHEpipeviewEnumIA *pNew;
*ppEnum = NULL;
//Create the clone
//
pNew = new ILHEpipeviewEnumIA(m_pUnkRef, m_cIA, m_pIA, m_pmem);
if (NULL == pNew)
return E_OUTOFMEMORY;
pNew->AddRef();
// Set the 'state' of the clone to match the state if this
//
pNew->m_iCur = m_iCur;
*ppEnum = pNew;
return S_OK;
}