home *** CD-ROM | disk | FTP | other *** search
/ Supercompiler 1997 / SUPERCOMPILER97.iso / MS_VC.50 / VC / MFC / SRC / OLEENUM.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1996-10-30  |  4.6 KB  |  218 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1997 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10.  
  11. #include "stdafx.h"
  12.  
  13. #ifdef AFX_OLE3_SEG
  14. #pragma code_seg(AFX_OLE3_SEG)
  15. #endif
  16.  
  17. #ifdef _DEBUG
  18. #undef THIS_FILE
  19. static char THIS_FILE[] = __FILE__;
  20. #endif
  21.  
  22. #define new DEBUG_NEW
  23.  
  24. /////////////////////////////////////////////////////////////////////////////
  25. // CEnumArray (provides OLE enumerator for arbitrary items in an array)
  26.  
  27. CEnumArray::CEnumArray(size_t nSizeElem, const void* pvEnum, UINT nSize,
  28.     BOOL bNeedFree)
  29. {
  30.     m_nSizeElem = nSizeElem;
  31.     m_pClonedFrom = NULL;
  32.  
  33.     m_nCurPos = 0;
  34.     m_nSize = nSize;
  35.     m_pvEnum = (BYTE*)pvEnum;
  36.     m_bNeedFree = bNeedFree;
  37.  
  38.     ASSERT_VALID(this);
  39. }
  40.  
  41. CEnumArray::~CEnumArray()
  42. {
  43.     ASSERT_VALID(this);
  44.  
  45.     // release the clone pointer (only for clones)
  46.     if (m_pClonedFrom != NULL)
  47.     {
  48.         m_pClonedFrom->InternalRelease();
  49.         ASSERT(!m_bNeedFree);
  50.     }
  51.  
  52.     // release the pointer (should only happen on non-clones)
  53.     if (m_bNeedFree)
  54.     {
  55.         ASSERT(m_pClonedFrom == NULL);
  56.         delete m_pvEnum;
  57.     }
  58. }
  59.  
  60. BOOL CEnumArray::OnNext(void* pv)
  61. {
  62.     ASSERT_VALID(this);
  63.  
  64.     if (m_nCurPos >= m_nSize)
  65.         return FALSE;
  66.  
  67.     memcpy(pv, &m_pvEnum[m_nCurPos*m_nSizeElem], m_nSizeElem);
  68.     ++m_nCurPos;
  69.     return TRUE;
  70. }
  71.  
  72. BOOL CEnumArray::OnSkip()
  73. {
  74.     ASSERT_VALID(this);
  75.  
  76.     if (m_nCurPos >= m_nSize)
  77.         return FALSE;
  78.  
  79.     return ++m_nCurPos < m_nSize;
  80. }
  81.  
  82. void CEnumArray::OnReset()
  83. {
  84.     ASSERT_VALID(this);
  85.  
  86.     m_nCurPos = 0;
  87. }
  88.  
  89. CEnumArray* CEnumArray::OnClone()
  90. {
  91.     ASSERT_VALID(this);
  92.  
  93.     // set up an exact copy of this object
  94.     //  (derivatives may have to replace this code)
  95.     CEnumArray* pClone;
  96.     pClone = new CEnumArray(m_nSizeElem, m_pvEnum, m_nSize);
  97.     ASSERT(pClone != NULL);
  98.     ASSERT(!pClone->m_bNeedFree);   // clones should never free themselves
  99.     pClone->m_nCurPos = m_nCurPos;
  100.  
  101.     // finally, return the clone to OLE
  102.     ASSERT_VALID(pClone);
  103.     return pClone;
  104. }
  105.  
  106. /////////////////////////////////////////////////////////////////////////////
  107. // CEnumArray::XEnumVOID implementation
  108.  
  109. STDMETHODIMP_(ULONG) CEnumArray::XEnumVOID::AddRef()
  110. {
  111.     METHOD_PROLOGUE_EX_(CEnumArray, EnumVOID)
  112.     return pThis->ExternalAddRef();
  113. }
  114.  
  115. STDMETHODIMP_(ULONG) CEnumArray::XEnumVOID::Release()
  116. {
  117.     METHOD_PROLOGUE_EX_(CEnumArray, EnumVOID)
  118.     return pThis->ExternalRelease();
  119. }
  120.  
  121. STDMETHODIMP CEnumArray::XEnumVOID::QueryInterface(
  122.     REFIID iid, LPVOID* ppvObj)
  123. {
  124.     METHOD_PROLOGUE_EX_(CEnumArray, EnumVOID)
  125.     return pThis->ExternalQueryInterface(&iid, ppvObj);
  126. }
  127.  
  128. STDMETHODIMP CEnumArray::XEnumVOID::Next(
  129.     ULONG celt, void* reelt, ULONG* pceltFetched)
  130. {
  131.     METHOD_PROLOGUE_EX(CEnumArray, EnumVOID);
  132.     ASSERT_VALID(pThis);
  133.  
  134.     if (pceltFetched != NULL)
  135.         *pceltFetched = 0;
  136.  
  137.     ASSERT(celt > 0);
  138.     ASSERT(celt == 1 || pceltFetched != NULL);
  139.  
  140.     BYTE* pchCur = (BYTE*)reelt;
  141.     ULONG nFetched = 0;
  142.  
  143.     ULONG celtT = celt;
  144.     SCODE sc = E_UNEXPECTED;
  145.     TRY
  146.     {
  147.         while (celtT != 0 && pThis->OnNext((void*)pchCur))
  148.         {
  149.             pchCur += pThis->m_nSizeElem;
  150.             --celtT;
  151.         }
  152.         if (pceltFetched != NULL)
  153.             *pceltFetched = celt - celtT;
  154.         sc = celtT == 0 ? S_OK : S_FALSE;
  155.     }
  156.     END_TRY
  157.  
  158.     return sc;
  159. }
  160.  
  161. STDMETHODIMP CEnumArray::XEnumVOID::Skip(ULONG celt)
  162. {
  163.     METHOD_PROLOGUE_EX(CEnumArray, EnumVOID);
  164.     ASSERT_VALID(pThis);
  165.  
  166.     ULONG celtT = celt;
  167.     SCODE sc = E_UNEXPECTED;
  168.     TRY
  169.     {
  170.         while (celtT != 0 && pThis->OnSkip())
  171.             --celtT;
  172.         sc = celtT == 0 ? S_OK : S_FALSE;
  173.     }
  174.     END_TRY
  175.  
  176.     return celtT != 0 ? S_FALSE : S_OK;
  177. }
  178.  
  179. STDMETHODIMP CEnumArray::XEnumVOID::Reset()
  180. {
  181.     METHOD_PROLOGUE_EX(CEnumArray, EnumVOID);
  182.     ASSERT_VALID(pThis);
  183.  
  184.     pThis->OnReset();
  185.     return S_OK;
  186. }
  187.  
  188. STDMETHODIMP CEnumArray::XEnumVOID::Clone(IEnumVOID** ppenm)
  189. {
  190.     METHOD_PROLOGUE_EX(CEnumArray, EnumVOID);
  191.     ASSERT_VALID(pThis);
  192.  
  193.     *ppenm = NULL;
  194.  
  195.     SCODE sc = E_UNEXPECTED;
  196.     TRY
  197.     {
  198.         CEnumArray* pEnumHelper = pThis->OnClone();
  199.         ASSERT_VALID(pEnumHelper);
  200.  
  201.         // we use an extra reference to keep the original object alive
  202.         //  (the extra reference is removed in the clone's destructor)
  203.         if (pThis->m_pClonedFrom != NULL)
  204.             pEnumHelper->m_pClonedFrom = pThis->m_pClonedFrom;
  205.         else
  206.             pEnumHelper->m_pClonedFrom = pThis;
  207.         pEnumHelper->m_pClonedFrom->InternalAddRef();
  208.         *ppenm = &pEnumHelper->m_xEnumVOID;
  209.  
  210.         sc = S_OK;
  211.     }
  212.     END_TRY
  213.  
  214.     return sc;
  215. }
  216.  
  217. /////////////////////////////////////////////////////////////////////////////
  218.