]>
git.saurik.com Git - apple/mdnsresponder.git/blob - mDNSShared/GenLinkedList.c
2 * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
25 Contains: implementation of generic linked lists.
30 Change History (most recent first):
32 $Log: GenLinkedList.c,v $
33 Revision 1.3 2004/04/22 21:14:42 cheshire
34 Fix comment spelling mistake
36 Revision 1.2 2004/02/05 07:41:08 cheshire
41 #include "GenLinkedList.h"
44 // Return the link pointer contained within element e at offset o.
45 #define GETLINK( e, o) ( *(void**)((char*) (e) + (o)) )
47 // Assign the link pointer l to element e at offset o.
48 #define ASSIGNLINK( e, l, o) ( *((void**)((char*) (e) + (o))) = (l))
51 // GenLinkedList /////////////////////////////////////////////////////////////
53 void InitLinkedList( GenLinkedList
*pList
, size_t linkOffset
)
54 /* Initialize the block of memory pointed to by pList as a linked list. */
58 pList
->LinkOffset
= linkOffset
;
62 void AddToTail( GenLinkedList
*pList
, void *elem
)
63 /* Add a linked list element to the tail of the list. */
66 ASSIGNLINK( pList
->Tail
, elem
, pList
->LinkOffset
);
69 ASSIGNLINK( elem
, NULL
, pList
->LinkOffset
);
75 void AddToHead( GenLinkedList
*pList
, void *elem
)
76 /* Add a linked list element to the head of the list. */
78 ASSIGNLINK( elem
, pList
->Head
, pList
->LinkOffset
);
79 if ( pList
->Tail
== NULL
)
86 int RemoveFromList( GenLinkedList
*pList
, void *elem
)
87 /* Remove a linked list element from the list. Return 0 if it was not found. */
88 /* If the element is removed, its link will be set to NULL. */
90 void *iElem
, *lastElem
;
92 for ( iElem
= pList
->Head
, lastElem
= NULL
; iElem
; iElem
= GETLINK( iElem
, pList
->LinkOffset
)) {
94 if ( lastElem
) { // somewhere past the head
95 ASSIGNLINK( lastElem
, GETLINK( elem
, pList
->LinkOffset
), pList
->LinkOffset
);
96 } else { // at the head
97 pList
->Head
= GETLINK( elem
, pList
->LinkOffset
);
99 if ( pList
->Tail
== elem
)
100 pList
->Tail
= lastElem
? lastElem
: NULL
;
101 ASSIGNLINK( elem
, NULL
, pList
->LinkOffset
); // maybe catch a stale reference bug.
111 int ReplaceElem( GenLinkedList
*pList
, void *elemInList
, void *newElem
)
112 /* Replace an element in the list with a new element, in the same position. */
114 void *iElem
, *lastElem
;
116 if ( elemInList
== NULL
|| newElem
== NULL
)
119 for ( iElem
= pList
->Head
, lastElem
= NULL
; iElem
; iElem
= GETLINK( iElem
, pList
->LinkOffset
))
121 if ( iElem
== elemInList
)
123 ASSIGNLINK( newElem
, GETLINK( elemInList
, pList
->LinkOffset
), pList
->LinkOffset
);
124 if ( lastElem
) // somewhere past the head
126 ASSIGNLINK( lastElem
, newElem
, pList
->LinkOffset
);
130 pList
->Head
= newElem
;
132 if ( pList
->Tail
== elemInList
)
133 pList
->Tail
= newElem
;
143 // GenDoubleLinkedList /////////////////////////////////////////////////////////
145 void InitDoubleLinkedList( GenDoubleLinkedList
*pList
, size_t fwdLinkOffset
,
146 size_t backLinkOffset
)
147 /* Initialize the block of memory pointed to by pList as a double linked list. */
151 pList
->FwdLinkOffset
= fwdLinkOffset
;
152 pList
->BackLinkOffset
= backLinkOffset
;
156 void DLLAddToHead( GenDoubleLinkedList
*pList
, void *elem
)
157 /* Add a linked list element to the head of the list. */
163 // fix up the forward links
164 ASSIGNLINK( elem
, pList
->Head
, pList
->FwdLinkOffset
);
167 // fix up the backward links
169 ASSIGNLINK( pNext
, elem
, pList
->BackLinkOffset
);
172 ASSIGNLINK( elem
, NULL
, pList
->BackLinkOffset
);
176 void DLLRemoveFromList( GenDoubleLinkedList
*pList
, void *elem
)
177 /* Remove a linked list element from the list. */
178 /* When the element is removed, its link will be set to NULL. */
182 pNext
= GETLINK( elem
, pList
->FwdLinkOffset
);
183 pPrev
= GETLINK( elem
, pList
->BackLinkOffset
);
185 // fix up the forward links
187 ASSIGNLINK( pPrev
, pNext
, pList
->FwdLinkOffset
);
191 // fix up the backward links
193 ASSIGNLINK( pNext
, pPrev
, pList
->BackLinkOffset
);
197 ASSIGNLINK( elem
, NULL
, pList
->FwdLinkOffset
);
198 ASSIGNLINK( elem
, NULL
, pList
->BackLinkOffset
);
202 // GenLinkedOffsetList /////////////////////////////////////////////////////
204 // Extract the Next offset from element
205 #define GETOFFSET( e, o) ( *(size_t*)((char*) (e) + (o)) )
207 static void AssignOffsetLink( void *elem
, void *link
, size_t linkOffset
);
210 static void AssignOffsetLink( void *elem
, void *link
, size_t linkOffset
)
211 // Assign link to elem as an offset from elem. Assign 0 to elem if link is NULL.
213 GETOFFSET( elem
, linkOffset
) = link
? (size_t) link
- (size_t) elem
: 0;
217 void *GetHeadPtr( GenLinkedOffsetList
*pList
)
218 /* Return a pointer to the head element of a list, or NULL if none. */
220 return pList
->Head
? ( (char*) (pList
) + pList
->Head
) : NULL
;
224 void *GetTailPtr( GenLinkedOffsetList
*pList
)
225 /* Return a pointer to the tail element of a list, or NULL if none. */
227 return pList
->Tail
? ( (char*) (pList
) + pList
->Tail
) : NULL
;
231 void *GetOffsetLink( GenLinkedOffsetList
*pList
, void *elem
)
232 /* Return the link pointer contained within element e for pList, or NULL if it is 0. */
236 nextOffset
= GETOFFSET( elem
, pList
->LinkOffset
);
238 return nextOffset
? (char*) elem
+ nextOffset
: NULL
;
242 void InitLinkedOffsetList( GenLinkedOffsetList
*pList
, size_t linkOffset
)
243 /* Initialize the block of memory pointed to by pList as a linked list. */
247 pList
->LinkOffset
= linkOffset
;
251 void OffsetAddToTail( GenLinkedOffsetList
*pList
, void *elem
)
252 /* Add a linked list element to the tail of the list. */
255 AssignOffsetLink( GetTailPtr( pList
), elem
, pList
->LinkOffset
);
257 pList
->Head
= (size_t) elem
- (size_t) pList
;
258 AssignOffsetLink( elem
, NULL
, pList
->LinkOffset
);
260 pList
->Tail
= (size_t) elem
- (size_t) pList
;
264 void OffsetAddToHead( GenLinkedOffsetList
*pList
, void *elem
)
265 /* Add a linked list element to the head of the list. */
267 AssignOffsetLink( elem
, GetHeadPtr( pList
), pList
->LinkOffset
);
268 if ( pList
->Tail
== 0)
269 pList
->Tail
= (size_t) elem
- (size_t) pList
;
271 pList
->Head
= (size_t) elem
- (size_t) pList
;
275 int OffsetRemoveFromList( GenLinkedOffsetList
*pList
, void *elem
)
276 /* Remove a linked list element from the list. Return 0 if it was not found. */
277 /* If the element is removed, its link will be set to NULL. */
279 void *iElem
, *lastElem
;
281 for ( iElem
= GetHeadPtr( pList
), lastElem
= NULL
; iElem
;
282 iElem
= GetOffsetLink( pList
, iElem
))
284 if ( iElem
== elem
) {
285 if ( lastElem
) { // somewhere past the head
286 AssignOffsetLink( lastElem
, GetOffsetLink( pList
, elem
), pList
->LinkOffset
);
287 } else { // at the head
288 iElem
= GetOffsetLink( pList
, elem
);
289 pList
->Head
= iElem
? (size_t) iElem
- (size_t) pList
: 0;
291 if ( GetTailPtr( pList
) == elem
)
292 pList
->Tail
= lastElem
? (size_t) lastElem
- (size_t) pList
: 0;
293 AssignOffsetLink( elem
, NULL
, pList
->LinkOffset
); // maybe catch a stale reference bug.
303 int OffsetReplaceElem( GenLinkedOffsetList
*pList
, void *elemInList
, void *newElem
)
304 /* Replace an element in the list with a new element, in the same position. */
306 void *iElem
, *lastElem
;
308 if ( elemInList
== NULL
|| newElem
== NULL
)
311 for ( iElem
= GetHeadPtr( pList
), lastElem
= NULL
; iElem
;
312 iElem
= GetOffsetLink( pList
, iElem
))
314 if ( iElem
== elemInList
)
316 AssignOffsetLink( newElem
, GetOffsetLink( pList
, elemInList
), pList
->LinkOffset
);
317 if ( lastElem
) // somewhere past the head
319 AssignOffsetLink( lastElem
, newElem
, pList
->LinkOffset
);
323 pList
->Head
= (size_t) newElem
- (size_t) pList
;
325 if ( GetTailPtr( pList
) == elemInList
)
326 pList
->Tail
= (size_t) newElem
- (size_t) pList
;