LinkedList.c
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright (c) 2009, 2020 IBM Corp.
3  *
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v2.0
6  * and Eclipse Distribution License v1.0 which accompany this distribution.
7  *
8  * The Eclipse Public License is available at
9  * https://www.eclipse.org/legal/epl-2.0/
10  * and the Eclipse Distribution License is available at
11  * http://www.eclipse.org/org/documents/edl-v10.php.
12  *
13  * Contributors:
14  * Ian Craggs - initial API and implementation and/or initial documentation
15  * Ian Craggs - updates for the async client
16  *******************************************************************************/
17 
27 #include "LinkedList.h"
28 
29 #include <stdlib.h>
30 #include <string.h>
31 
32 #include "Heap.h"
33 
34 
35 static int ListUnlink(List* aList, void* content, int(*callback)(void*, void*), int freeContent);
36 
37 
42 void ListZero(List* newl)
43 {
44  memset(newl, '\0', sizeof(List));
45 }
46 
47 
53 {
54  List* newl = malloc(sizeof(List));
55  if (newl)
56  ListZero(newl);
57  return newl;
58 }
59 
60 
69 void ListAppendNoMalloc(List* aList, void* content, ListElement* newel, size_t size)
70 { /* for heap use */
71  newel->content = content;
72  newel->next = NULL;
73  newel->prev = aList->last;
74  if (aList->first == NULL)
75  aList->first = newel;
76  else
77  aList->last->next = newel;
78  aList->last = newel;
79  ++(aList->count);
80  aList->size += size;
81 }
82 
83 
90 ListElement* ListAppend(List* aList, void* content, size_t size)
91 {
92  ListElement* newel = malloc(sizeof(ListElement));
93  if (newel)
94  ListAppendNoMalloc(aList, content, newel, size);
95  return newel;
96 }
97 
98 
107 ListElement* ListInsert(List* aList, void* content, size_t size, ListElement* index)
108 {
109  ListElement* newel = malloc(sizeof(ListElement));
110 
111  if (newel == NULL)
112  return newel;
113  if ( index == NULL )
114  ListAppendNoMalloc(aList, content, newel, size);
115  else
116  {
117  newel->content = content;
118  newel->next = index;
119  newel->prev = index->prev;
120 
121  index->prev = newel;
122  if ( newel->prev != NULL )
123  newel->prev->next = newel;
124  else
125  aList->first = newel;
126 
127  ++(aList->count);
128  aList->size += size;
129  }
130  return newel;
131 }
132 
133 
140 ListElement* ListFind(List* aList, void* content)
141 {
142  return ListFindItem(aList, content, NULL);
143 }
144 
145 
154 ListElement* ListFindItem(List* aList, void* content, int(*callback)(void*, void*))
155 {
156  ListElement* rc = NULL;
157 
158  if (aList->current != NULL && ((callback == NULL && aList->current->content == content) ||
159  (callback != NULL && callback(aList->current->content, content))))
160  rc = aList->current;
161  else
162  {
163  ListElement* current = NULL;
164 
165  /* find the content */
166  while (ListNextElement(aList, &current) != NULL)
167  {
168  if (callback == NULL)
169  {
170  if (current->content == content)
171  {
172  rc = current;
173  break;
174  }
175  }
176  else
177  {
178  if (callback(current->content, content))
179  {
180  rc = current;
181  break;
182  }
183  }
184  }
185  if (rc != NULL)
186  aList->current = rc;
187  }
188  return rc;
189 }
190 
191 
201 static int ListUnlink(List* aList, void* content, int(*callback)(void*, void*), int freeContent)
202 {
203  ListElement* next = NULL;
204  ListElement* saved = aList->current;
205  int saveddeleted = 0;
206 
207  if (!ListFindItem(aList, content, callback))
208  return 0; /* false, did not remove item */
209 
210  if (aList->current->prev == NULL)
211  /* so this is the first element, and we have to update the "first" pointer */
212  aList->first = aList->current->next;
213  else
214  aList->current->prev->next = aList->current->next;
215 
216  if (aList->current->next == NULL)
217  aList->last = aList->current->prev;
218  else
219  aList->current->next->prev = aList->current->prev;
220 
221  next = aList->current->next;
222  if (freeContent)
223  {
224  free(aList->current->content);
225  aList->current->content = NULL;
226  }
227  if (saved == aList->current)
228  saveddeleted = 1;
229  free(aList->current);
230  if (saveddeleted)
231  aList->current = next;
232  else
233  aList->current = saved;
234  --(aList->count);
235  return 1; /* successfully removed item */
236 }
237 
238 
245 int ListDetach(List* aList, void* content)
246 {
247  return ListUnlink(aList, content, NULL, 0);
248 }
249 
250 
257 int ListRemove(List* aList, void* content)
258 {
259  return ListUnlink(aList, content, NULL, 1);
260 }
261 
262 
268 void* ListDetachHead(List* aList)
269 {
270  void *content = NULL;
271  if (aList->count > 0)
272  {
273  ListElement* first = aList->first;
274  if (aList->current == first)
275  aList->current = first->next;
276  if (aList->last == first) /* i.e. no of items in list == 1 */
277  aList->last = NULL;
278  content = first->content;
279  aList->first = aList->first->next;
280  if (aList->first)
281  aList->first->prev = NULL;
282  free(first);
283  --(aList->count);
284  }
285  return content;
286 }
287 
288 
294 int ListRemoveHead(List* aList)
295 {
296  free(ListDetachHead(aList));
297  return 0;
298 }
299 
300 
306 void* ListPopTail(List* aList)
307 {
308  void* content = NULL;
309  if (aList->count > 0)
310  {
311  ListElement* last = aList->last;
312  if (aList->current == last)
313  aList->current = last->prev;
314  if (aList->first == last) /* i.e. no of items in list == 1 */
315  aList->first = NULL;
316  content = last->content;
317  aList->last = aList->last->prev;
318  if (aList->last)
319  aList->last->next = NULL;
320  free(last);
321  --(aList->count);
322  }
323  return content;
324 }
325 
326 
335 int ListDetachItem(List* aList, void* content, int(*callback)(void*, void*))
336 { /* do not free the content */
337  return ListUnlink(aList, content, callback, 0);
338 }
339 
340 
349 int ListRemoveItem(List* aList, void* content, int(*callback)(void*, void*))
350 { /* remove from list and free the content */
351  return ListUnlink(aList, content, callback, 1);
352 }
353 
354 
359 void ListEmpty(List* aList)
360 {
361  while (aList->first != NULL)
362  {
363  ListElement* first = aList->first;
364  if (first->content != NULL)
365  {
366  free(first->content);
367  first->content = NULL;
368  }
369  aList->first = first->next;
370  free(first);
371  }
372  aList->count = 0;
373  aList->size = 0;
374  aList->current = aList->first = aList->last = NULL;
375 }
376 
381 void ListFree(List* aList)
382 {
383  ListEmpty(aList);
384  free(aList);
385 }
386 
387 
393 {
394  while (aList->first != NULL)
395  {
396  ListElement* first = aList->first;
397  aList->first = first->next;
398  free(first);
399  }
400  free(aList);
401 }
402 
403 
412 {
413  return *pos = (*pos == NULL) ? aList->first : (*pos)->next;
414 }
415 
416 
425 {
426  return *pos = (*pos == NULL) ? aList->last : (*pos)->prev;
427 }
428 
429 
436 int intcompare(void* a, void* b)
437 {
438  return *((int*)a) == *((int*)b);
439 }
440 
441 
448 int stringcompare(void* a, void* b)
449 {
450  return strcmp((char*)a, (char*)b) == 0;
451 }
452 
453 
454 #if defined(UNIT_TESTS)
455 
456 
457 int main(int argc, char *argv[])
458 {
459  int i, *ip, *todelete;
460  ListElement* current = NULL;
461  List* l = ListInitialize();
462  printf("List initialized\n");
463 
464  for (i = 0; i < 10; i++)
465  {
466  ip = malloc(sizeof(int));
467  *ip = i;
468  ListAppend(l, (void*)ip, sizeof(int));
469  if (i==5)
470  todelete = ip;
471  printf("List element appended %d\n", *((int*)(l->last->content)));
472  }
473 
474  printf("List contents:\n");
475  current = NULL;
476  while (ListNextElement(l, &current) != NULL)
477  printf("List element: %d\n", *((int*)(current->content)));
478 
479  printf("List contents in reverse order:\n");
480  current = NULL;
481  while (ListPrevElement(l, &current) != NULL)
482  printf("List element: %d\n", *((int*)(current->content)));
483 
484  /* if ListFindItem(l, *ip, intcompare)->content */
485 
486  printf("List contents having deleted element %d:\n", *todelete);
487  ListRemove(l, todelete);
488  current = NULL;
489  while (ListNextElement(l, &current) != NULL)
490  printf("List element: %d\n", *((int*)(current->content)));
491 
492  i = 9;
493  ListRemoveItem(l, &i, intcompare);
494  printf("List contents having deleted another element, %d, size now %d:\n", i, l->size);
495  current = NULL;
496  while (ListNextElement(l, &current) != NULL)
497  printf("List element: %d\n", *((int*)(current->content)));
498 
499  ListFree(l);
500  printf("List freed\n");
501 }
502 
503 #endif
504 
505 
506 
507 
508 
size_t size
Definition: LinkedList.h:73
ListElement * current
Definition: LinkedList.h:69
#define malloc(x)
Definition: Heap.h:41
void ListZero(List *newl)
Definition: LinkedList.c:42
int ListRemove(List *aList, void *content)
Definition: LinkedList.c:257
struct ListElementStruct * next
Definition: LinkedList.h:58
int ListDetach(List *aList, void *content)
Definition: LinkedList.c:245
int stringcompare(void *a, void *b)
Definition: LinkedList.c:448
#define free(x)
Definition: Heap.h:55
ListElement * ListInsert(List *aList, void *content, size_t size, ListElement *index)
Definition: LinkedList.c:107
void ListEmpty(List *aList)
Definition: LinkedList.c:359
void * ListDetachHead(List *aList)
Definition: LinkedList.c:268
void ListAppendNoMalloc(List *aList, void *content, ListElement *newel, size_t size)
Definition: LinkedList.c:69
int count
Definition: LinkedList.h:72
ListElement * ListNextElement(List *aList, ListElement **pos)
Definition: LinkedList.c:411
void * ListPopTail(List *aList)
Definition: LinkedList.c:306
int ListRemoveItem(List *aList, void *content, int(*callback)(void *, void *))
Definition: LinkedList.c:349
static int ListUnlink(List *aList, void *content, int(*callback)(void *, void *), int freeContent)
Definition: LinkedList.c:201
#define next(ls)
Definition: llex.c:32
struct ListElementStruct * prev
Definition: LinkedList.h:58
ListElement * ListAppend(List *aList, void *content, size_t size)
Definition: LinkedList.c:90
ListElement * ListPrevElement(List *aList, ListElement **pos)
Definition: LinkedList.c:424
ListElement * last
Definition: LinkedList.h:69
int ListRemoveHead(List *aList)
Definition: LinkedList.c:294
List * ListInitialize(void)
Definition: LinkedList.c:52
int ListDetachItem(List *aList, void *content, int(*callback)(void *, void *))
Definition: LinkedList.c:335
void ListFreeNoContent(List *aList)
Definition: LinkedList.c:392
ListElement * ListFindItem(List *aList, void *content, int(*callback)(void *, void *))
Definition: LinkedList.c:154
ListElement * first
Definition: LinkedList.h:69
ListElement * ListFind(List *aList, void *content)
Definition: LinkedList.c:140
int intcompare(void *a, void *b)
Definition: LinkedList.c:436
void ListFree(List *aList)
Definition: LinkedList.c:381
enum MQTTReasonCodes rc
Definition: test10.c:1112
int main(int argc, char **argv)
Definition: lua.c:619


plotjuggler
Author(s): Davide Faconti
autogenerated on Sun Dec 6 2020 03:48:09