Fix changelog email address
[freerdp-ubuntu-pcb-backport.git] / libfreerdp-utils / list.c
1 /**
2  * FreeRDP: A Remote Desktop Protocol Client
3  * Double-linked List Utils
4  *
5  * Copyright 2011 Vic Lee
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <freerdp/utils/memory.h>
24 #include <freerdp/utils/list.h>
25
26 static LIST_ITEM* list_item_new(void* data)
27 {
28         LIST_ITEM* item;
29
30         item = xnew(LIST_ITEM);
31         item->data = data;
32         return item;
33 }
34
35 static LIST_ITEM* list_item_find(LIST* list, void* data)
36 {
37         LIST_ITEM* item;
38
39         for (item = list->head; item; item = item->next)
40         {
41                 if (item->data == data)
42                         return item;
43         }
44         return NULL;
45 }
46
47 LIST* list_new(void)
48 {
49         LIST* list;
50
51         list = xnew(LIST);
52         list->count = 0;
53         return list;
54 }
55
56 void list_free(LIST* list)
57 {
58         while (list->head)
59                 list_dequeue(list);
60         xfree(list);
61 }
62
63 void list_enqueue(LIST* list, void* data)
64 {
65         LIST_ITEM* item;
66
67         item = list_item_new(data);
68         if (list->tail == NULL)
69         {
70                 list->head = item;
71                 list->tail = item;
72         }
73         else
74         {
75                 item->prev = list->tail;
76                 list->tail->next = item;
77                 list->tail = item;
78         }
79         list->count++;
80 }
81
82 void* list_dequeue(LIST* list)
83 {
84         LIST_ITEM* item;
85         void* data = NULL;
86
87         item = list->head;
88         if (item != NULL)
89         {
90                 list->head = item->next;
91                 if (list->head == NULL)
92                         list->tail = NULL;
93                 else
94                         list->head->prev = NULL;
95
96                 data = item->data;
97                 xfree(item);
98                 list->count--;
99         }
100         return data;
101 }
102
103 void* list_peek(LIST* list)
104 {
105         LIST_ITEM* item;
106
107         item = list->head;
108         return item ? item->data : NULL;
109 }
110
111 void* list_next(LIST* list, void* data)
112 {
113         LIST_ITEM* item;
114
115         item = list_item_find(list, data);
116         data = NULL;
117         if (item != NULL)
118         {
119                 if (item->next != NULL)
120                         data = item->next->data;
121         }
122         return data;
123 }
124
125 void* list_remove(LIST* list, void* data)
126 {
127         LIST_ITEM* item;
128
129         item = list_item_find(list, data);
130         if (item != NULL)
131         {
132                 if (item->prev != NULL)
133                         item->prev->next = item->next;
134                 if (item->next != NULL)
135                         item->next->prev = item->prev;
136                 if (list->head == item)
137                         list->head = item->next;
138                 if (list->tail == item)
139                         list->tail = item->prev;
140                 xfree(item);
141                 list->count--;
142         }
143         else
144                 data = NULL;
145         return data;
146 }
147
148 int list_size(LIST* list)
149 {
150         return list->count;
151 }