Annotation of libwww/Library/src/HTList.c, revision 2.29
2.8 frystyk 1: /* HTList.c
2: ** MANAGEMENT OF LINKED LISTS
3: **
2.12 frystyk 4: ** (c) COPYRIGHT MIT 1995.
2.8 frystyk 5: ** Please first read the full copyright statement in the file COPYRIGH.
2.29 ! frystyk 6: ** @(#) $Id: HTList.c,v 2.28 1996/12/13 22:06:14 eric Exp $
1.1 timbl 7: **
8: ** A list is represented as a sequence of linked nodes of type HTList.
9: ** The first node is a header which contains no object.
10: ** New nodes are inserted between the header and the rest of the list.
11: */
12:
2.10 frystyk 13: /* Library include files */
2.22 frystyk 14: #include "sysdep.h"
2.10 frystyk 15: #include "HTUtils.h"
1.1 timbl 16: #include "HTList.h"
17:
2.17 frystyk 18: PUBLIC HTList * HTList_new (void)
1.1 timbl 19: {
2.20 frystyk 20: HTList *newList;
21: if ((newList = (HTList *) HT_CALLOC(1, sizeof (HTList))) == NULL)
22: HT_OUTOFMEM("HTList_new");
2.17 frystyk 23: newList->object = NULL;
24: newList->next = NULL;
25: return newList;
1.1 timbl 26: }
27:
2.17 frystyk 28: PUBLIC BOOL HTList_delete (HTList * me)
1.1 timbl 29: {
2.15 frystyk 30: if (me) {
31: HTList *current;
32: while ((current = me)) {
33: me = me->next;
2.20 frystyk 34: HT_FREE(current);
2.15 frystyk 35: }
36: return YES;
37: }
38: return NO;
1.1 timbl 39: }
40:
2.17 frystyk 41: PUBLIC BOOL HTList_addObject (HTList * me, void * newObject)
1.1 timbl 42: {
2.11 frystyk 43: if (me) {
2.20 frystyk 44: HTList *newNode;
45: if ((newNode = (HTList *) HT_CALLOC(1, sizeof(HTList))) == NULL)
46: HT_OUTOFMEM("HTList_addObject");
2.11 frystyk 47: newNode->object = newObject;
48: newNode->next = me->next;
49: me->next = newNode;
50: return YES;
51: } else {
2.25 frystyk 52: if (CORE_TRACE)
53: HTTrace("HTList...... Can not add object %p to nonexisting list\n",
2.11 frystyk 54: newObject);
55: }
56: return NO;
1.1 timbl 57: }
58:
2.18 frystyk 59: PUBLIC BOOL HTList_appendObject (HTList * me, void * newObject)
60: {
61: if (me) {
62: while (me->next) me = me->next;
63: return HTList_addObject(me, newObject);
64: }
65: return NO;
66: }
67:
2.27 eric 68: PUBLIC BOOL HTList_removeObject (HTList * me, void * oldObject)
1.1 timbl 69: {
2.11 frystyk 70: if (me) {
71: HTList *previous;
72: while (me->next) {
73: previous = me;
74: me = me->next;
2.19 frystyk 75: if (me->object == oldObject) {
2.11 frystyk 76: previous->next = me->next;
2.20 frystyk 77: HT_FREE(me);
2.11 frystyk 78: return YES; /* Success */
79: }
80: }
2.26 eric 81: }
82: return NO; /* object not found or NULL list */
83: }
84:
2.27 eric 85: PUBLIC BOOL HTList_quickRemoveElement (HTList * me, HTList * last)
2.26 eric 86: {
87: if (me && last) {
88: last->next = me->next;
89: HT_FREE(me);
90: return YES; /* Success */
1.1 timbl 91: }
2.11 frystyk 92: return NO; /* object not found or NULL list */
1.1 timbl 93: }
94:
2.27 eric 95: PUBLIC BOOL HTList_removeObjectAll (HTList * me, void * oldObject)
2.25 frystyk 96: {
97: BOOL found = NO;
98: if (me) {
99: HTList *previous;
100: while (me->next) {
101: previous = me;
102: me = me->next;
103: if (me->object == oldObject) {
104: previous->next = me->next;
105: HT_FREE(me);
106: found = YES; /* At least one object found */
107: }
108: }
109: }
110: return found;
111: }
112:
2.17 frystyk 113: PUBLIC void * HTList_removeLastObject (HTList * me)
1.1 timbl 114: {
2.17 frystyk 115: if (me && me->next) {
116: HTList *lastNode = me->next;
117: void * lastObject = lastNode->object;
118: me->next = lastNode->next;
2.20 frystyk 119: HT_FREE(lastNode);
2.17 frystyk 120: return lastObject;
121: } else /* Empty list */
122: return NULL;
123: }
124:
125: PUBLIC void * HTList_removeFirstObject (HTList * me)
126: {
127: if (me && me->next) {
128: HTList * prevNode;
129: void *firstObject;
130: while (me->next) {
131: prevNode = me;
132: me = me->next;
133: }
134: firstObject = me->object;
135: prevNode->next = NULL;
2.20 frystyk 136: HT_FREE(me);
2.17 frystyk 137: return firstObject;
2.24 frystyk 138: } else /* Empty list */
139: return NULL;
140: }
141:
142: PUBLIC void * HTList_firstObject (HTList * me)
143: {
144: if (me && me->next) {
145: HTList * prevNode;
146: while (me->next) {
147: prevNode = me;
148: me = me->next;
149: }
150: return me->object;
2.17 frystyk 151: } else /* Empty list */
152: return NULL;
1.1 timbl 153: }
154:
2.17 frystyk 155: PUBLIC int HTList_count (HTList * me)
1.1 timbl 156: {
2.17 frystyk 157: int count = 0;
158: if (me)
159: while ((me = me->next))
160: count++;
161: return count;
1.1 timbl 162: }
163:
2.17 frystyk 164: PUBLIC int HTList_indexOf (HTList * me, void * object)
1.1 timbl 165: {
2.17 frystyk 166: if (me) {
167: int position = 0;
168: while ((me = me->next)) {
169: if (me->object == object)
170: return position;
171: position++;
172: }
1.1 timbl 173: }
2.17 frystyk 174: return -1;
2.28 eric 175: }
176:
177: PUBLIC int HTList_indexOfElement (HTList * me, HTList * element)
178: {
179: if (me) {
180: int position = 0;
181: if (me == element)
182: return -1;
183: while ((me = me->next)) {
184: if (me == element)
185: return position;
186: position++;
187: }
188: }
189: return -2;
2.27 eric 190: }
191:
192: PUBLIC HTList * HTList_elementOf (HTList * cur, void * object, HTList ** pLast)
193: {
194: HTList * last = cur;
195: void * pres;
196:
197: while ((pres = HTList_nextObject(cur))) {
198: if (pres == object) {
199: if (pLast)
200: *pLast = last;
201: return cur;
202: }
203: last = cur;
204: }
205:
206: /*
207: ** didn't find object, but return end of list so it is easy to append
208: */
209: if (pLast)
210: *pLast = last;
211: return NULL;
1.1 timbl 212: }
213:
2.17 frystyk 214: PUBLIC void * HTList_objectAt (HTList * me, int position)
1.1 timbl 215: {
2.17 frystyk 216: if (position < 0)
217: return NULL;
218: if (me) {
219: while ((me = me->next)) {
220: if (position == 0)
221: return me->object;
222: position--;
223: }
1.1 timbl 224: }
2.17 frystyk 225: return NULL; /* Reached the end of the list */
1.1 timbl 226: }
2.10 frystyk 227:
2.17 frystyk 228: PUBLIC void * HTList_removeObjectAt (HTList * me, int position)
2.10 frystyk 229: {
2.17 frystyk 230: if (position < 0)
231: return NULL;
232: if (me) {
233: HTList * prevNode;
234: prevNode = me;
235: while ((me = me->next)) {
236: if (position == 0) {
237: prevNode->next = me->next;
238: return me->object;
239: }
240: prevNode = me;
241: position--;
242: }
2.10 frystyk 243: }
2.17 frystyk 244: return NULL; /* Reached the end of the list */
2.10 frystyk 245: }
2.25 frystyk 246:
247: /*
248: ** Do an insertion sort algorithm on the list. An empty list is already
249: ** sorted and so is a single element list.
250: */
251: PUBLIC BOOL HTList_insertionSort (HTList * head, HTComparer * comp)
252: {
253: HTList *tail, *q, *r, *p;
254: if (head && head->next && comp) {
255: tail = head->next;
256: while (tail->next) {
257: q = tail->next;
258:
259: /*
260: ** Depending on the return status of the comparer we either move
261: ** the sentinel down the list or search the sorted sublist to
262: ** insert it.
263: */
264: if (comp(q->object, head->next->object) >= 0) {
265: tail->next = q->next;
266: q->next = head->next;
267: head->next = q;
268: } else {
269: r = head->next;
270: p = r->next;
271: while (comp(q->object, p->object) < 0) {
272: r = p;
273: p = r->next;
274: }
275:
276: /*
277: ** If sentinel was found then q is already in right place.
278: ** Otherwise we'll have to move it
279: */
280: if (q == p)
281: tail = q;
282: else {
283: tail->next = q->next;
284: q->next = p;
285: r->next = q;
286: }
287: }
288: }
289: return YES;
290: } else {
2.29 ! frystyk 291: if (CORE_TRACE) HTTrace("List........ Empty list or no sort algorithm\n");
2.25 frystyk 292: }
293: return NO;
294: }
295:
Webmaster