]>
git.saurik.com Git - apple/mdnsresponder.git/blob - mDNSShared/GenLinkedList.c
04a15812cd4ae70dccb51c653e4948ede711d57c
2 * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
27 Contains: implementation of generic linked lists.
32 Change History (most recent first):
34 $Log: GenLinkedList.c,v $
35 Revision 1.3 2004/04/22 21:14:42 cheshire
36 Fix comment spelling mistake
38 Revision 1.2 2004/02/05 07:41:08 cheshire
43 #include "GenLinkedList.h"
46 // Return the link pointer contained within element e at offset o.
47 #define GETLINK( e, o) ( *(void**)((char*) (e) + (o)) )
49 // Assign the link pointer l to element e at offset o.
50 #define ASSIGNLINK( e, l, o) ( *((void**)((char*) (e) + (o))) = (l))
53 // GenLinkedList /////////////////////////////////////////////////////////////
55 void InitLinkedList( GenLinkedList
*pList
, size_t linkOffset
)
56 /* Initialize the block of memory pointed to by pList as a linked list. */
60 pList
->LinkOffset
= linkOffset
;
64 void AddToTail( GenLinkedList
*pList
, void *elem
)
65 /* Add a linked list element to the tail of the list. */
68 ASSIGNLINK( pList
->Tail
, elem
, pList
->LinkOffset
);
71 ASSIGNLINK( elem
, NULL
, pList
->LinkOffset
);
77 void AddToHead( GenLinkedList
*pList
, void *elem
)
78 /* Add a linked list element to the head of the list. */
80 ASSIGNLINK( elem
, pList
->Head
, pList
->LinkOffset
);
81 if ( pList
->Tail
== NULL
)
88 int RemoveFromList( GenLinkedList
*pList
, void *elem
)
89 /* Remove a linked list element from the list. Return 0 if it was not found. */
90 /* If the element is removed, its link will be set to NULL. */
92 void *iElem
, *lastElem
;
94 for ( iElem
= pList
->Head
, lastElem
= NULL
; iElem
; iElem
= GETLINK( iElem
, pList
->LinkOffset
)) {
96 if ( lastElem
) { // somewhere past the head
97 ASSIGNLINK( lastElem
, GETLINK( elem
, pList
->LinkOffset
), pList
->LinkOffset
);
98 } else { // at the head
99 pList
->Head
= GETLINK( elem
, pList
->LinkOffset
);
101 if ( pList
->Tail
== elem
)
102 pList
->Tail
= lastElem
? lastElem
: NULL
;
103 ASSIGNLINK( elem
, NULL
, pList
->LinkOffset
); // maybe catch a stale reference bug.
113 int ReplaceElem( GenLinkedList
*pList
, void *elemInList
, void *newElem
)
114 /* Replace an element in the list with a new element, in the same position. */
116 void *iElem
, *lastElem
;
118 if ( elemInList
== NULL
|| newElem
== NULL
)
121 for ( iElem
= pList
->Head
, lastElem
= NULL
; iElem
; iElem
= GETLINK( iElem
, pList
->LinkOffset
))
123 if ( iElem
== elemInList
)
125 ASSIGNLINK( newElem
, GETLINK( elemInList
, pList
->LinkOffset
), pList
->LinkOffset
);
126 if ( lastElem
) // somewhere past the head
128 ASSIGNLINK( lastElem
, newElem
, pList
->LinkOffset
);
132 pList
->Head
= newElem
;
134 if ( pList
->Tail
== elemInList
)
135 pList
->Tail
= newElem
;
145 // GenDoubleLinkedList /////////////////////////////////////////////////////////
147 void InitDoubleLinkedList( GenDoubleLinkedList
*pList
, size_t fwdLinkOffset
,
148 size_t backLinkOffset
)
149 /* Initialize the block of memory pointed to by pList as a double linked list. */
153 pList
->FwdLinkOffset
= fwdLinkOffset
;
154 pList
->BackLinkOffset
= backLinkOffset
;
158 void DLLAddToHead( GenDoubleLinkedList
*pList
, void *elem
)
159 /* Add a linked list element to the head of the list. */
165 // fix up the forward links
166 ASSIGNLINK( elem
, pList
->Head
, pList
->FwdLinkOffset
);
169 // fix up the backward links
171 ASSIGNLINK( pNext
, elem
, pList
->BackLinkOffset
);
174 ASSIGNLINK( elem
, NULL
, pList
->BackLinkOffset
);
178 void DLLRemoveFromList( GenDoubleLinkedList
*pList
, void *elem
)
179 /* Remove a linked list element from the list. */
180 /* When the element is removed, its link will be set to NULL. */
184 pNext
= GETLINK( elem
, pList
->FwdLinkOffset
);
185 pPrev
= GETLINK( elem
, pList
->BackLinkOffset
);
187 // fix up the forward links
189 ASSIGNLINK( pPrev
, pNext
, pList
->FwdLinkOffset
);
193 // fix up the backward links
195 ASSIGNLINK( pNext
, pPrev
, pList
->BackLinkOffset
);
199 ASSIGNLINK( elem
, NULL
, pList
->FwdLinkOffset
);
200 ASSIGNLINK( elem
, NULL
, pList
->BackLinkOffset
);
204 // GenLinkedOffsetList /////////////////////////////////////////////////////
206 // Extract the Next offset from element
207 #define GETOFFSET( e, o) ( *(size_t*)((char*) (e) + (o)) )
209 static void AssignOffsetLink( void *elem
, void *link
, size_t linkOffset
);
212 static void AssignOffsetLink( void *elem
, void *link
, size_t linkOffset
)
213 // Assign link to elem as an offset from elem. Assign 0 to elem if link is NULL.
215 GETOFFSET( elem
, linkOffset
) = link
? (size_t) link
- (size_t) elem
: 0;
219 void *GetHeadPtr( GenLinkedOffsetList
*pList
)
220 /* Return a pointer to the head element of a list, or NULL if none. */
222 return pList
->Head
? ( (char*) (pList
) + pList
->Head
) : NULL
;
226 void *GetTailPtr( GenLinkedOffsetList
*pList
)
227 /* Return a pointer to the tail element of a list, or NULL if none. */
229 return pList
->Tail
? ( (char*) (pList
) + pList
->Tail
) : NULL
;
233 void *GetOffsetLink( GenLinkedOffsetList
*pList
, void *elem
)
234 /* Return the link pointer contained within element e for pList, or NULL if it is 0. */
238 nextOffset
= GETOFFSET( elem
, pList
->LinkOffset
);
240 return nextOffset
? (char*) elem
+ nextOffset
: NULL
;
244 void InitLinkedOffsetList( GenLinkedOffsetList
*pList
, size_t linkOffset
)
245 /* Initialize the block of memory pointed to by pList as a linked list. */
249 pList
->LinkOffset
= linkOffset
;
253 void OffsetAddToTail( GenLinkedOffsetList
*pList
, void *elem
)
254 /* Add a linked list element to the tail of the list. */
257 AssignOffsetLink( GetTailPtr( pList
), elem
, pList
->LinkOffset
);
259 pList
->Head
= (size_t) elem
- (size_t) pList
;
260 AssignOffsetLink( elem
, NULL
, pList
->LinkOffset
);
262 pList
->Tail
= (size_t) elem
- (size_t) pList
;
266 void OffsetAddToHead( GenLinkedOffsetList
*pList
, void *elem
)
267 /* Add a linked list element to the head of the list. */
269 AssignOffsetLink( elem
, GetHeadPtr( pList
), pList
->LinkOffset
);
270 if ( pList
->Tail
== 0)
271 pList
->Tail
= (size_t) elem
- (size_t) pList
;
273 pList
->Head
= (size_t) elem
- (size_t) pList
;
277 int OffsetRemoveFromList( GenLinkedOffsetList
*pList
, void *elem
)
278 /* Remove a linked list element from the list. Return 0 if it was not found. */
279 /* If the element is removed, its link will be set to NULL. */
281 void *iElem
, *lastElem
;
283 for ( iElem
= GetHeadPtr( pList
), lastElem
= NULL
; iElem
;
284 iElem
= GetOffsetLink( pList
, iElem
))
286 if ( iElem
== elem
) {
287 if ( lastElem
) { // somewhere past the head
288 AssignOffsetLink( lastElem
, GetOffsetLink( pList
, elem
), pList
->LinkOffset
);
289 } else { // at the head
290 iElem
= GetOffsetLink( pList
, elem
);
291 pList
->Head
= iElem
? (size_t) iElem
- (size_t) pList
: 0;
293 if ( GetTailPtr( pList
) == elem
)
294 pList
->Tail
= lastElem
? (size_t) lastElem
- (size_t) pList
: 0;
295 AssignOffsetLink( elem
, NULL
, pList
->LinkOffset
); // maybe catch a stale reference bug.
305 int OffsetReplaceElem( GenLinkedOffsetList
*pList
, void *elemInList
, void *newElem
)
306 /* Replace an element in the list with a new element, in the same position. */
308 void *iElem
, *lastElem
;
310 if ( elemInList
== NULL
|| newElem
== NULL
)
313 for ( iElem
= GetHeadPtr( pList
), lastElem
= NULL
; iElem
;
314 iElem
= GetOffsetLink( pList
, iElem
))
316 if ( iElem
== elemInList
)
318 AssignOffsetLink( newElem
, GetOffsetLink( pList
, elemInList
), pList
->LinkOffset
);
319 if ( lastElem
) // somewhere past the head
321 AssignOffsetLink( lastElem
, newElem
, pList
->LinkOffset
);
325 pList
->Head
= (size_t) newElem
- (size_t) pList
;
327 if ( GetTailPtr( pList
) == elemInList
)
328 pList
->Tail
= (size_t) newElem
- (size_t) pList
;