8f1d97cb45c6b8a9288d5030cf3903d58ec54b4a
[reactos.git] / reactos / boot / freeldr / freeldr / rtl / list.c
1 /*
2 * FreeLoader
3 * Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 #include <freeldr.h>
21
22 VOID RtlListInitializeHead(PLIST_ITEM ListHead)
23 {
24 ListHead->ListPrev = NULL;
25 ListHead->ListNext = NULL;
26 }
27
28 VOID RtlListInsertHead(PLIST_ITEM ListHead, PLIST_ITEM Entry)
29 {
30 ListHead = RtlListGetHead(ListHead);
31 ListHead->ListPrev = Entry;
32 Entry->ListNext = ListHead;
33 Entry->ListPrev = NULL;
34 }
35
36 VOID RtlListInsertTail(PLIST_ITEM ListHead, PLIST_ITEM Entry)
37 {
38 ListHead = RtlListGetTail(ListHead);
39 ListHead->ListNext = Entry;
40 Entry->ListNext = NULL;
41 Entry->ListPrev = ListHead;
42 }
43
44 PLIST_ITEM RtlListRemoveHead(PLIST_ITEM ListHead)
45 {
46 PLIST_ITEM OldListHead = RtlListGetHead(ListHead);
47
48 ListHead = ListHead->ListNext;
49 ListHead->ListPrev = NULL;
50
51 return OldListHead;
52 }
53
54 PLIST_ITEM RtlListRemoveTail(PLIST_ITEM ListHead)
55 {
56 PLIST_ITEM ListTail;
57
58 ListTail = RtlListGetTail(ListHead);
59 ListHead = ListTail->ListPrev;
60 ListHead->ListNext = NULL;
61
62 return ListTail;
63 }
64
65 PLIST_ITEM RtlListGetHead(PLIST_ITEM ListHead)
66 {
67 while (ListHead->ListPrev != NULL)
68 {
69 ListHead = ListHead->ListPrev;
70 }
71
72 return ListHead;
73 }
74
75 PLIST_ITEM RtlListGetTail(PLIST_ITEM ListHead)
76 {
77 while (ListHead->ListNext != NULL)
78 {
79 ListHead = ListHead->ListNext;
80 }
81
82 return ListHead;
83 }
84
85 BOOL RtlListIsEmpty(PLIST_ITEM ListHead)
86 {
87 if (ListHead == NULL)
88 {
89 return TRUE;
90 }
91
92 return (ListHead->ListNext == NULL);
93 }
94
95 ULONG RtlListCountEntries(PLIST_ITEM ListHead)
96 {
97 ULONG Count = 0;
98
99 while (ListHead != NULL)
100 {
101 Count++;
102 ListHead = ListHead->ListNext;
103 }
104
105 return Count;
106 }
107
108 PLIST_ITEM RtlListGetPrevious(PLIST_ITEM ListEntry)
109 {
110 return ListEntry->ListPrev;
111 }
112
113 PLIST_ITEM RtlListGetNext(PLIST_ITEM ListEntry)
114 {
115 return ListEntry->ListNext;
116 }
117
118 PLIST_ITEM RtlListRemoveEntry(PLIST_ITEM ListEntry)
119 {
120 PLIST_ITEM ListNext = RtlListGetNext(ListEntry);
121 PLIST_ITEM ListPrev = RtlListGetPrevious(ListEntry);
122
123 if (ListPrev != NULL)
124 {
125 ListPrev->ListNext = ListNext;
126 }
127
128 if (ListNext != NULL)
129 {
130 ListNext->ListPrev = ListPrev;
131 }
132
133 return ListNext;
134 }
135
136 VOID RtlListInsertEntry(PLIST_ITEM InsertAfter, PLIST_ITEM ListEntry)
137 {
138 PLIST_ITEM ListNext = RtlListGetNext(InsertAfter);
139
140 InsertAfter->ListNext = ListEntry;
141 ListEntry->ListPrev = InsertAfter;
142 ListEntry->ListNext = ListNext;
143 }
144
145 VOID RtlListMoveEntryPrevious(PLIST_ITEM ListEntry)
146 {
147 PLIST_ITEM ListPrev = RtlListGetPrevious(ListEntry);
148
149 if (ListPrev == NULL)
150 {
151 return;
152 }
153
154 //
155 // Move the previous entry after this one
156 //
157 RtlListRemoveEntry(ListPrev);
158 RtlListInsertEntry(ListEntry, ListPrev);
159 }
160
161 VOID RtlListMoveEntryNext(PLIST_ITEM ListEntry)
162 {
163 PLIST_ITEM ListNext = RtlListGetNext(ListEntry);
164
165 if (ListNext == NULL)
166 {
167 return;
168 }
169
170 //
171 // Move this entry after the next entry
172 //
173 RtlListRemoveEntry(ListEntry);
174 RtlListInsertEntry(ListNext, ListEntry);
175 }