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.

363 lines
8.7 KiB

  1. /*
  2. *
  3. * NOTES:
  4. *
  5. * REVISIONS:
  6. * pcy26Nov92: Removed windows.h debug stuff
  7. * jod03Dec92: Changed the == tests to x.Equal in a couple of places.
  8. * TSC11May93: In Equal(), cast theItemsInContainer as
  9. * (int) theItemsInContainer
  10. * TSC11May93: Changed operator ++ (INT) to always return a value,
  11. * including *(NULL) !! This allows a clean compile,
  12. * but is not a good solution. PCY SHOULD REVIEW.
  13. * cad27Sep93: Return before delete moved
  14. * rct01Feb94: List no longer inherits from Container
  15. * pcy08Apr94: Trim size, use static iterators, dead code removal
  16. * mwh05May94: #include file madness , part 2
  17. * ajr24May94: Added some casts for Uware
  18. * jps13Jul94: added stdlib.h for os2, changed include order
  19. * ntf12Oct95: Added line to Next ListIterator::Next function to stop it
  20. * bombing if theCurrentElement is NULL.
  21. * cgm24Apr96: Current() returns NULL when theCurrentElement is NULL
  22. *
  23. * v-stebe 29Jul2000 Added checks for mem. alloc. failures
  24. * (bugs #46329, #46330, #46331, #46332, #46333)
  25. * v-stebe 29Jan2002 Removed List::Equals and ListIterator:operator++
  26. * methods to resolve prefast errors.
  27. */
  28. #define INCL_BASE
  29. #define INCL_NOPM
  30. #include "cdefine.h"
  31. extern "C" {
  32. #if (C_OS & C_OS2)
  33. #include <stdlib.h>
  34. #endif
  35. #include <string.h>
  36. #if (C_OS & C_NLM)
  37. #include <process.h>
  38. #endif
  39. }
  40. #include "list.h"
  41. #include "node.h"
  42. //------------------------------------------------------------------------
  43. List::List() :
  44. theItemsInContainer(0),
  45. theHead((PNode)NULL),
  46. theTail((PNode)NULL)
  47. {
  48. }
  49. //------------------------------------------------------------------------
  50. List::List(PList anOldList) :
  51. theItemsInContainer(0),
  52. theHead((PNode)NULL),
  53. theTail((PNode)NULL)
  54. {
  55. INT err = ErrNO_ERROR;
  56. INT items_in_list = anOldList->GetItemsInContainer();
  57. if (items_in_list == 0)
  58. {
  59. err = ErrLIST_EMPTY;
  60. }
  61. else
  62. {
  63. PObj current_object = (PObj)anOldList->GetHead();
  64. ListIterator list_iterator(*anOldList);
  65. while ((current_object) && (err == ErrNO_ERROR))
  66. {
  67. if (theTail == theHead)
  68. {
  69. theTail = new Node(current_object);
  70. if (theTail == NULL) {
  71. // Memory allocation error
  72. err = ErrMEMORY;
  73. break;
  74. }
  75. if (theHead == (PNode)NULL)
  76. {
  77. theHead = theTail;
  78. theHead->SetNext((PNode)NULL);
  79. theHead->SetPrev((PNode)NULL);
  80. }
  81. else
  82. {
  83. theHead->SetNext(theTail);
  84. theTail->SetPrev(theHead);
  85. }
  86. }
  87. else
  88. {
  89. PNode temp = new Node(current_object);
  90. theTail->SetNext(temp);
  91. temp->SetPrev(theTail);
  92. theTail = temp;
  93. }
  94. theItemsInContainer++;
  95. current_object = (PObj)list_iterator.Next();
  96. }
  97. }
  98. }
  99. //------------------------------------------------------------------------
  100. RObj List::PeekHead() const
  101. {
  102. return *(theHead->theNext->theData);
  103. }
  104. //------------------------------------------------------------------------
  105. VOID List::Add( RObj anObject )
  106. {
  107. if (theHead == (PNode)NULL)
  108. {
  109. theHead = new Node( &anObject);
  110. theTail = theHead;
  111. theItemsInContainer++;
  112. }
  113. else
  114. {
  115. PNode temp = new Node( &anObject, theHead );
  116. if (temp != NULL) {
  117. theHead->SetPrev(temp);
  118. temp->SetNext(theHead);
  119. theHead = temp;
  120. theItemsInContainer++;
  121. }
  122. }
  123. }
  124. //------------------------------------------------------------------------
  125. VOID List::Append( PObj anObject )
  126. {
  127. if (theTail == theHead)
  128. {
  129. theTail = new Node(anObject);
  130. if (theTail != NULL) {
  131. if (theHead == (PNode)NULL)
  132. {
  133. theHead = theTail;
  134. theHead->SetNext((PNode)NULL);
  135. theHead->SetPrev((PNode)NULL);
  136. }
  137. else
  138. {
  139. theHead->SetNext(theTail);
  140. theTail->SetPrev(theHead);
  141. }
  142. theItemsInContainer++;
  143. }
  144. }
  145. else
  146. {
  147. PNode temp = new Node(anObject);
  148. if (temp != NULL) {
  149. theTail->SetNext(temp);
  150. temp->SetPrev(theTail);
  151. theTail = temp;
  152. theItemsInContainer++;
  153. }
  154. }
  155. }
  156. //------------------------------------------------------------------------
  157. PObj List::GetHead()
  158. {
  159. if (theHead != (PNode)NULL)
  160. return theHead->GetData();
  161. return (PObj)NULL;
  162. }
  163. //------------------------------------------------------------------------
  164. PObj List::GetTail()
  165. {
  166. if (theTail != (PNode)NULL)
  167. return theTail->GetData();
  168. return (PObj)NULL;
  169. }
  170. //------------------------------------------------------------------------
  171. PObj List::Find( PObj anObject )
  172. {
  173. PNode cursor = theHead;
  174. while ( cursor != (PNode)NULL)
  175. {
  176. // if (*anObject == *(cursor->GetData()) )
  177. if (anObject->Equal(*(cursor->GetData())) )
  178. return cursor->GetData();
  179. cursor = cursor->GetNext();
  180. }
  181. return (PObj)NULL;
  182. }
  183. //------------------------------------------------------------------------
  184. PNode List::FindNode( PObj anObject )
  185. {
  186. PNode cursor = theHead;
  187. while ( cursor != (PNode)NULL)
  188. {
  189. // if (*anObject == *(cursor->GetData()) )
  190. if (anObject->Equal(*(cursor->GetData())) )
  191. return cursor;
  192. cursor = cursor->GetNext();
  193. }
  194. return (PNode)NULL;
  195. }
  196. //------------------------------------------------------------------------
  197. VOID List::Detach( RObj anObject )
  198. {
  199. PNode thenode = FindNode( &anObject );
  200. if (thenode == (PNode)NULL)
  201. return; // Not in the List
  202. PNode next = thenode->theNext;
  203. PNode prev = thenode->thePrev;
  204. if (prev) // If there is a previous node
  205. prev->SetNext(thenode->GetNext()); // assign its next field
  206. else
  207. theHead = next;
  208. if (next)
  209. next->SetPrev(thenode->GetPrev());
  210. else
  211. theTail = prev;
  212. theItemsInContainer--;
  213. delete thenode;
  214. thenode = NULL;
  215. }
  216. //------------------------------------------------------------------------
  217. /*
  218. C+
  219. Name :FlushALL
  220. Synop :Will delete all the NODES in the list along with the user objects
  221. as well. The user objects in the list are held by the NODES.
  222. */
  223. VOID List::FlushAll()
  224. //c-
  225. {
  226. PNode current = theHead;
  227. while( current != (PNode)NULL) //theTail )
  228. {
  229. PNode temp = current;
  230. current = current->theNext;
  231. // Delete the User Data. List is a friend of node
  232. if(temp->theData) {
  233. delete temp->theData;
  234. }
  235. delete temp; // Delete the Node now.
  236. temp = NULL;
  237. }
  238. theHead = (PNode)NULL;
  239. theTail = (PNode)NULL;
  240. theItemsInContainer = 0;
  241. }
  242. VOID List::Flush()
  243. {
  244. // PNode current = theHead->theNext;
  245. PNode current = theHead;
  246. while( current != (PNode)NULL )
  247. {
  248. PNode temp = current;
  249. current = current->theNext;
  250. delete temp;
  251. temp = NULL;
  252. }
  253. theHead = (PNode)NULL;
  254. theTail = (PNode)NULL;
  255. theItemsInContainer = 0;
  256. }
  257. // SRB: Removed method INT List::Equal( RObj anObject ) const
  258. //------------------------------------------------------------------------
  259. RListIterator List::InitIterator() const
  260. {
  261. return *( new ListIterator( (RList)*this ) );
  262. }
  263. //------------------------------------------------------------------------
  264. ListIterator::ListIterator( RList aList )
  265. {
  266. theList = (PList)&aList;
  267. theCurrentElement = theList->GetHeadNode();
  268. }
  269. //------------------------------------------------------------------------
  270. RObj ListIterator::Current()
  271. {
  272. if (theCurrentElement)
  273. return *(theCurrentElement->GetData());
  274. else
  275. return *((PObj)NULL);
  276. }
  277. // SRB: Removed method RObj ListIterator::operator ++ ( INT )
  278. // SRB: Removed method RObj ListIterator::operator ++ ()
  279. //------------------------------------------------------------------------
  280. VOID ListIterator::Reset()
  281. {
  282. theCurrentElement = theList->GetHeadNode();
  283. }
  284. //------------------------------------------------------------------------
  285. PObj ListIterator:: Next()
  286. {
  287. //ntf12Oct95: Added next line to stop this function bombing
  288. if (theCurrentElement == NULL) return((PObj) NULL);
  289. PNode tmp = theCurrentElement->GetNext(); //If above if not there, could bomb
  290. if (tmp)
  291. {
  292. theCurrentElement = tmp;
  293. return theCurrentElement->GetData();
  294. }
  295. return (PObj)NULL;
  296. }