1 /*****************************************************************************/
2 /*                                                                           */
3 /*                                 LISTNODE.CC                               */
4 /*                                                                           */
5 /* (C) 1993,94  Ullrich von Bassewitz                                        */
6 /*              Zwehrenbuehlstrasse 33                                       */
7 /*              D-72070 Tuebingen                                            */
8 /* EMail:       uz@ibb.schwaben.com                                          */
9 /*                                                                           */
10 /*****************************************************************************/
11 
12 
13 
14 // $Id$
15 //
16 // $Log$
17 //
18 //
19 
20 
21 
22 #include "listnode.h"
23 
24 
25 
26 /*****************************************************************************/
27 /*                             class _ListNode                               */
28 /*****************************************************************************/
29 
30 
31 
_ListNode(void * DataPtr)32 _ListNode::_ListNode (void* DataPtr)
33 {
34     NextNode = PrevNode = this;
35     ContentsPtr = DataPtr;
36 }
37 
38 
39 
~_ListNode()40 _ListNode::~_ListNode ()
41 {
42     Unlink ();
43 }
44 
45 
46 
InsertAfter(_ListNode * N)47 void _ListNode::InsertAfter (_ListNode* N)
48 // inserts one node after another
49 {
50     // the node cannot be inserted after itself
51     PRECONDITION (N != this);
52 
53     // switch pointers
54     NextNode = N->NextNode;
55     PrevNode = N;
56     N->NextNode = this;
57     NextNode->PrevNode = this;
58 }
59 
60 
61 
InsertBefore(_ListNode * N)62 void _ListNode::InsertBefore (_ListNode* N)
63 // inserts one node before another
64 {
65     // the node cannot be inserted before itself
66     PRECONDITION (N != this);
67 
68     // switch pointers
69     PrevNode = N->PrevNode;
70     NextNode = N;
71     N->PrevNode = this;
72     PrevNode->NextNode = this;
73 }
74 
75 
76 
Unlink()77 void _ListNode::Unlink ()
78 // Unlinks a node from a list.
79 {
80     // If the list constists only of this element, no unlink is necessary
81     if (NextNode == this) {
82         return;
83     }
84 
85     // unlink node
86     PrevNode->NextNode = NextNode;
87     NextNode->PrevNode = PrevNode;
88 
89     // the unlinked node is a list with one node
90     NextNode = PrevNode = this;
91 }
92 
93 
94 
Traverse(int Forward,int (* F)(_ListNode *,void *),void * UserPtr)95 _ListNode* _ListNode::Traverse (int Forward, int (*F) (_ListNode*, void*),
96                                      void *UserPtr)
97 // Traverse through a list, starting with the current node and calling the
98 // given function F with every node as argument. Ends if finally the current
99 // node is reached again (all nodes have been visited in this case) or if the
100 // called function returns a value != 0. In the former case, Traverse returns
101 // a NULL pointer, in the latter, a pointer to the node is returned.
102 {
103     _ListNode* N = this;
104 
105     do {
106 
107         if (F (N, UserPtr)) {
108             // function returned true
109             return N;
110         }
111 
112         if (Forward) {
113             N = N->NextNode;
114         } else {
115             N = N->PrevNode;
116         }
117 
118     } while (N != this);
119 
120     // Walked through the whole list, return NULL
121     return NULL;
122 }
123 
124 
125 
NodeCount()126 u16 _ListNode::NodeCount ()
127 // Returns the node count of the list
128 {
129     register u16 Count = 0;
130 
131     _ListNode* N = this;
132 
133     do {
134         Count++;
135         N = N->NextNode;
136     } while (N != this);
137 
138     return Count;
139 }
140 
141 
142 
NodeWithNumber(u16 X)143 _ListNode* _ListNode::NodeWithNumber (u16 X)
144 // Returns the node with number X. Counting begins with "this", (which has
145 // number 0) and proceeds in "Next" direction.
146 // Warning: If X is greater than the number of nodes in the list, the
147 // result is undefined (wraping around).
148 {
149     _ListNode* N = this;
150 
151     while (X--) {
152         N = N->NextNode;
153     }
154 
155     return N;
156 }
157 
158 
159 
NumberOfNode(_ListNode * N)160 u16 _ListNode::NumberOfNode (_ListNode* N)
161 // Returns the number of node N. Counting begins with "this" node
162 // (which has number 0) and proceeds in "Next" direction.
163 {
164     register u16 Count = 0;
165     _ListNode* R = this;
166 
167     while (R != N) {
168         Count++;
169         R = R->NextNode;
170         CHECK (R != this);              // Means N is not in list
171     }
172 
173     return Count;
174 }
175 
176 
177 
178