text: /******************************************************************************
  
  Copyright (c) 2000 Microsoft Corporation
  
  Module Name:
      MPCUploadEnum.cpp
  
  Abstract:
      This file contains the implementation of the MPCUploadEnum class,
      the enumerator of the MPCUpload class.
  
  Revision History:
      Davide Massarenti   (Dmassare)  04/15/99
          created
  
  ******************************************************************************/
  
  #include "stdafx.h"
  
  
  CMPCUploadEnum::CMPCUploadEnum()
  {
      __ULT_FUNC_ENTRY( "CMPCUploadEnum::CMPCUploadEnum" );
  
  	                                 // List m_lstJobs
      m_itCurrent = m_lstJobs.begin(); // Iter m_itCurrent
  }
  
  void CMPCUploadEnum::FinalRelease()
  {
      __ULT_FUNC_ENTRY( "CMPCUploadEnum::FinalRelease" );
  
  
  	MPC::ReleaseAll( m_lstJobs );
  }
  
  HRESULT CMPCUploadEnum::AddItem( /*[in]*/ IMPCUploadJob* job )
  {
      __ULT_FUNC_ENTRY( "CMPCUploadEnum::Init" );
  
  	MPC::SmartLock<_ThreadModel> lock( this );
  
  
      m_lstJobs.push_back( job ); job->AddRef();
      m_itCurrent    = m_lstJobs.begin();
  
  
      __ULT_FUNC_EXIT(S_OK);
  }
  
  
  STDMETHODIMP CMPCUploadEnum::Next( /*[in]*/ ULONG celt, /*[out]*/ VARIANT *rgelt, /*[out]*/ ULONG *pceltFetched )
  {
      __ULT_FUNC_ENTRY( "CMPCUploadEnum::Next" );
  
      HRESULT 			         hr;
      ULONG   			         cNum = 0;
      VARIANT 			        *pelt = rgelt;
  	MPC::SmartLock<_ThreadModel> lock( this );
  
  
      if(rgelt == NULL || (celt != 1 && pceltFetched == NULL))
  	{
          __MPC_SET_ERROR_AND_EXIT(hr, E_POINTER);
  	}
  
  
      while(celt && m_itCurrent != m_lstJobs.end())
      {
          IMPCUploadJob* mpcujJob = *m_itCurrent++;
  
          pelt->vt = VT_DISPATCH;
          if(FAILED(hr = mpcujJob->QueryInterface( IID_IDispatch, (void**)&pelt->pdispVal )))
          {
              while(rgelt < pelt)
              {
                  ::VariantClear( rgelt++ );
              }
  
              cNum = 0;
  			__MPC_FUNC_LEAVE;
          }
  
          pelt++; cNum++; celt--;
      }
  
      hr = S_OK;
  
  
      __ULT_FUNC_CLEANUP;
  
      if(pceltFetched != NULL) *pceltFetched = cNum;
  
      if(SUCCEEDED(hr))
      {
          if(celt != 0) hr = S_FALSE;
      }
  
      __ULT_FUNC_EXIT(hr);
  }
  
  STDMETHODIMP CMPCUploadEnum::Skip( /*[in]*/ ULONG celt )
  {
      __ULT_FUNC_ENTRY( "CMPCUploadEnum::Skip" );
  
      HRESULT                      hr;
  	MPC::SmartLock<_ThreadModel> lock( this );
  
  
      while(celt && m_itCurrent != m_lstJobs.end())
      {
          m_itCurrent++;
          celt--;
      }
  
      hr = celt ? S_FALSE : S_OK;
  
  
      __ULT_FUNC_EXIT(hr);
  }
  
  STDMETHODIMP CMPCUploadEnum::Reset()
  {
      __ULT_FUNC_ENTRY( "CMPCUploadEnum::Reset" );
  
      HRESULT                      hr;
  	MPC::SmartLock<_ThreadModel> lock( this );
  
  
      m_itCurrent = m_lstJobs.begin();
  	hr          = S_OK;
  
  
      __ULT_FUNC_EXIT(hr);
  }
  
  STDMETHODIMP CMPCUploadEnum::Clone( /*[out]*/ IEnumVARIANT* *ppEnum )
  {
      __ULT_FUNC_ENTRY( "CMPCUploadEnum::Clone" );
  
      HRESULT    					 hr;
  	Iter                         it;
      CComPtr<CMPCUploadEnum>      pEnum;
  	MPC::SmartLock<_ThreadModel> lock( this );
  
  	__MPC_PARAMCHECK_BEGIN(hr)
  		__MPC_PARAMCHECK_POINTER_AND_SET(ppEnum,NULL);
  	__MPC_PARAMCHECK_END();
  
  
      __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &pEnum ));
  
  	for(it = m_lstJobs.begin(); it != m_lstJobs.end(); it++)
  	{
  		__MPC_EXIT_IF_METHOD_FAILS(hr, pEnum->AddItem( *it ));
  	}
  
      __MPC_EXIT_IF_METHOD_FAILS(hr, pEnum->QueryInterface( IID_IEnumVARIANT, (void**)ppEnum ));
  
      hr = S_OK;
  
  
      __ULT_FUNC_CLEANUP;
  
      __ULT_FUNC_EXIT(hr);
  }
  
  