blob: 272079c0debee58807d3df5d0d44bab1c8a1eb67 [file] [log] [blame]
SE Android8c48de12012-01-24 05:27:18 -08001
2/* Author : Stephen Smalley, <sds@epoch.ncsc.mil> */
3
4/* FLASK */
5
6/*
7 * Implementation of the double-ended queue type.
8 */
9
10#include <stdlib.h>
11#include "queue.h"
12
13queue_t queue_create(void)
14{
15 queue_t q;
16
17 q = (queue_t) malloc(sizeof(struct queue_info));
18 if (q == NULL)
19 return NULL;
20
21 q->head = q->tail = NULL;
22
23 return q;
24}
25
26int queue_insert(queue_t q, queue_element_t e)
27{
28 queue_node_ptr_t newnode;
29
30 if (!q)
31 return -1;
32
33 newnode = (queue_node_ptr_t) malloc(sizeof(struct queue_node));
34 if (newnode == NULL)
35 return -1;
36
37 newnode->element = e;
38 newnode->next = NULL;
39
40 if (q->head == NULL) {
41 q->head = q->tail = newnode;
42 } else {
43 q->tail->next = newnode;
44 q->tail = newnode;
45 }
46
47 return 0;
48}
49
50int queue_push(queue_t q, queue_element_t e)
51{
52 queue_node_ptr_t newnode;
53
54 if (!q)
55 return -1;
56
57 newnode = (queue_node_ptr_t) malloc(sizeof(struct queue_node));
58 if (newnode == NULL)
59 return -1;
60
61 newnode->element = e;
62 newnode->next = NULL;
63
64 if (q->head == NULL) {
65 q->head = q->tail = newnode;
66 } else {
67 newnode->next = q->head;
68 q->head = newnode;
69 }
70
71 return 0;
72}
73
74queue_element_t queue_remove(queue_t q)
75{
76 queue_node_ptr_t node;
77 queue_element_t e;
78
79 if (!q)
80 return NULL;
81
82 if (q->head == NULL)
83 return NULL;
84
85 node = q->head;
86 q->head = q->head->next;
87 if (q->head == NULL)
88 q->tail = NULL;
89
90 e = node->element;
91 free(node);
92
93 return e;
94}
95
96queue_element_t queue_head(queue_t q)
97{
98 if (!q)
99 return NULL;
100
101 if (q->head == NULL)
102 return NULL;
103
104 return q->head->element;
105}
106
107void queue_destroy(queue_t q)
108{
109 queue_node_ptr_t p, temp;
110
111 if (!q)
112 return;
113
114 p = q->head;
115 while (p != NULL) {
116 temp = p;
117 p = p->next;
118 free(temp);
119 }
120
121 free(q);
122}
123
124int queue_map(queue_t q, int (*f) (queue_element_t, void *), void *vp)
125{
126 queue_node_ptr_t p;
127 int ret;
128
129 if (!q)
130 return 0;
131
132 p = q->head;
133 while (p != NULL) {
134 ret = f(p->element, vp);
135 if (ret)
136 return ret;
137 p = p->next;
138 }
139 return 0;
140}
141
142void queue_map_remove_on_error(queue_t q,
143 int (*f) (queue_element_t, void *),
144 void (*g) (queue_element_t, void *), void *vp)
145{
146 queue_node_ptr_t p, last, temp;
147 int ret;
148
149 if (!q)
150 return;
151
152 last = NULL;
153 p = q->head;
154 while (p != NULL) {
155 ret = f(p->element, vp);
156 if (ret) {
157 if (last) {
158 last->next = p->next;
159 if (last->next == NULL)
160 q->tail = last;
161 } else {
162 q->head = p->next;
163 if (q->head == NULL)
164 q->tail = NULL;
165 }
166
167 temp = p;
168 p = p->next;
169 g(temp->element, vp);
170 free(temp);
171 } else {
172 last = p;
173 p = p->next;
174 }
175 }
176
177 return;
178}
179
180/* FLASK */