You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
425 lines
11 KiB
425 lines
11 KiB
/*++
|
|
|
|
Copyright (c) 1999, Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
sample\list.h
|
|
|
|
Abstract:
|
|
|
|
The file contains a list implementation.
|
|
|
|
--*/
|
|
|
|
#ifndef _LIST_H_
|
|
#define _LIST_H_
|
|
|
|
/*++
|
|
|
|
The Following are already defined
|
|
|
|
(public\sdk\inc\winnt.h)
|
|
|
|
//
|
|
// Calculate the byte offset of a 'field' in a structure of type 'type'.
|
|
//
|
|
// #define FIELD_OFFSET(type, field) \
|
|
// ((LONG)(LONG_PTR)&(((type *)0)->field))
|
|
//
|
|
|
|
//
|
|
// Calculate the address of the base of the structure given its 'type',
|
|
// and an 'address' of a 'field' within the structure.
|
|
//
|
|
// #define CONTAINING_RECORD(address, type, field) \
|
|
// ((type *)((PCHAR)(address) - (ULONG_PTR)(&((type *)0)->field)))
|
|
//
|
|
|
|
// Doubly linked list structure.
|
|
//
|
|
// typedef struct _LIST_ENTRY
|
|
// {
|
|
// struct _LIST_ENTRY *Flink;
|
|
// struct _LIST_ENTRY *Blink;
|
|
// } LIST_ENTRY, *PLIST_ENTRY;
|
|
//
|
|
|
|
--*/
|
|
|
|
//
|
|
// Doubly-linked list manipulation routines. Implemented as macros but
|
|
// logically these are procedures.
|
|
//
|
|
|
|
|
|
|
|
//
|
|
// VOID
|
|
// InitializeListHead(
|
|
// PLIST_ENTRY ListHead
|
|
// );
|
|
//
|
|
|
|
#define InitializeListHead(ListHead) \
|
|
((ListHead)->Flink = (ListHead)->Blink = (ListHead))
|
|
|
|
|
|
|
|
//
|
|
// BOOLEAN
|
|
// IsListEmpty(
|
|
// PLIST_ENTRY ListHead
|
|
// );
|
|
//
|
|
|
|
#define IsListEmpty(ListHead) \
|
|
((ListHead)->Flink == (ListHead))
|
|
|
|
|
|
|
|
//
|
|
// PLIST_ENTRY
|
|
// RemoveHeadList(
|
|
// PLIST_ENTRY ListHead
|
|
// );
|
|
//
|
|
|
|
#define RemoveHeadList(ListHead) \
|
|
(ListHead)->Flink; \
|
|
{RemoveEntryList((ListHead)->Flink)}
|
|
|
|
|
|
|
|
//
|
|
// PLIST_ENTRY
|
|
// RemoveTailList(
|
|
// PLIST_ENTRY ListHead
|
|
// );
|
|
//
|
|
|
|
#define RemoveTailList(ListHead) \
|
|
(ListHead)->Blink; \
|
|
{RemoveEntryList((ListHead)->Blink)}
|
|
|
|
|
|
|
|
//
|
|
// VOID
|
|
// RemoveEntryList(
|
|
// PLIST_ENTRY Entry
|
|
// );
|
|
//
|
|
|
|
#define RemoveEntryList(Entry) \
|
|
{ \
|
|
PLIST_ENTRY _EX_Blink; \
|
|
PLIST_ENTRY _EX_Flink; \
|
|
_EX_Flink = (Entry)->Flink; \
|
|
_EX_Blink = (Entry)->Blink; \
|
|
_EX_Blink->Flink = _EX_Flink; \
|
|
_EX_Flink->Blink = _EX_Blink; \
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// VOID
|
|
// InsertTailList(
|
|
// PLIST_ENTRY ListHead,
|
|
// PLIST_ENTRY Entry
|
|
// );
|
|
//
|
|
|
|
#define InsertTailList(ListHead,Entry) \
|
|
{ \
|
|
PLIST_ENTRY _EX_Blink; \
|
|
PLIST_ENTRY _EX_ListHead; \
|
|
_EX_ListHead = (ListHead); \
|
|
_EX_Blink = _EX_ListHead->Blink; \
|
|
(Entry)->Flink = _EX_ListHead; \
|
|
(Entry)->Blink = _EX_Blink; \
|
|
_EX_Blink->Flink = (Entry); \
|
|
_EX_ListHead->Blink = (Entry); \
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// VOID
|
|
// InsertHeadList(
|
|
// PLIST_ENTRY ListHead,
|
|
// PLIST_ENTRY Entry
|
|
// );
|
|
//
|
|
|
|
#define InsertHeadList(ListHead,Entry) \
|
|
{ \
|
|
PLIST_ENTRY _EX_Flink; \
|
|
PLIST_ENTRY _EX_ListHead; \
|
|
_EX_ListHead = (ListHead); \
|
|
_EX_Flink = _EX_ListHead->Flink; \
|
|
(Entry)->Flink = _EX_Flink; \
|
|
(Entry)->Blink = _EX_ListHead; \
|
|
_EX_Flink->Blink = (Entry); \
|
|
_EX_ListHead->Flink = (Entry); \
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// VOID
|
|
// InsertSortedList(
|
|
// PLIST_ENTRY ListHead,
|
|
// PLIST_ENTRY Entry,
|
|
// LONG(*CompareFunction)(PLIST_ENTRY, PLIST_ENTRY)
|
|
// );
|
|
//
|
|
|
|
#define InsertSortedList(ListHead, Entry, CompareFunction) \
|
|
{ \
|
|
PLIST_ENTRY _EX_Entry; \
|
|
PLIST_ENTRY _EX_Blink; \
|
|
for (_EX_Entry = (ListHead)->Flink; \
|
|
_EX_Entry != (ListHead); \
|
|
_EX_Entry = _EX_Entry->Flink) \
|
|
if ((*(CompareFunction))((Entry), _EX_Entry) <= 0) \
|
|
break; \
|
|
_EX_Blink = _EX_Entry->Blink; \
|
|
_EX_Blink->Flink = (Entry); \
|
|
_EX_Entry->Blink = (Entry); \
|
|
(Entry)->Flink = _EX_Entry; \
|
|
(Entry)->Blink = _EX_Blink; \
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// Finds an 'Entry' equal to 'Key' in a 'List'
|
|
//
|
|
// VOID
|
|
// FindList(
|
|
// PLIST_ENTRY ListHead,
|
|
// PLIST_ENTRY Key,
|
|
// PLIST_ENTRY *Entry,
|
|
// LONG (*CompareFunction)(PLIST_ENTRY, PLIST_ENTRY)
|
|
// );
|
|
//
|
|
|
|
#define FindList(ListHead, Key, Entry, CompareFunction) \
|
|
{ \
|
|
PLIST_ENTRY _EX_Entry; \
|
|
*(Entry) = NULL; \
|
|
for (_EX_Entry = (ListHead)->Flink; \
|
|
_EX_Entry != (ListHead); \
|
|
_EX_Entry = _EX_Entry->Flink) \
|
|
if ((*(CompareFunction))((Key), _EX_Entry) is 0) \
|
|
{ \
|
|
*(Entry) = _EX_Entry; \
|
|
break; \
|
|
} \
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// Finds an 'Entry' equal to or greater than 'Key' in a sorted 'List'
|
|
//
|
|
// VOID
|
|
// FindSortedList(
|
|
// PLIST_ENTRY ListHead,
|
|
// PLIST_ENTRY Key,
|
|
// PLIST_ENTRY *Entry,
|
|
// LONG (*CompareFunction)(PLIST_ENTRY, PLIST_ENTRY)
|
|
// );
|
|
//
|
|
|
|
#define FindSortedList(ListHead, Key, Entry, CompareFunction) \
|
|
{ \
|
|
PLIST_ENTRY _EX_Entry; \
|
|
*(Entry) = NULL; \
|
|
for (_EX_Entry = (ListHead)->Flink; \
|
|
_EX_Entry != (ListHead); \
|
|
_EX_Entry = _EX_Entry->Flink) \
|
|
if ((*(CompareFunction))((Key), _EX_Entry) <= 0) \
|
|
{ \
|
|
*(Entry) = _EX_Entry; \
|
|
break; \
|
|
} \
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// Applies a 'Function' to all entries in a list.
|
|
//
|
|
// VOID
|
|
// MapCarList(
|
|
// PLIST_ENTRY ListHead,
|
|
// VOID(*VoidFunction)(PLIST_ENTRY)
|
|
// );
|
|
//
|
|
|
|
#define MapCarList(ListHead, VoidFunction) \
|
|
{ \
|
|
PLIST_ENTRY _EX_Entry; \
|
|
for (_EX_Entry = (ListHead)->Flink; \
|
|
_EX_Entry != (ListHead); \
|
|
_EX_Entry = _EX_Entry->Flink) \
|
|
(*(VoidFunction))(_EX_Entry); \
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// Frees a list.
|
|
//
|
|
// VOID
|
|
// FreeList(
|
|
// PLIST_ENTRY ListHead,
|
|
// VOID(*FreeFunction)(PLIST_ENTRY)
|
|
// );
|
|
//
|
|
|
|
#define FreeList(ListHead, FreeFunction) \
|
|
{ \
|
|
PLIST_ENTRY _EX_Head; \
|
|
while (!IsListEmpty(ListHead)) \
|
|
{ \
|
|
_EX_Head = RemoveHeadList(ListHead); \
|
|
(*(FreeFunction))(_EX_Head); \
|
|
} \
|
|
}
|
|
|
|
|
|
|
|
#define QUEUE_ENTRY LIST_ENTRY
|
|
#define PQUEUE_ENTRY PLIST_ENTRY
|
|
|
|
//
|
|
// VOID
|
|
// InitializeQueueHead(
|
|
// PQUEUE_ENTRY QueueHead
|
|
// );
|
|
//
|
|
|
|
#define InitializeQueueHead(QueueHead) InitializeListHead(QueueHead)
|
|
|
|
//
|
|
// BOOLEAN
|
|
// IsQueueEmpty(
|
|
// PQUEUE_ENTRY QueueHead
|
|
// );
|
|
//
|
|
|
|
#define IsQueueEmpty(QueueHead) IsListEmpty(QueueHead)
|
|
|
|
//
|
|
// VOID
|
|
// Enqueue(
|
|
// PQUEUE_ENTRY QueueHead,
|
|
// PQUEUE_ENTRY Entry
|
|
// );
|
|
//
|
|
|
|
#define Enqueue(QueueHead, Entry) InsertTailList(QueueHead, Entry)
|
|
|
|
//
|
|
// PQUEUE_ENTRY
|
|
// Dequeue(
|
|
// PQUEUE_ENTRY QueueHead,
|
|
// );
|
|
//
|
|
|
|
#define Dequeue(QueueHead) RemoveHeadList(QueueHead)
|
|
|
|
//
|
|
// VOID
|
|
// FreeQueue(
|
|
// PQUEUE_ENTRY QueueHead,
|
|
// VOID(*FreeFunction)(PQUEUE_ENTRY)
|
|
// );
|
|
//
|
|
|
|
#define FreeQueue(QueueHead, FreeFunction) \
|
|
FreeList(QueueHead, FreeFunction)
|
|
|
|
//
|
|
// VOID
|
|
// MapCarQueue(
|
|
// PQUEUE_ENTRY QueueHead,
|
|
// VOID(*VoidFunction)(PQUEUE_ENTRY)
|
|
// );
|
|
//
|
|
|
|
#define MapCarQueue(QueueHead, VoidFunction) \
|
|
MapCarList(QueueHead, VoidFunction)
|
|
|
|
|
|
|
|
#define STACK_ENTRY LIST_ENTRY
|
|
#define PSTACK_ENTRY PLIST_ENTRY
|
|
|
|
//
|
|
// VOID
|
|
// InitializeStackHead(
|
|
// PSTACK_ENTRY StackHead
|
|
// );
|
|
//
|
|
|
|
#define InitializeStackHead(StackHead) InitializeListHead(StackHead)
|
|
|
|
//
|
|
// BOOLEAN
|
|
// IsStackEmpty(
|
|
// PSTACK_ENTRY StackHead
|
|
// );
|
|
//
|
|
|
|
#define IsStackEmpty(StackHead) IsListEmpty(StackHead)
|
|
|
|
//
|
|
// VOID
|
|
// Push(
|
|
// PSTACK_ENTRY StackHead,
|
|
// PSTACK_ENTRY Entry
|
|
// );
|
|
//
|
|
|
|
#define Push(StackHead, Entry) InsertHeadList(StackHead, Entry)
|
|
|
|
//
|
|
// PSTACK_ENTRY
|
|
// Pop(
|
|
// PSTACK_ENTRY StackHead,
|
|
// );
|
|
//
|
|
|
|
#define Pop(StackHead) RemoveHeadList(StackHead)
|
|
|
|
//
|
|
// VOID
|
|
// FreeStack(
|
|
// PSTACK_ENTRY StackHead,
|
|
// VOID(*FreeFunction)(PSTACK_ENTRY)
|
|
// );
|
|
//
|
|
|
|
#define FreeStack(StackHead, FreeFunction) \
|
|
FreeList(StackHead, FreeFunction)
|
|
|
|
//
|
|
// VOID
|
|
// MapCarStack(
|
|
// PSTACK_ENTRY StackHead,
|
|
// VOID(*VoidFunction)(PSTACK_ENTRY)
|
|
// );
|
|
//
|
|
|
|
#define MapCarStack(StackHead, VoidFunction) \
|
|
MapCarList(StackHead, VoidFunction)
|
|
|
|
#endif // _LIST_H_
|
|
|
|
|
|
|