srcs/toolbox/list.c

00001 /* 
00002  * Copyright (c) 2005-2012 by KoanLogic s.r.l. - All rights reserved.  
00003  */
00004 
00005 #include <u/libu_conf.h>
00006 #include <u/libu.h>
00007 #include <toolbox/list.h>
00008 
00009 typedef struct u_list_item_s
00010 {
00011     TAILQ_ENTRY(u_list_item_s) np;
00012     void *ptr;
00013 } u_list_item_t;
00014 
00015 struct u_list_s
00016 {
00017     TAILQ_HEAD(u_list_head_s, u_list_item_s) head;
00018     size_t count;
00019 };
00020 
00047 int u_list_create (u_list_t **plist)
00048 {
00049     u_list_t *list = NULL;
00050 
00051     list = u_zalloc(sizeof(u_list_t));
00052     dbg_err_sif (list == NULL); 
00053 
00054     TAILQ_INIT(&list->head);
00055 
00056     *plist = list;
00057 
00058     return 0;
00059 err:
00060     if(list)
00061         u_free(list);
00062     return ~0;
00063 }
00064 
00075 void u_list_free (u_list_t *list)
00076 {
00077     dbg_return_if(list == NULL, );
00078 
00079     u_list_clear(list);
00080 
00081     u_free(list);
00082 
00083     return;
00084 }
00085 
00097 int u_list_add (u_list_t *list, void *ptr)
00098 {
00099     return u_list_insert(list, ptr, list->count);
00100 }
00101 
00113 int u_list_del (u_list_t *list, void *ptr)
00114 {
00115     u_list_item_t *item = NULL;
00116 
00117     TAILQ_FOREACH(item, &list->head, np)
00118     {
00119         if(item->ptr == ptr)
00120         {
00121             TAILQ_REMOVE(&list->head, item, np);
00122             list->count--;
00123             u_free(item);
00124             return 0; /* removed */
00125         }
00126     }
00127 
00128     return ~0; /* not found */
00129 }
00130 
00141 size_t u_list_count (u_list_t *list)
00142 {
00143     /* a SIGBUS/SIGSEGV is better than returning 0 if list == NULL */
00144     /* NOTE: perhaps we could use ssize_t instead, and return -1 on error */
00145     return list->count;
00146 }
00147 
00159 void *u_list_get_n (u_list_t *list, size_t n)
00160 {
00161     u_list_item_t *item = NULL;
00162 
00163     dbg_return_if (list == NULL, NULL);
00164     dbg_return_if (n > list->count, NULL);
00165 
00166     TAILQ_FOREACH(item, &list->head, np)
00167     {
00168         if(n-- == 0)
00169             return item->ptr;
00170     }
00171 
00172     return NULL;
00173 }
00174 
00188 int u_list_insert (u_list_t *list, void *ptr, size_t n)
00189 {
00190     u_list_item_t *prev, *item = NULL;
00191 
00192     dbg_return_if (list == NULL, ~0);
00193     dbg_return_if (n > list->count, ~0);
00194 
00195     item = u_zalloc(sizeof(u_list_item_t));
00196     dbg_err_sif (item == NULL);
00197 
00198     item->ptr = ptr;
00199             
00200     if(n == 0)
00201     {
00202         TAILQ_INSERT_HEAD(&list->head, item, np);
00203     } else if (n == list->count) {
00204         TAILQ_INSERT_TAIL(&list->head, item, np);
00205     } else {
00206         /* find the current n-th elem */
00207         TAILQ_FOREACH(prev, &list->head, np)
00208         {
00209             if(n-- == 0)
00210                 break;
00211         }
00212 
00213         TAILQ_INSERT_BEFORE(prev, item, np);
00214     }
00215 
00216     list->count++;
00217 
00218     return 0;
00219 err:
00220     if(item)
00221         u_free(item);
00222     return ~0;
00223 }
00224 
00236 void *u_list_first (u_list_t *list, void **it)
00237 {
00238     u_list_item_t *item;
00239 
00240     dbg_return_if (list == NULL, NULL);
00241 
00242     item = TAILQ_FIRST(&list->head);
00243 
00244     if(it && item)
00245         *it = TAILQ_NEXT(item, np);
00246     else if(it)
00247         *it = NULL;
00248 
00249     if(item)
00250         return item->ptr;
00251 
00252     return NULL;
00253 }
00254 
00281 void *u_list_next (u_list_t *list, void **it)
00282 {
00283     u_list_item_t *item;
00284 
00285     dbg_return_if (list == NULL, NULL);
00286     dbg_return_if (it == NULL, NULL);
00287     nop_return_if (*it == NULL, NULL);
00288 
00289     item = *it;
00290 
00291     if(it && item)
00292         *it = TAILQ_NEXT(item, np);
00293     else if(it)
00294         *it = NULL;
00295 
00296     if(item)
00297         return item->ptr;
00298 
00299     return NULL;
00300 }
00301 
00316 int u_list_del_n (u_list_t *list, size_t n, void **pptr)
00317 {
00318     u_list_item_t *item = NULL;
00319 
00320     dbg_return_if (list == NULL, ~0);
00321     dbg_return_if (n >= list->count, ~0);
00322 
00323     TAILQ_FOREACH(item, &list->head, np)
00324     {
00325         if(n-- == 0)
00326             break;
00327     }
00328 
00329     if(pptr)
00330         *pptr = item->ptr;
00331 
00332     TAILQ_REMOVE(&list->head, item, np);
00333 
00334     list->count--;
00335 
00336     u_free(item);
00337 
00338     return 0;
00339 }
00340 
00353 int u_list_clear (u_list_t *list)
00354 {
00355     u_list_item_t *item;
00356 
00357     dbg_err_if(list == NULL);
00358 
00359     while((item = TAILQ_FIRST(&list->head)) != NULL)
00360     {
00361         TAILQ_REMOVE(&list->head, item, np);
00362 
00363         u_free(item);
00364     }
00365 
00366     return 0;
00367 err:
00368     return ~0;
00369 }
00370 

←Products
© 2005-2012 - KoanLogic S.r.l. - All rights reserved