]>
git.proxmox.com Git - mirror_frr.git/blob - pceplib/pcep_utils_double_linked_list.c
2 * This file is part of the PCEPlib, a PCEP protocol library.
4 * Copyright (C) 2020 Volta Networks https://voltanet.io/
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.
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.
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/>.
19 * Author : Brady Johnson <brady@voltanet.io>
30 #include "pcep_utils_double_linked_list.h"
31 #include "pcep_utils_logging.h"
32 #include "pcep_utils_memory.h"
34 double_linked_list
*dll_initialize(void)
36 double_linked_list
*handle
=
37 pceplib_malloc(PCEPLIB_INFRA
, sizeof(double_linked_list
));
39 memset(handle
, 0, sizeof(double_linked_list
));
40 handle
->num_entries
= 0;
45 "%s: dll_initialize cannot allocate memory for handle",
54 void dll_destroy(double_linked_list
*handle
)
58 "%s: dll_destroy cannot destroy NULL handle",
63 double_linked_list_node
*node
= handle
->head
;
64 while (node
!= NULL
) {
65 double_linked_list_node
*node_to_delete
= node
;
66 node
= node
->next_node
;
67 pceplib_free(PCEPLIB_INFRA
, node_to_delete
);
70 pceplib_free(PCEPLIB_INFRA
, handle
);
74 void dll_destroy_with_data_memtype(double_linked_list
*handle
,
75 void *data_memory_type
)
79 "%s: dll_destroy_with_data cannot destroy NULL handle",
84 double_linked_list_node
*node
= handle
->head
;
85 while (node
!= NULL
) {
86 double_linked_list_node
*node_to_delete
= node
;
87 pceplib_free(data_memory_type
, node
->data
);
88 node
= node
->next_node
;
89 pceplib_free(PCEPLIB_INFRA
, node_to_delete
);
92 pceplib_free(PCEPLIB_INFRA
, handle
);
96 void dll_destroy_with_data(double_linked_list
*handle
)
98 /* Default to destroying the data with the INFRA mem type */
99 dll_destroy_with_data_memtype(handle
, PCEPLIB_INFRA
);
103 /* Creates a node and adds it as the first item in the list */
104 double_linked_list_node
*dll_prepend(double_linked_list
*handle
, void *data
)
106 if (handle
== NULL
) {
107 pcep_log(LOG_WARNING
, "%s: dll_prepend_data NULL handle",
112 /* Create the new node */
113 double_linked_list_node
*new_node
=
114 pceplib_malloc(PCEPLIB_INFRA
, sizeof(double_linked_list_node
));
115 memset(new_node
, 0, sizeof(double_linked_list_node
));
116 new_node
->data
= data
;
118 if (handle
->head
== NULL
) {
119 handle
->head
= new_node
;
120 handle
->tail
= new_node
;
122 new_node
->next_node
= handle
->head
;
123 handle
->head
->prev_node
= new_node
;
124 handle
->head
= new_node
;
127 (handle
->num_entries
)++;
133 /* Creates a node and adds it as the last item in the list */
134 double_linked_list_node
*dll_append(double_linked_list
*handle
, void *data
)
136 if (handle
== NULL
) {
137 pcep_log(LOG_WARNING
, "%s: dll_append_data NULL handle",
142 /* Create the new node */
143 double_linked_list_node
*new_node
=
144 pceplib_malloc(PCEPLIB_INFRA
, sizeof(double_linked_list_node
));
145 memset(new_node
, 0, sizeof(double_linked_list_node
));
146 new_node
->data
= data
;
148 if (handle
->head
== NULL
) {
149 handle
->head
= new_node
;
150 handle
->tail
= new_node
;
152 new_node
->prev_node
= handle
->tail
;
153 handle
->tail
->next_node
= new_node
;
154 handle
->tail
= new_node
;
157 (handle
->num_entries
)++;
163 /* Delete the first node in the list, and return the data */
164 void *dll_delete_first_node(double_linked_list
*handle
)
166 if (handle
== NULL
) {
167 pcep_log(LOG_WARNING
, "%s: dll_delete_first_node NULL handle",
172 if (handle
->head
== NULL
) {
176 double_linked_list_node
*delete_node
= handle
->head
;
177 void *data
= delete_node
->data
;
179 if (delete_node
->next_node
== NULL
) {
180 /* Its the last node in the list */
184 handle
->head
= delete_node
->next_node
;
185 handle
->head
->prev_node
= NULL
;
188 pceplib_free(PCEPLIB_INFRA
, delete_node
);
189 (handle
->num_entries
)--;
195 /* Delete the last node in the list, and return the data */
196 void *dll_delete_last_node(double_linked_list
*handle
)
198 if (handle
== NULL
) {
199 pcep_log(LOG_WARNING
, "%s: dll_delete_last_node NULL handle",
204 if (handle
->head
== NULL
) {
208 double_linked_list_node
*delete_node
= handle
->tail
;
209 void *data
= delete_node
->data
;
211 if (delete_node
->prev_node
== NULL
) {
212 /* Its the last node in the list */
216 handle
->tail
= delete_node
->prev_node
;
217 handle
->tail
->next_node
= NULL
;
220 pceplib_free(PCEPLIB_INFRA
, delete_node
);
221 (handle
->num_entries
)--;
227 /* Delete the designated node in the list, and return the data */
228 void *dll_delete_node(double_linked_list
*handle
, double_linked_list_node
*node
)
230 if (handle
== NULL
) {
231 pcep_log(LOG_WARNING
, "%s: dll_delete_node NULL handle",
240 if (handle
->head
== NULL
) {
244 void *data
= node
->data
;
246 if (handle
->head
== handle
->tail
) {
247 /* Its the last node in the list */
250 } else if (handle
->head
== node
) {
251 handle
->head
= node
->next_node
;
252 handle
->head
->prev_node
= NULL
;
253 } else if (handle
->tail
== node
) {
254 handle
->tail
= node
->prev_node
;
255 handle
->tail
->next_node
= NULL
;
257 /* Its somewhere in the middle of the list */
258 node
->next_node
->prev_node
= node
->prev_node
;
259 node
->prev_node
->next_node
= node
->next_node
;
262 pceplib_free(PCEPLIB_INFRA
, node
);
263 (handle
->num_entries
)--;