Flowgrind
Advanced TCP traffic generator
fg_list.c
Go to the documentation of this file.
1 
6 /*
7  * Copyright (C) 2014 Marcel Nehring <marcel.nehring@rwth-aachen.de>
8  *
9  * This file is part of Flowgrind.
10  *
11  * Flowgrind is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation, either version 3 of the License, or
14  * (at your option) any later version.
15  *
16  * Flowgrind is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with Flowgrind. If not, see <http://www.gnu.org/licenses/>.
23  *
24  */
25 
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif /* HAVE_CONFIG_H */
29 
30 #include <stdlib.h>
31 
32 #include "fg_list.h"
33 
34 int fg_list_init(struct linked_list * const list)
35 {
36  if (!list)
37  return -1;
38  if (list->head)
39  if (!fg_list_clear(list))
40  return -2;
41 
42  list->head = NULL;
43  list->tail = NULL;
44  list->size = 0;
45 
46  return 0;
47 }
48 
49 const struct list_node* fg_list_front(struct linked_list * const list)
50 {
51  if (!list)
52  return NULL;
53 
54  return list->head;
55 }
56 
57 const struct list_node* fg_list_back(struct linked_list * const list)
58 {
59  if (!list)
60  return NULL;
61 
62  return list->tail;
63 }
64 
65 int fg_list_remove(struct linked_list * const list, const void * const data)
66 {
67  if (!list)
68  return -1;
69  if (!list->head)
70  return -3;
71 
72  struct list_node *node = list->head;
73 
74  while (node->data != data) {
75  node = node->next;
76  if (!node)
77  return -4;
78  }
79 
80  if (list->head == node)
81  list->head = node->next;
82  if (list->tail == node)
83  list->tail = node->previous;
84  if (node->previous)
85  node->previous->next = node->next;
86  if (node->next)
87  node->next->previous = node->previous;
88 
89  free(node);
90  --list->size;
91 
92  return 0;
93 }
94 
107 static struct list_node* create_node(void * const data,
108  struct list_node * const previous,
109  struct list_node * const next)
110 {
111  struct list_node *new_node = (struct list_node*)malloc(sizeof(struct list_node));
112 
113  if (!new_node)
114  return NULL;
115 
116  new_node->data = data;
117  new_node->previous = previous;
118  new_node->next = next;
119 
120  return new_node;
121 }
122 
123 int fg_list_push_front(struct linked_list * const list, void * const data)
124 {
125  if (!list)
126  return -1;
127 
128  struct list_node *new_node = create_node(data, NULL, list->head);
129 
130  if (!new_node)
131  return -5;
132 
133  if (!list->head)
134  list->tail = new_node;
135  else
136  list->head->previous = new_node;
137 
138  list->head = new_node;
139  ++list->size;
140 
141  return 0;
142 }
143 
144 void* fg_list_pop_front(struct linked_list * const list)
145 {
146  if (!list)
147  return NULL;
148  if (!list->head)
149  return NULL;
150 
151  struct list_node *head = list->head;
152 
153  if (list->head == list->tail)
154  list->tail = NULL;
155  if (head->next)
156  head->next->previous = NULL;
157 
158  list->head = head->next;
159  void *data = head->data;
160 
161  free(head);
162  --list->size;
163 
164  return data;
165 }
166 
167 int fg_list_push_back(struct linked_list * const list, void * const data)
168 {
169  if (!list)
170  return -1;
171 
172  struct list_node *new_node = create_node(data, list->tail, NULL);
173 
174  if (!new_node)
175  return -5;
176 
177  if (!list->head)
178  list->head = new_node;
179  if (list->tail)
180  list->tail->next = new_node;
181 
182  list->tail = new_node;
183  ++list->size;
184 
185  return 0;
186 }
187 
188 void* fg_list_pop_back(struct linked_list * const list)
189 {
190  if (!list)
191  return NULL;
192  if (!list->tail)
193  return NULL;
194 
195  struct list_node *tail = list->tail;
196  void *data = tail->data;
197 
198  if (tail->previous)
199  tail->previous->next = NULL;
200  if (list->tail == list->head)
201  list->head = NULL;
202 
203  list->tail = tail->previous;
204 
205  free(tail);
206  --list->size;
207 
208  return data;
209 }
210 
211 size_t fg_list_size(struct linked_list * const list)
212 {
213  if (!list)
214  return -1;
215 
216  return list->size;
217 }
218 
219 int fg_list_clear(struct linked_list * const list)
220 {
221  if (!list)
222  return -1;
223 
224  while (fg_list_size(list)) {
225  void * data = fg_list_pop_front(list);
226  free(data);
227  }
228 
229  return 0;
230 }
fg_list_size
size_t fg_list_size(struct linked_list *const list)
Returns the number of elements in the list.
Definition: fg_list.c:211
create_node
static struct list_node * create_node(void *const data, struct list_node *const previous, struct list_node *const next)
Creates a new list element on the heap.
Definition: fg_list.c:107
fg_list_remove
int fg_list_remove(struct linked_list *const list, const void *const data)
Removes from the list the first element whose data points to data.
Definition: fg_list.c:65
list_node::data
void * data
Pointer to user defined data stored with this node.
Definition: fg_list.h:38
fg_list_clear
int fg_list_clear(struct linked_list *const list)
Removes and destroys all elements from the list, leaving it with a size of 0.
Definition: fg_list.c:219
list_node::previous
struct list_node * previous
Pointer to the next node in the list.
Definition: fg_list.h:42
linked_list::head
struct list_node * head
Pointer to the first element in the list.
Definition: fg_list.h:48
fg_list.h
Generic doubly linked list implementation.
linked_list::size
size_t size
Size of the list i.e.
Definition: fg_list.h:52
fg_list_push_back
int fg_list_push_back(struct linked_list *const list, void *const data)
Inserts a new element at the end of the list.
Definition: fg_list.c:167
fg_list_pop_front
void * fg_list_pop_front(struct linked_list *const list)
Removes the first element in the list, effectively reducing its size by one.
Definition: fg_list.c:144
linked_list::tail
struct list_node * tail
Pointer to the last element in the list.
Definition: fg_list.h:50
list_node
Single element in a doubly linked list.
Definition: fg_list.h:36
linked_list
A doubly linked list.
Definition: fg_list.h:46
config.h
list_node::next
struct list_node * next
Pointer to the previous node in the list.
Definition: fg_list.h:40
fg_list_back
const struct list_node * fg_list_back(struct linked_list *const list)
Returns the last element of the list.
Definition: fg_list.c:57
fg_list_push_front
int fg_list_push_front(struct linked_list *const list, void *const data)
Inserts a new element at the beginning of the list.
Definition: fg_list.c:123
fg_list_init
int fg_list_init(struct linked_list *const list)
Initializes the list by setting its head and tail to NULL and its size to 0.
Definition: fg_list.c:34
fg_list_front
const struct list_node * fg_list_front(struct linked_list *const list)
Returns the first element of the list.
Definition: fg_list.c:49
fg_list_pop_back
void * fg_list_pop_back(struct linked_list *const list)
Removes the last element in the list, effectively reducing its size by one.
Definition: fg_list.c:188