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