]> git.proxmox.com Git - mirror_frr.git/blame - pceplib/pcep_utils_double_linked_list.c
Merge pull request #8536 from idryzhov/bfd-enabled
[mirror_frr.git] / pceplib / pcep_utils_double_linked_list.c
CommitLineData
74971473
JG
1/*
2 * This file is part of the PCEPlib, a PCEP protocol library.
3 *
4 * Copyright (C) 2020 Volta Networks https://voltanet.io/
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 *
19 * Author : Brady Johnson <brady@voltanet.io>
20 *
21 */
22
23#include <stddef.h>
24#include <string.h>
25
26#include "pcep_utils_double_linked_list.h"
27#include "pcep_utils_logging.h"
28#include "pcep_utils_memory.h"
29
30double_linked_list *dll_initialize()
31{
32 double_linked_list *handle =
33 pceplib_malloc(PCEPLIB_INFRA, sizeof(double_linked_list));
34 if (handle != NULL) {
35 memset(handle, 0, sizeof(double_linked_list));
36 handle->num_entries = 0;
37 handle->head = NULL;
38 handle->tail = NULL;
39 } else {
40 pcep_log(LOG_WARNING,
41 "%s: dll_initialize cannot allocate memory for handle",
42 __func__);
43 return NULL;
44 }
45
46 return handle;
47}
48
49
50void dll_destroy(double_linked_list *handle)
51{
52 if (handle == NULL) {
53 pcep_log(LOG_WARNING,
54 "%s: dll_destroy cannot destroy NULL handle",
55 __func__);
56 return;
57 }
58
59 double_linked_list_node *node = handle->head;
60 while (node != NULL) {
61 double_linked_list_node *node_to_delete = node;
62 node = node->next_node;
63 pceplib_free(PCEPLIB_INFRA, node_to_delete);
64 }
65
66 pceplib_free(PCEPLIB_INFRA, handle);
67}
68
69
70void dll_destroy_with_data_memtype(double_linked_list *handle,
71 void *data_memory_type)
72{
73 if (handle == NULL) {
74 pcep_log(LOG_WARNING,
75 "%s: dll_destroy_with_data cannot destroy NULL handle",
76 __func__);
77 return;
78 }
79
80 double_linked_list_node *node = handle->head;
81 while (node != NULL) {
82 double_linked_list_node *node_to_delete = node;
83 pceplib_free(data_memory_type, node->data);
84 node = node->next_node;
85 pceplib_free(PCEPLIB_INFRA, node_to_delete);
86 }
87
88 pceplib_free(PCEPLIB_INFRA, handle);
89}
90
91
92void dll_destroy_with_data(double_linked_list *handle)
93{
94 /* Default to destroying the data with the INFRA mem type */
95 dll_destroy_with_data_memtype(handle, PCEPLIB_INFRA);
96}
97
98
99/* Creates a node and adds it as the first item in the list */
100double_linked_list_node *dll_prepend(double_linked_list *handle, void *data)
101{
102 if (handle == NULL) {
103 pcep_log(LOG_WARNING, "%s: dll_prepend_data NULL handle",
104 __func__);
105 return NULL;
106 }
107
108 /* Create the new node */
109 double_linked_list_node *new_node =
110 pceplib_malloc(PCEPLIB_INFRA, sizeof(double_linked_list_node));
111 memset(new_node, 0, sizeof(double_linked_list_node));
112 new_node->data = data;
113
114 if (handle->head == NULL) {
115 handle->head = new_node;
116 handle->tail = new_node;
117 } else {
118 new_node->next_node = handle->head;
119 handle->head->prev_node = new_node;
120 handle->head = new_node;
121 }
122
123 (handle->num_entries)++;
124
125 return new_node;
126}
127
128
129/* Creates a node and adds it as the last item in the list */
130double_linked_list_node *dll_append(double_linked_list *handle, void *data)
131{
132 if (handle == NULL) {
133 pcep_log(LOG_WARNING, "%s: dll_append_data NULL handle",
134 __func__);
135 return NULL;
136 }
137
138 /* Create the new node */
139 double_linked_list_node *new_node =
140 pceplib_malloc(PCEPLIB_INFRA, sizeof(double_linked_list_node));
141 memset(new_node, 0, sizeof(double_linked_list_node));
142 new_node->data = data;
143
144 if (handle->head == NULL) {
145 handle->head = new_node;
146 handle->tail = new_node;
147 } else {
148 new_node->prev_node = handle->tail;
149 handle->tail->next_node = new_node;
150 handle->tail = new_node;
151 }
152
153 (handle->num_entries)++;
154
155 return new_node;
156}
157
158
159/* Delete the first node in the list, and return the data */
160void *dll_delete_first_node(double_linked_list *handle)
161{
162 if (handle == NULL) {
163 pcep_log(LOG_WARNING, "%s: dll_delete_first_node NULL handle",
164 __func__);
165 return NULL;
166 }
167
168 if (handle->head == NULL) {
169 return NULL;
170 }
171
172 double_linked_list_node *delete_node = handle->head;
173 void *data = delete_node->data;
174
175 if (delete_node->next_node == NULL) {
176 /* Its the last node in the list */
177 handle->head = NULL;
178 handle->tail = NULL;
179 } else {
180 handle->head = delete_node->next_node;
181 handle->head->prev_node = NULL;
182 }
183
184 pceplib_free(PCEPLIB_INFRA, delete_node);
185 (handle->num_entries)--;
186
187 return data;
188}
189
190
191/* Delete the last node in the list, and return the data */
192void *dll_delete_last_node(double_linked_list *handle)
193{
194 if (handle == NULL) {
195 pcep_log(LOG_WARNING, "%s: dll_delete_last_node NULL handle",
196 __func__);
197 return NULL;
198 }
199
200 if (handle->head == NULL) {
201 return NULL;
202 }
203
204 double_linked_list_node *delete_node = handle->tail;
205 void *data = delete_node->data;
206
207 if (delete_node->prev_node == NULL) {
208 /* Its the last node in the list */
209 handle->head = NULL;
210 handle->tail = NULL;
211 } else {
212 handle->tail = delete_node->prev_node;
213 handle->tail->next_node = NULL;
214 }
215
216 pceplib_free(PCEPLIB_INFRA, delete_node);
217 (handle->num_entries)--;
218
219 return data;
220}
221
222
223/* Delete the designated node in the list, and return the data */
224void *dll_delete_node(double_linked_list *handle, double_linked_list_node *node)
225{
226 if (handle == NULL) {
227 pcep_log(LOG_WARNING, "%s: dll_delete_node NULL handle",
228 __func__);
229 return NULL;
230 }
231
232 if (node == NULL) {
233 return NULL;
234 }
235
236 if (handle->head == NULL) {
237 return NULL;
238 }
239
240 void *data = node->data;
241
242 if (handle->head == handle->tail) {
243 /* Its the last node in the list */
244 handle->head = NULL;
245 handle->tail = NULL;
246 } else if (handle->head == node) {
247 handle->head = node->next_node;
248 handle->head->prev_node = NULL;
249 } else if (handle->tail == node) {
250 handle->tail = node->prev_node;
251 handle->tail->next_node = NULL;
252 } else {
253 /* Its somewhere in the middle of the list */
254 node->next_node->prev_node = node->prev_node;
255 node->prev_node->next_node = node->next_node;
256 }
257
258 pceplib_free(PCEPLIB_INFRA, node);
259 (handle->num_entries)--;
260
261 return data;
262}