Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

182 lines
3.8 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1997
  6. //
  7. // File: ntree.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. //
  11. // NTREE.CPP
  12. //
  13. #include <algorithm>
  14. #include <functional>
  15. #include "ntree.h"
  16. #include "glnkenum.h"
  17. NTELEM :: NTELEM ()
  18. : _pnteParent(NULL),
  19. _pnteChild(NULL)
  20. {
  21. }
  22. NTELEM :: ~ NTELEM ()
  23. {
  24. Orphan();
  25. NTELEM * pnteChild = NULL;
  26. while ( pnteChild = _pnteChild )
  27. {
  28. delete pnteChild;
  29. }
  30. }
  31. // Adopt (link) a child
  32. void NTELEM :: Adopt ( NTELEM * pnteChild, bool bSort )
  33. {
  34. pnteChild->Orphan();
  35. NTELEM * pNextChild = _pnteChild ;
  36. bool bFoundHigher = true ;
  37. if ( pNextChild && bSort )
  38. {
  39. // Position among the children based upon sort order.
  40. GLNKENUM<NTELEM,false> glnkEnum( *pNextChild );
  41. bFoundHigher = false;
  42. while ( pNextChild = glnkEnum.PlnkelNext() )
  43. {
  44. if ( pnteChild->ICompare( pNextChild ) < 0 )
  45. break ;
  46. }
  47. // If we didn't find a higher child, link *this
  48. // such that it points to the first child.
  49. if ( ! (bFoundHigher = pNextChild != NULL) )
  50. pNextChild = _pnteChild ;
  51. }
  52. // If there is another child, insert this in front of it.
  53. if ( pNextChild )
  54. pnteChild->ChnSib().Link( pNextChild ) ;
  55. // If this is the first child, or if this new child
  56. // sorted low, use it as the anchor.
  57. if ( _pnteChild == NULL || pnteChild->ICompare( _pnteChild ) < 0 )
  58. _pnteChild = pnteChild;
  59. _pnteChild->_pnteParent = this ;
  60. }
  61. // Disown (release) a child
  62. void NTELEM :: Disown ( NTELEM * pnteChild )
  63. {
  64. if ( _pnteChild == pnteChild )
  65. {
  66. _pnteChild = pnteChild->ChnSib().PgelemNext() ;
  67. if ( _pnteChild == pnteChild )
  68. _pnteChild = NULL ; // There goes the last child
  69. }
  70. pnteChild->ChnSib().Unlink() ;
  71. pnteChild->_pnteParent = NULL ;
  72. }
  73. // Become an orphan
  74. void NTELEM :: Orphan ()
  75. {
  76. if ( _pnteParent )
  77. _pnteParent->Disown( this );
  78. _pnteParent = NULL;
  79. }
  80. INT NTELEM :: SiblingCount ()
  81. {
  82. return ChnSib().Count();
  83. }
  84. INT NTELEM :: ChildCount ()
  85. {
  86. if ( _pnteChild == NULL )
  87. return 0;
  88. return _pnteChild->ChnSib().Count();
  89. }
  90. NTELEM * NTELEM :: PnteChild ( INT index )
  91. {
  92. if ( _pnteChild == NULL )
  93. return NULL ;
  94. GLNKENUM<NTELEM,false> glnkEnum( *_pnteChild );
  95. int i = 0 ;
  96. do
  97. {
  98. if ( i++ == index )
  99. return glnkEnum.PlnkelCurrent() ;
  100. } while ( glnkEnum.PlnkelNext() ) ;
  101. return NULL ;
  102. }
  103. bool NTELEM :: BIsChild ( NTELEM * pnte )
  104. {
  105. if ( _pnteChild == NULL )
  106. return false ;
  107. GLNKENUM<NTELEM,false> glnkEnum( *_pnteChild );
  108. NTELEM * pnteCurr = NULL ;
  109. do
  110. {
  111. // If this is it, we're done
  112. if ( (pnteCurr = glnkEnum.PlnkelCurrent()) == pnte )
  113. return true ;
  114. // If current object has a child, search its siblings
  115. if ( pnteCurr->_pnteChild && pnteCurr->BIsChild( pnte) )
  116. return true ;
  117. // On to the next object pointer
  118. }
  119. while ( glnkEnum.PlnkelNext() ) ;
  120. return false ;
  121. }
  122. DEFINEVP(NTELEM);
  123. static NTELEM::SRTFNC srtpntelem;
  124. void NTELEM :: ReorderChildren ( SRTFNC & fSortRoutine )
  125. {
  126. INT cChildren = ChildCount() ;
  127. if ( cChildren == 0 )
  128. return;
  129. // Enumerate the children into an array, disown them, sort the
  130. // array and re-adopt them in the new order.
  131. VPNTELEM rgpnteChild;
  132. rgpnteChild.resize(cChildren);
  133. GLNKENUM<NTELEM,false> glnkEnum( *_pnteChild );
  134. for ( int iChild = 0 ; rgpnteChild[iChild++] = glnkEnum.PlnkelNext() ; );
  135. while ( _pnteChild )
  136. {
  137. Disown( _pnteChild ) ;
  138. }
  139. sort( rgpnteChild.begin(), rgpnteChild.end(), fSortRoutine );
  140. // Re-adopt the children in the given order
  141. for ( iChild = 0 ; iChild < rgpnteChild.size() ; )
  142. {
  143. Adopt( rgpnteChild[iChild++] );
  144. }
  145. }
  146. NTREE :: NTREE ()
  147. {
  148. }
  149. NTREE :: ~ NTREE ()
  150. {
  151. }
  152. // End of NTREE.CPP