Annotation of libwww/Library/src/HTList.c, revision 2.27
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.27 ! eric 6: ** @(#) $Id: HTList.c,v 2.26 1996/12/03 05:46:20 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.27 ! eric 175: }
! 176:
! 177: PUBLIC HTList * HTList_elementOf (HTList * cur, void * object, HTList ** pLast)
! 178: {
! 179: HTList * last = cur;
! 180: void * pres;
! 181:
! 182: while ((pres = HTList_nextObject(cur))) {
! 183: if (pres == object) {
! 184: if (pLast)
! 185: *pLast = last;
! 186: return cur;
! 187: }
! 188: last = cur;
! 189: }
! 190:
! 191: /*
! 192: ** didn't find object, but return end of list so it is easy to append
! 193: */
! 194: if (pLast)
! 195: *pLast = last;
! 196: return NULL;
1.1 timbl 197: }
198:
2.17 frystyk 199: PUBLIC void * HTList_objectAt (HTList * me, int position)
1.1 timbl 200: {
2.17 frystyk 201: if (position < 0)
202: return NULL;
203: if (me) {
204: while ((me = me->next)) {
205: if (position == 0)
206: return me->object;
207: position--;
208: }
1.1 timbl 209: }
2.17 frystyk 210: return NULL; /* Reached the end of the list */
1.1 timbl 211: }
2.10 frystyk 212:
2.17 frystyk 213: PUBLIC void * HTList_removeObjectAt (HTList * me, int position)
2.10 frystyk 214: {
2.17 frystyk 215: if (position < 0)
216: return NULL;
217: if (me) {
218: HTList * prevNode;
219: prevNode = me;
220: while ((me = me->next)) {
221: if (position == 0) {
222: prevNode->next = me->next;
223: return me->object;
224: }
225: prevNode = me;
226: position--;
227: }
2.10 frystyk 228: }
2.17 frystyk 229: return NULL; /* Reached the end of the list */
2.10 frystyk 230: }
2.25 frystyk 231:
232: /*
233: ** Do an insertion sort algorithm on the list. An empty list is already
234: ** sorted and so is a single element list.
235: */
236: PUBLIC BOOL HTList_insertionSort (HTList * head, HTComparer * comp)
237: {
238: HTList *tail, *q, *r, *p;
239: if (head && head->next && comp) {
240: #if 0
241: HTList * tail = head->next; /* Tail of the sorted list */
242: #else
243: tail = head->next;
244: #endif
245:
246: while (tail->next) {
247: #if 0
248: HTList * q = tail->next; /* Head of unsorted list */
249: #else
250: q = tail->next;
251: #endif
252:
253: /*
254: ** Depending on the return status of the comparer we either move
255: ** the sentinel down the list or search the sorted sublist to
256: ** insert it.
257: */
258: if (comp(q->object, head->next->object) >= 0) {
259: tail->next = q->next;
260: q->next = head->next;
261: head->next = q;
262: } else {
263: #if 0
264: HTList * r = head->next;
265: HTList * p = r->next;
266: #else
267: r = head->next;
268: p = r->next;
269: #endif
270: while (comp(q->object, p->object) < 0) {
271: r = p;
272: p = r->next;
273: }
274:
275: /*
276: ** If sentinel was found then q is already in right place.
277: ** Otherwise we'll have to move it
278: */
279: if (q == p)
280: tail = q;
281: else {
282: tail->next = q->next;
283: q->next = p;
284: r->next = q;
285: }
286: }
287: }
288: return YES;
289: } else {
290: if (CORE_TRACE)
291: HTTrace("List........ Empty list or no sort algorithm\n");
292: }
293: return NO;
294: }
295:
Webmaster