conlist.cxx
Upload User: caisha3
Upload Date: 2013-09-21
Package Size: 208739k
Code Size: 7k
Category:

Windows Develop

Development Platform:

Visual C++

  1. /*++
  2. Copyright (c) 1997  Microsoft Corporation
  3. Module Name:  conlist.cxx
  4. Abstract:
  5.     Linked list of URL_CONTAINERs
  6.     
  7. Author:
  8.     Adriaan Canter (adriaanc) 04-02-97
  9.     
  10. --*/
  11. #include <cache.hxx>
  12. /*------------------------ CConElem -----------------------------------------*/
  13. /*-----------------------------------------------------------------------------
  14. CConElem constructor
  15.   ---------------------------------------------------------------------------*/
  16. CConElem::CConElem(URL_CONTAINER* pUrlCon)
  17. {
  18.     _pUrlCon = pUrlCon;
  19.     _pNext = NULL;
  20. }
  21. /*-----------------------------------------------------------------------------
  22. CConElem destructor. Destructs URL_CONTAINER* member.
  23.   ---------------------------------------------------------------------------*/
  24. CConElem::~CConElem()
  25. {
  26.     delete _pUrlCon;
  27. }
  28. /*------------------------ CConList Private Functions------------------------*/
  29. /*-----------------------------------------------------------------------------
  30. CConList::Seek      Sets current pointer to element of index nElem.
  31.   ---------------------------------------------------------------------------*/
  32. BOOL CConList::Seek(DWORD nElem)
  33. {   
  34.     // Bad list or index too high.
  35.     if (!_pHead || nElem > _n)
  36.     {
  37.         INET_ASSERT(FALSE);
  38.         return FALSE;
  39.     }
  40.     // Seek to element from current.
  41.     if (nElem > _nCur)        
  42.     {
  43.         while (_nCur < nElem)
  44.         {
  45.             _pCur = _pCur->_pNext;
  46.             _nCur++;
  47.         }
  48.     }
  49. //
  50. // BUGBUG: VC5 optimizer assumes if (a < b), then (b > a), so check (a != b) instead
  51. //
  52.     else if (nElem != _nCur) // if (nElem < _nCur)
  53.     {
  54.         // Seek to element from head.
  55.         _nCur = 0;
  56.         _pCur = _pHead;
  57.         while (_nCur < nElem)
  58.         {
  59.             _pCur = _pCur->_pNext;
  60.             _nCur++;
  61.         }
  62.     }
  63.     INET_ASSERT(_nCur != 0 || (_pCur == _pHead));
  64.     return TRUE;
  65. }
  66. /*------------------------ CConList Public Functions------------------------*/
  67. /*-----------------------------------------------------------------------------
  68. CConList constructor.
  69.   ---------------------------------------------------------------------------*/
  70. CConList::CConList()
  71. : _n(0), _nCur(0), _pCur(NULL), _pHead(NULL)
  72. {
  73. }
  74. /*-----------------------------------------------------------------------------
  75. CConList destructor.
  76.   ---------------------------------------------------------------------------*/
  77. CConList::~CConList()
  78. {
  79. }
  80. /*-----------------------------------------------------------------------------
  81. CConList::Size      Returns number of elements in list.
  82.   ---------------------------------------------------------------------------*/
  83. DWORD CConList::Size()
  84. // THIS FUNCTION MUST BE CALLED WITH THE CACHE CRIT SEC
  85. {
  86.     DWORD n = (_pHead ? _n+1 : 0);
  87.     return n;
  88. }
  89. /*-----------------------------------------------------------------------------
  90. CConList::Free      Removes and destructs each element in list.
  91.   ---------------------------------------------------------------------------*/
  92. BOOL CConList::Free()
  93. {
  94.     LOCK_CACHE();
  95.     DWORD i = Size();
  96.     //  Delete CONTENT last, as we reference fields of it's header (dwChangeCount)
  97.     //  in destructors of extensible containers
  98.     while (i)
  99.     {
  100.         Remove(--i);
  101.     }
  102.     UNLOCK_CACHE();
  103.     return TRUE;
  104. }
  105. /*-----------------------------------------------------------------------------
  106. CConList::Add      Appends new element to list.
  107.   ---------------------------------------------------------------------------*/
  108. BOOL CConList::Add(URL_CONTAINER * pUrlCon)
  109. {
  110.     LOCK_CACHE();
  111.     BOOL bSuccess = FALSE;
  112.     CConElem *pNew;
  113.     DWORD i;
  114.     
  115.     // Bad pointer.
  116.     if (!pUrlCon)
  117.     {
  118.         INET_ASSERT(FALSE);
  119.         goto exit;        
  120.     }
  121.     if (_pHead)
  122.     {
  123.         //  try to reuse a Container which has been deleted
  124.         for (i = 0; i <= _n; i++)
  125.         {
  126.             if (Seek(i))
  127.             {
  128.                 if (_pCur->_pUrlCon->GetDeleted())
  129.                 {
  130.                     delete _pCur->_pUrlCon;
  131.                     _pCur->_pUrlCon = pUrlCon;
  132.                     bSuccess = TRUE;
  133.                     goto exit;
  134.                 }
  135.             }
  136.         }
  137.     }
  138.     // Construct new element.
  139.     pNew = new CConElem(pUrlCon);
  140.     if (!pNew)
  141.     {
  142.         INET_ASSERT(FALSE);
  143.         goto exit;
  144.     }
  145.     // If valid list, seek to last element and add element.
  146.     if (_pHead)
  147.     {
  148.         if (_n == LARGEST_INDEX)
  149.         {
  150.             delete pNew;
  151.             INET_ASSERT(FALSE);
  152.             goto exit;        
  153.         }
  154.         Seek(_n);
  155.         _pCur->_pNext = pNew;
  156.         pNew->_pNext = _pHead;
  157.         _n++;
  158.     }
  159.     // If empty list, set head and current to new element.
  160.     else
  161.     {
  162.         _pHead = _pCur = pNew;
  163.         pNew->_pNext = _pHead;
  164.         _n = _nCur = 0;
  165.     }
  166.     
  167.     bSuccess = TRUE;
  168. exit:
  169.     
  170.     UNLOCK_CACHE();
  171.     return bSuccess;
  172. }
  173. /*-----------------------------------------------------------------------------
  174. CConList::Remove      Removes nElem'th element from list.
  175.   ---------------------------------------------------------------------------*/
  176. BOOL CConList::Remove(DWORD nElem)
  177. // THIS FUNCTION MUST BE CALLED WITH THE CACHE CRIT SEC
  178. {
  179.     DWORD     nPrev;
  180.     CConElem *pElem;
  181.     BOOL bSuccess = FALSE;
  182.     // Empty list or index too high.
  183.     if (!_pHead || nElem > _n)
  184.     {
  185.         INET_ASSERT(FALSE);
  186.         goto exit;
  187.     }
  188.     // Seek to previous element, or last if removing head.
  189.     nPrev = (nElem == 0 ? _n : nElem - 1);
  190.     Seek(nPrev);
  191.     // Save pointer to element, update prevous' next pointer.
  192.     pElem = _pCur->_pNext;
  193.     _pCur->_pNext = _pCur->_pNext->_pNext;
  194.     // Update head if necessary.
  195.     if (nElem == 0)
  196.         _pHead = _pHead->_pNext;
  197.     // Decrement index of last, zero out values if empty.
  198.     if (_n > 0)
  199.         _n--;
  200.     else
  201.     {
  202.         _pHead = _pCur = NULL;
  203.         _n = _nCur = 0;
  204.     }    
  205.     
  206.     // Destruct element.
  207.     delete pElem;
  208.     
  209.     bSuccess = TRUE;
  210. exit:
  211.     return bSuccess;
  212. }
  213. /*-----------------------------------------------------------------------------
  214. CConList::operator Get Returns Addref'ed reference to URL_CONTAINER* of index nElem.
  215.   ---------------------------------------------------------------------------*/
  216. // THIS FUNCTION MUST BE CALLED WITH THE CACHE CRIT SEC
  217. URL_CONTAINER* CConList::Get (DWORD nElem)
  218. {
  219.     URL_CONTAINER* pUrlCon;
  220.     if (Seek(nElem))
  221.         pUrlCon = _pCur->_pUrlCon;
  222.     else
  223.         pUrlCon = NULL;
  224.         
  225.     if (pUrlCon) pUrlCon->AddRef();
  226.     return pUrlCon;
  227. }