/************************************************************************ Copyright (c) 2000 - 2000 Microsoft Corporation Module Name : cenum.cpp Abstract : CPP files to enumeration abstraction. Author : Revision History : ***********************************************************************/ #include "stdafx.h" #if !defined( BITS_V12_ON_NT4 ) #include "cenum.tmh" #endif #define MAGIC_ACTIVE 0x44446666 #define MAGIC_INACTIVE 0x55553333 template<class B, class T, class P> CEnum<B,T,P>::CEnum() : m_CurrentIndex(0), m_magic( MAGIC_ACTIVE ) { memset( m_stack, 0, sizeof(m_stack) ); } template<class B, class T, class P> HRESULT CEnum<B,T,P>::NextInternal( ULONG celt, T rgelt[], ULONG * pceltFetched ) { CheckMagicValue(); ULONG i; HRESULT Hr = S_OK; CAutoExclusiveLock LockHolder(m_mutex); LogPublicApiBegin( "celt %u, rgelt %p, pceltFetched %p", celt, rgelt, pceltFetched ); ULONG Fetched = 0; try { for (unsigned int c=0; c<celt; c++) m_ItemPolicy.Init( rgelt[c] ); if ( !pceltFetched && (1 != celt) ) { LogWarning("Return count pointer is NULL, but requested count isn't 1" ); throw ComError( E_INVALIDARG ); } for (i=0; ( i < celt ) && ( m_CurrentIndex < m_items.size() ); i++, m_CurrentIndex++) { m_ItemPolicy.Copy( rgelt[i], m_items[m_CurrentIndex] ); Fetched++; } if ( pceltFetched ) { *pceltFetched = Fetched; } if ( Fetched != celt ) { Hr = S_FALSE; } } catch ( ComError exception ) { Hr = exception.Error(); } LogPublicApiEnd( "celt %u, rgelt %p, pceltFetched %p(%u)", celt, rgelt, pceltFetched, pceltFetched ? *pceltFetched : 1 ); return Hr; } template<class B, class T, class P> HRESULT CEnum<B,T,P>::CloneInternal( B **ppEnum ) { CheckMagicValue(); HRESULT Hr = S_OK; CEnum<B,T,P> * pEnum = NULL; CAutoExclusiveLock LockHolder( m_mutex ); LogPublicApiBegin( "ppEnum %p", ppEnum ); try { pEnum = new CEnum<B,T,P>; for (CItemList::iterator iter = m_items.begin(); iter != m_items.end(); ++iter) { pEnum->Add( *iter ); } pEnum->m_CurrentIndex = m_CurrentIndex; } catch ( ComError exception ) { delete pEnum; pEnum = NULL; Hr = exception.Error(); } *ppEnum = pEnum; LogPublicApiEnd( "ppEnum %p(%p)", ppEnum, *ppEnum ); return Hr; } template<class B, class T, class P> void CEnum<B, T,P>::Add( T item ) { CheckMagicValue(); CAutoExclusiveLock LockHolder( m_mutex ); T MyItem; try { m_ItemPolicy.Copy( MyItem, item ); m_items.push_back( MyItem ); } catch( ComError Error ) { m_ItemPolicy.Destroy( MyItem ); throw; } } template<class B, class T, class P> HRESULT CEnum<B,T,P>::GetCountInternal( ULONG * pCount ) { CheckMagicValue(); HRESULT Hr = S_OK; CAutoSharedLock LockHolder( m_mutex ); LogPublicApiBegin( "pCount %p", pCount ); *pCount = m_items.size(); LogPublicApiEnd( "pCount %p(%u)", pCount, *pCount ); return Hr; } template<class B, class T, class P> HRESULT CEnum<B, T, P>::ResetInternal() { CheckMagicValue(); HRESULT Hr = S_OK; CAutoExclusiveLock LockHolder( m_mutex ); LogPublicApiBegin( " " ); m_CurrentIndex = 0; LogPublicApiEnd( " " ); return Hr; } template<class B, class T, class P> HRESULT CEnum<B, T, P>::SkipInternal( ULONG celt ) { CheckMagicValue(); HRESULT Hr = S_OK; CAutoExclusiveLock LockHolder( m_mutex ); LogPublicApiBegin( "celt %u", celt ); while(celt) { if ( m_CurrentIndex >= m_items.size() ) break; // Hit the end of the list m_CurrentIndex++; --celt; } if (celt) { LogWarning( "Attempt to skip too many elements." ); Hr = S_FALSE; } LogPublicApiEnd( "celt %u", celt ); return Hr; } template<class B, class T, class P> CEnum<B,T,P>::~CEnum() { CheckMagicValue(); m_magic = MAGIC_INACTIVE; for (CItemList::const_iterator iter = m_items.begin(); iter != m_items.end(); ++iter) { T Item = (*iter); m_ItemPolicy.Destroy( Item ); } } template<class B, class T, class P> void CEnum<B,T,P>::CheckMagicValue() { ASSERT( m_magic == MAGIC_ACTIVE ); } CEnumJobs::CEnumJobs() : CEnumInterface<IEnumBackgroundCopyJobs,IBackgroundCopyJob>() {} CEnumFiles::CEnumFiles() : CEnumInterface<IEnumBackgroundCopyFiles,IBackgroundCopyFile>() {} CEnumOldGroups::CEnumOldGroups() : CEnumItem<IEnumBackgroundCopyGroups,GUID>( ) {} CEnumOldJobs::CEnumOldJobs() : CEnumItem<IEnumBackgroundCopyJobs1,GUID>( ) {}