FreeRDP
LinkedList.c
1 
20 #include <winpr/config.h>
21 
22 #include <winpr/collections.h>
23 #include <winpr/assert.h>
24 
25 typedef struct s_wLinkedListItem wLinkedListNode;
26 
27 struct s_wLinkedListItem
28 {
29  void* value;
30  wLinkedListNode* prev;
31  wLinkedListNode* next;
32 };
33 
34 struct s_wLinkedList
35 {
36  size_t count;
37  int initial;
38  wLinkedListNode* head;
39  wLinkedListNode* tail;
40  wLinkedListNode* current;
41  wObject object;
42 };
43 
59 size_t LinkedList_Count(wLinkedList* list)
60 {
61  WINPR_ASSERT(list);
62  return list->count;
63 }
64 
69 void* LinkedList_First(wLinkedList* list)
70 {
71  WINPR_ASSERT(list);
72  if (list->head)
73  return list->head->value;
74  else
75  return NULL;
76 }
77 
82 void* LinkedList_Last(wLinkedList* list)
83 {
84  WINPR_ASSERT(list);
85  if (list->tail)
86  return list->tail->value;
87  else
88  return NULL;
89 }
90 
99 BOOL LinkedList_Contains(wLinkedList* list, const void* value)
100 {
101  wLinkedListNode* item = NULL;
102  OBJECT_EQUALS_FN keyEquals = NULL;
103 
104  WINPR_ASSERT(list);
105  if (!list->head)
106  return FALSE;
107 
108  item = list->head;
109  keyEquals = list->object.fnObjectEquals;
110 
111  while (item)
112  {
113  if (keyEquals(item->value, value))
114  break;
115 
116  item = item->next;
117  }
118 
119  return (item) ? TRUE : FALSE;
120 }
121 
122 static wLinkedListNode* LinkedList_FreeNode(wLinkedList* list, wLinkedListNode* node)
123 {
124  wLinkedListNode* next = NULL;
125  wLinkedListNode* prev = NULL;
126 
127  WINPR_ASSERT(list);
128  WINPR_ASSERT(node);
129 
130  next = node->next;
131  prev = node->prev;
132  if (prev)
133  prev->next = next;
134 
135  if (next)
136  next->prev = prev;
137 
138  if (node == list->head)
139  list->head = node->next;
140 
141  if (node == list->tail)
142  list->tail = node->prev;
143 
144  if (list->object.fnObjectUninit)
145  list->object.fnObjectUninit(node);
146 
147  if (list->object.fnObjectFree)
148  list->object.fnObjectFree(node);
149 
150  free(node);
151  list->count--;
152  return next;
153 }
154 
159 void LinkedList_Clear(wLinkedList* list)
160 {
161  wLinkedListNode* node = NULL;
162  WINPR_ASSERT(list);
163  if (!list->head)
164  return;
165 
166  node = list->head;
167 
168  while (node)
169  node = LinkedList_FreeNode(list, node);
170 
171  list->head = list->tail = NULL;
172  list->count = 0;
173 }
174 
175 static wLinkedListNode* LinkedList_Create(wLinkedList* list, const void* value)
176 {
177  wLinkedListNode* node = NULL;
178 
179  WINPR_ASSERT(list);
180  node = (wLinkedListNode*)calloc(1, sizeof(wLinkedListNode));
181 
182  if (!node)
183  return NULL;
184 
185  if (list->object.fnObjectNew)
186  node->value = list->object.fnObjectNew(value);
187  else
188  {
189  union
190  {
191  const void* cpv;
192  void* pv;
193  } cnv;
194  cnv.cpv = value;
195  node->value = cnv.pv;
196  }
197 
198  if (list->object.fnObjectInit)
199  list->object.fnObjectInit(node);
200 
201  return node;
202 }
207 BOOL LinkedList_AddFirst(wLinkedList* list, const void* value)
208 {
209  wLinkedListNode* node = LinkedList_Create(list, value);
210 
211  if (!node)
212  return FALSE;
213 
214  if (!list->head)
215  {
216  list->tail = list->head = node;
217  }
218  else
219  {
220  list->head->prev = node;
221  node->next = list->head;
222  list->head = node;
223  }
224 
225  list->count++;
226  return TRUE;
227 }
228 
233 BOOL LinkedList_AddLast(wLinkedList* list, const void* value)
234 {
235  wLinkedListNode* node = LinkedList_Create(list, value);
236 
237  if (!node)
238  return FALSE;
239 
240  if (!list->tail)
241  {
242  list->head = list->tail = node;
243  }
244  else
245  {
246  list->tail->next = node;
247  node->prev = list->tail;
248  list->tail = node;
249  }
250 
251  list->count++;
252  return TRUE;
253 }
254 
259 BOOL LinkedList_Remove(wLinkedList* list, const void* value)
260 {
261  wLinkedListNode* node = NULL;
262  OBJECT_EQUALS_FN keyEquals = NULL;
263  WINPR_ASSERT(list);
264 
265  keyEquals = list->object.fnObjectEquals;
266  node = list->head;
267 
268  while (node)
269  {
270  if (keyEquals(node->value, value))
271  {
272  LinkedList_FreeNode(list, node);
273  return TRUE;
274  }
275 
276  node = node->next;
277  }
278 
279  return FALSE;
280 }
281 
286 void LinkedList_RemoveFirst(wLinkedList* list)
287 {
288  WINPR_ASSERT(list);
289  if (list->head)
290  LinkedList_FreeNode(list, list->head);
291 }
292 
297 void LinkedList_RemoveLast(wLinkedList* list)
298 {
299  WINPR_ASSERT(list);
300  if (list->tail)
301  LinkedList_FreeNode(list, list->tail);
302 }
303 
308 void LinkedList_Enumerator_Reset(wLinkedList* list)
309 {
310  WINPR_ASSERT(list);
311  list->initial = 1;
312  list->current = list->head;
313 }
314 
315 /*
316  * Gets the element at the current position of the enumerator.
317  */
318 
319 void* LinkedList_Enumerator_Current(wLinkedList* list)
320 {
321  WINPR_ASSERT(list);
322  if (list->initial)
323  return NULL;
324 
325  if (list->current)
326  return list->current->value;
327  else
328  return NULL;
329 }
330 
331 /*
332  * Advances the enumerator to the next element of the LinkedList.
333  */
334 
335 BOOL LinkedList_Enumerator_MoveNext(wLinkedList* list)
336 {
337  WINPR_ASSERT(list);
338  if (list->initial)
339  list->initial = 0;
340  else if (list->current)
341  list->current = list->current->next;
342 
343  if (!list->current)
344  return FALSE;
345 
346  return TRUE;
347 }
348 
349 static BOOL default_equal_function(const void* objA, const void* objB)
350 {
351  return objA == objB;
352 }
353 
358 wLinkedList* LinkedList_New(void)
359 {
360  wLinkedList* list = NULL;
361  list = (wLinkedList*)calloc(1, sizeof(wLinkedList));
362 
363  if (list)
364  {
365  list->object.fnObjectEquals = default_equal_function;
366  }
367 
368  return list;
369 }
370 
371 void LinkedList_Free(wLinkedList* list)
372 {
373  if (list)
374  {
375  LinkedList_Clear(list);
376  free(list);
377  }
378 }
379 
380 wObject* LinkedList_Object(wLinkedList* list)
381 {
382  WINPR_ASSERT(list);
383 
384  return &list->object;
385 }
This struct contains function pointer to initialize/free objects.
Definition: collections.h:57