1 /*
2     QUEUE
3 
4     Implementation of the queue on top of collection library interface.
5 
6     Copyright (C) Dmitri Pal <dpal@redhat.com> 2009
7 
8     Collection Library is free software: you can redistribute it and/or modify
9     it under the terms of the GNU Lesser General Public License as published by
10     the Free Software Foundation, either version 3 of the License, or
11     (at your option) any later version.
12 
13     Collection Library is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16     GNU Lesser General Public License for more details.
17 
18     You should have received a copy of the GNU Lesser General Public License
19     along with Collection Library.  If not, see <http://www.gnu.org/licenses/>.
20 */
21 
22 #include "config.h"
23 #include <stdlib.h>
24 #include <errno.h>
25 #include "collection_queue.h"
26 #include "trace.h"
27 
28 /* Function that creates a queue object */
col_create_queue(struct collection_item ** queue)29 int col_create_queue(struct collection_item **queue)
30 {
31     int error = EOK;
32 
33     TRACE_FLOW_STRING("col_create_queue", "Entry point.");
34 
35     error = col_create_collection(queue, COL_NAME_QUEUE, COL_CLASS_QUEUE);
36 
37     TRACE_FLOW_STRING("col_create_queue", "Exit.");
38     return error;
39 }
40 
41 /* Function that destroys a queue object */
col_destroy_queue(struct collection_item * queue)42 void col_destroy_queue(struct collection_item *queue)
43 {
44     TRACE_FLOW_STRING("col_destroy_queue", "Entry point.");
45 
46     col_destroy_collection(queue);
47 
48     TRACE_FLOW_STRING("col_destroy_queue", "Exit");
49 }
50 
51 
52 /* Put a string property into a queue.  */
col_enqueue_str_property(struct collection_item * queue,const char * property,const char * string,int length)53 int col_enqueue_str_property(struct collection_item *queue,
54                              const char *property,
55                              const char *string,
56                              int length)
57 {
58     int error = EOK;
59 
60     TRACE_FLOW_STRING("col_enqueue_str_property", "Entry point.");
61 
62     /* Check that queue is not empty */
63     if (queue == NULL) {
64         TRACE_ERROR_STRING("queue can't be NULL", "");
65         return EINVAL;
66     }
67 
68     /* Make sure it is a queue */
69     if (!col_is_of_class(queue, COL_CLASS_QUEUE)) {
70         TRACE_ERROR_STRING("Wrong class", "");
71         return EINVAL;
72     }
73 
74     error = col_add_str_property(queue, NULL, property, string, length);
75 
76     TRACE_FLOW_STRING("col_enqueue_str_property", "Exit.");
77     return error;
78 }
79 
80 /* Put a binary property into a queue.  */
col_enqueue_binary_property(struct collection_item * queue,const char * property,void * binary_data,int length)81 int col_enqueue_binary_property(struct collection_item *queue,
82                                 const char *property,
83                                 void *binary_data,
84                                 int length)
85 {
86     int error = EOK;
87 
88     TRACE_FLOW_STRING("col_enqueue_binary_property", "Entry point.");
89 
90     /* Check that queue is not empty */
91     if (queue == NULL) {
92         TRACE_ERROR_STRING("queue can't be NULL", "");
93         return EINVAL;
94     }
95 
96     /* Make sure it is a queue */
97     if (!col_is_of_class(queue, COL_CLASS_QUEUE)) {
98         TRACE_ERROR_STRING("Wrong class", "");
99         return EINVAL;
100     }
101 
102     error = col_add_binary_property(queue, NULL, property, binary_data, length);
103 
104     TRACE_FLOW_STRING("col_enqueue_binary_property", "Exit.");
105     return error;
106 }
107 
108 
109 /* Put an int property into a queue. */
col_enqueue_int_property(struct collection_item * queue,const char * property,int32_t number)110 int col_enqueue_int_property(struct collection_item *queue,
111                              const char *property,
112                              int32_t number)
113 {
114     int error = EOK;
115 
116     TRACE_FLOW_STRING("col_enqueue_int_property", "Entry point.");
117 
118     /* Check that queue is not empty */
119     if (queue == NULL) {
120         TRACE_ERROR_STRING("queue can't be NULL", "");
121         return EINVAL;
122     }
123 
124     /* Make sure it is a queue */
125     if (!col_is_of_class(queue, COL_CLASS_QUEUE)) {
126         TRACE_ERROR_STRING("Wrong class", "");
127         return EINVAL;
128     }
129 
130     error = col_add_int_property(queue, NULL, property, number);
131 
132     TRACE_FLOW_STRING("col_enqueue_int_property", "Exit.");
133     return error;
134 }
135 
136 /* Put an unsigned int property into a queue. */
col_enqueue_unsigned_property(struct collection_item * queue,const char * property,uint32_t number)137 int col_enqueue_unsigned_property(struct collection_item *queue,
138                                   const char *property,
139                                   uint32_t number)
140 {
141     int error = EOK;
142 
143     TRACE_FLOW_STRING("col_enqueue_unsigned_property", "Entry point.");
144 
145     /* Check that queue is not empty */
146     if (queue == NULL) {
147         TRACE_ERROR_STRING("queue can't be NULL", "");
148         return EINVAL;
149     }
150 
151     /* Make sure it is a queue */
152     if (!col_is_of_class(queue, COL_CLASS_QUEUE)) {
153         TRACE_ERROR_STRING("Wrong class", "");
154         return EINVAL;
155     }
156 
157     error = col_add_unsigned_property(queue, NULL, property, number);
158 
159     TRACE_FLOW_STRING("col_enqueue_unsigned_property", "Exit.");
160     return error;
161 }
162 
163 
164 /* Put a long property. */
col_enqueue_long_property(struct collection_item * queue,const char * property,int64_t number)165 int col_enqueue_long_property(struct collection_item *queue,
166                               const char *property,
167                               int64_t number)
168 {
169     int error = EOK;
170 
171     TRACE_FLOW_STRING("col_enqueue_long_property", "Entry point.");
172 
173     /* Check that queue is not empty */
174     if (queue == NULL) {
175         TRACE_ERROR_STRING("queue can't be NULL", "");
176         return EINVAL;
177     }
178 
179     /* Make sure it is a queue */
180     if (!col_is_of_class(queue, COL_CLASS_QUEUE)) {
181         TRACE_ERROR_STRING("Wrong class", "");
182         return EINVAL;
183     }
184 
185     error = col_add_long_property(queue, NULL, property, number);
186 
187     TRACE_FLOW_STRING("col_enqueue_long_property", "Exit.");
188     return error;
189 }
190 
191 /* Put an unsigned long property. */
col_enqueue_ulong_property(struct collection_item * queue,const char * property,uint64_t number)192 int col_enqueue_ulong_property(struct collection_item *queue,
193                                const char *property,
194                                uint64_t number)
195 {
196     int error = EOK;
197 
198     TRACE_FLOW_STRING("col_enqueue_ulong_property", "Entry point.");
199 
200     /* Check that queue is not empty */
201     if (queue == NULL) {
202         TRACE_ERROR_STRING("queue can't be NULL", "");
203         return EINVAL;
204     }
205 
206     /* Make sure it is a queue */
207     if (!col_is_of_class(queue, COL_CLASS_QUEUE)) {
208         TRACE_ERROR_STRING("Wrong class", "");
209         return EINVAL;
210     }
211 
212     error = col_add_ulong_property(queue, NULL, property, number);
213 
214     TRACE_FLOW_STRING("col_enqueue_ulong_property", "Exit.");
215     return error;
216 }
217 
218 /* Put a double property. */
col_enqueue_double_property(struct collection_item * queue,const char * property,double number)219 int col_enqueue_double_property(struct collection_item *queue,
220                                 const char *property,
221                                 double number)
222 {
223     int error = EOK;
224 
225     TRACE_FLOW_STRING("col_enqueue_double_property", "Entry point.");
226 
227     /* Check that queue is not empty */
228     if (queue == NULL) {
229         TRACE_ERROR_STRING("queue can't be NULL", "");
230         return EINVAL;
231     }
232 
233     /* Make sure it is a queue */
234     if (!col_is_of_class(queue, COL_CLASS_QUEUE)) {
235         TRACE_ERROR_STRING("Wrong class", "");
236         return EINVAL;
237     }
238 
239     error = col_add_double_property(queue, NULL, property, number);
240 
241     TRACE_FLOW_STRING("enqueue_double_property", "Exit.");
242     return error;
243 }
244 
245 /* Put a bool property. */
col_enqueue_bool_property(struct collection_item * queue,const char * property,unsigned char logical)246 int col_enqueue_bool_property(struct collection_item *queue,
247                               const char *property,
248                               unsigned char logical)
249 {
250     int error = EOK;
251 
252     TRACE_FLOW_STRING("col_enqueue_bool_property", "Entry point.");
253 
254     /* Check that queue is not empty */
255     if (queue == NULL) {
256         TRACE_ERROR_STRING("queue can't be NULL", "");
257         return EINVAL;
258     }
259 
260     /* Make sure it is a queue */
261     if (!col_is_of_class(queue, COL_CLASS_QUEUE)) {
262         TRACE_ERROR_STRING("Wrong class", "");
263         return EINVAL;
264     }
265 
266     error = col_add_bool_property(queue, NULL, property, logical);
267 
268     TRACE_FLOW_STRING("col_enqueue_bool_property", "Exit.");
269     return error;
270 }
271 
272 /* Put any property */
col_enqueue_any_property(struct collection_item * queue,const char * property,int type,void * data,int length)273 int col_enqueue_any_property(struct collection_item *queue,
274                              const char *property,
275                              int type,
276                              void *data,
277                              int length)
278 {
279     int error = EOK;
280 
281     TRACE_FLOW_STRING("col_enqueue_any_property", "Entry point.");
282 
283     /* Check that queue is not empty */
284     if (queue == NULL) {
285         TRACE_ERROR_STRING("queue can't be NULL", "");
286         return EINVAL;
287     }
288 
289     /* Make sure it is a queue */
290     if (!col_is_of_class(queue, COL_CLASS_QUEUE)) {
291         TRACE_ERROR_STRING("Wrong class", "");
292         return EINVAL;
293     }
294 
295     error = col_add_any_property(queue, NULL, property, type, data, length);
296 
297     TRACE_FLOW_STRING("col_enqueue_any_property", "Exit.");
298     return error;
299 }
300 
301 /* Enqueue item */
col_enqueue_item(struct collection_item * queue,struct collection_item * item)302 int col_enqueue_item(struct collection_item *queue,
303                      struct collection_item *item)
304 {
305     int error = EOK;
306 
307     TRACE_FLOW_STRING("col_enqueue_item", "Entry point.");
308 
309     /* Check that queue is not empty */
310     if (queue == NULL) {
311         TRACE_ERROR_STRING("queue can't be NULL", "");
312         return EINVAL;
313     }
314 
315     /* Make sure it is a queue */
316     if (!col_is_of_class(queue, COL_CLASS_QUEUE)) {
317         TRACE_ERROR_STRING("Wrong class", "");
318         return EINVAL;
319     }
320 
321     error = col_insert_item_into_current(queue,
322                                          item,
323                                          COL_DSP_END,
324                                          NULL,
325                                          0,
326                                          COL_INSERT_NOCHECK);
327 
328     TRACE_FLOW_STRING("col_enqueue_item", "Exit.");
329     return error;
330 }
331 
332 /* Dequeue item */
col_dequeue_item(struct collection_item * queue,struct collection_item ** item)333 int col_dequeue_item(struct collection_item *queue,
334                      struct collection_item **item)
335 {
336     int error = EOK;
337 
338     TRACE_FLOW_STRING("col_dequeue_item", "Entry point.");
339 
340     /* Check that queue is not empty */
341     if (queue == NULL) {
342         TRACE_ERROR_STRING("queue can't be NULL", "");
343         return EINVAL;
344     }
345 
346     /* Make sure it is a queue */
347     if (!col_is_of_class(queue, COL_CLASS_QUEUE)) {
348         TRACE_ERROR_STRING("Wrong class", "");
349         return EINVAL;
350     }
351 
352     error = col_extract_item_from_current(queue,
353                                           COL_DSP_FRONT,
354                                           NULL,
355                                           0,
356                                           0,
357                                           item);
358 
359     TRACE_FLOW_STRING("col_dequeue_item", "Exit.");
360     return error;
361 }
362