mem: add memends_str() helper for symmetry
[ccan] / junkcode / dongre.avinash@gmail.com-clibutils / src / c_slist.c
1 /** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **\r
2  *  This file is part of clib library\r
3  *  Copyright (C) 2011 Avinash Dongre ( dongre.avinash@gmail.com )\r
4  *\r
5  *  Permission is hereby granted, free of charge, to any person obtaining a copy\r
6  *  of this software and associated documentation files (the "Software"), to deal\r
7  *  in the Software without restriction, including without limitation the rights\r
8  *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
9  *  copies of the Software, and to permit persons to whom the Software is\r
10  *  furnished to do so, subject to the following conditions:\r
11  * \r
12  *  The above copyright notice and this permission notice shall be included in\r
13  *  all copies or substantial portions of the Software.\r
14  * \r
15  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
16  *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
17  *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
18  *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
19  *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
20  *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
21  *  THE SOFTWARE.\r
22  ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **/\r
23 \r
24 #include "c_lib.h"\r
25 \r
26 struct clib_slist* \r
27 new_clib_slist(clib_destroy fn_d, clib_compare fn_c){\r
28     struct clib_slist *pSlist  = (struct clib_slist*)malloc(sizeof(struct clib_slist));\r
29     pSlist->head           = (struct clib_slist_node*)0;\r
30     pSlist->destruct_fn    = fn_d;\r
31     pSlist->compare_fn = fn_c;\r
32     pSlist->size           = 0;\r
33     return pSlist;\r
34 }\r
35 void           \r
36 delete_clib_slist( struct clib_slist *pSlist){\r
37     while(pSlist->size != 0) {\r
38         remove_clib_slist ( pSlist, 0 );\r
39     }\r
40     free ( pSlist );\r
41 }\r
42 \r
43 clib_error           \r
44 push_back_clib_slist( struct clib_slist *pSlist, void *elem, size_t elem_size){\r
45 \r
46     struct clib_slist_node* current  = (struct clib_slist_node*)0;\r
47     struct clib_slist_node* new_node = (struct clib_slist_node*)0;\r
48 \r
49     new_node = (struct clib_slist_node*)malloc(sizeof(struct clib_slist_node));\r
50 \r
51     new_node->elem = new_clib_object ( elem, elem_size );\r
52     if ( ! new_node->elem )\r
53         return CLIB_SLIST_INSERT_FAILED;\r
54     new_node->next = (struct clib_slist_node*)0;\r
55 \r
56     if ( pSlist->head == (struct clib_slist_node*)0 ) {\r
57         pSlist->head = new_node;\r
58         pSlist->size++;\r
59         return CLIB_ERROR_SUCCESS;\r
60     }\r
61     current = pSlist->head;\r
62     while ( current->next != (struct clib_slist_node*)0 )\r
63         current  = current->next;    \r
64     current->next = new_node;\r
65     pSlist->size++;\r
66 \r
67     return CLIB_ERROR_SUCCESS;\r
68 }\r
69 static void \r
70 pvt_remove_clib_list ( struct clib_slist *pSlist, struct clib_slist_node* pSlistNode ) {\r
71     void *elem;\r
72     get_raw_clib_object(pSlistNode->elem, &elem);\r
73     if ( pSlist->destruct_fn) {             \r
74         (pSlist->destruct_fn)(elem);\r
75         delete_clib_object ( pSlistNode->elem );\r
76     }else {\r
77         free ( elem );\r
78         delete_clib_object ( pSlistNode->elem );\r
79     }        \r
80     free ( pSlistNode);\r
81 }\r
82 void           \r
83 remove_clib_slist( struct clib_slist *pSlist, int pos ) {\r
84     int i = 0;\r
85 \r
86     struct clib_slist_node* current = pSlist->head;\r
87     struct clib_slist_node* temp    = (struct clib_slist_node*)0;\r
88 \r
89     if ( pos > pSlist->size ) return;\r
90 \r
91     if ( pos == 0 ) {                \r
92         pSlist->head = current->next;    \r
93         pvt_remove_clib_list(pSlist, current);    \r
94         pSlist->size--;\r
95         return;\r
96     }\r
97     for ( i = 1; i < pos - 1; i++)\r
98         current = current->next;\r
99 \r
100     temp          = current->next;\r
101     current->next = current->next->next;\r
102     pvt_remove_clib_list ( pSlist, temp );\r
103 \r
104     pSlist->size--;\r
105 }\r
106 clib_error           \r
107 insert_clib_slist(struct clib_slist *pSlist, int pos, void *elem, size_t elem_size) {\r
108     int i = 0;\r
109     struct clib_slist_node* current  = pSlist->head;\r
110     struct clib_slist_node* new_node = (struct clib_slist_node*)0;\r
111    \r
112     if ( pos == 1 ) {\r
113         new_node       = (struct clib_slist_node*)malloc(sizeof(struct clib_slist_node));\r
114         new_node->elem = new_clib_object ( elem, elem_size );\r
115         if ( ! new_node->elem ) {\r
116             free ( new_node );\r
117             return CLIB_SLIST_INSERT_FAILED;\r
118         }\r
119         new_node->next = pSlist->head;\r
120         pSlist->head       = new_node;\r
121         pSlist->size++;\r
122         return CLIB_ERROR_SUCCESS;\r
123     }\r
124 \r
125     if ( pos >= pSlist->size + 1 ) {\r
126         return push_back_clib_slist ( pSlist, elem, elem_size );\r
127     }\r
128 \r
129     for ( i = 1; i < pos - 1; i++) {\r
130         current = current->next;\r
131     }\r
132     new_node       = (struct clib_slist_node*)malloc(sizeof(struct clib_slist_node));\r
133     new_node->elem = new_clib_object ( elem, elem_size );\r
134     if ( ! new_node->elem ) {\r
135         free ( new_node );\r
136         return CLIB_SLIST_INSERT_FAILED;\r
137     }\r
138 \r
139     new_node->next = current->next;\r
140     current->next  = new_node;\r
141     pSlist->size++;\r
142 \r
143     return CLIB_ERROR_SUCCESS;\r
144 }\r
145 void           \r
146 for_each_clib_slist (struct clib_slist *pSlist, void (*fn)(void* )) {\r
147     void *elem;\r
148     struct clib_slist_node* current  = pSlist->head;\r
149     while ( current != (struct clib_slist_node*)0 ) {\r
150         get_raw_clib_object(current->elem, &elem);\r
151         (fn)(elem);\r
152         free ( elem );\r
153         current = current->next;\r
154     }    \r
155 }\r
156 clib_bool\r
157 find_clib_slist (struct clib_slist *pSlist, void* find_value, void**out_value) {\r
158     struct clib_slist_node* current  = pSlist->head;  \r
159     while ( current != (struct clib_slist_node*)0 ) {        \r
160         get_raw_clib_object(current->elem, out_value);\r
161         if ((pSlist->compare_fn)(find_value,*out_value) != 0){\r
162             break;\r
163         }\r
164         free ( *out_value );\r
165         current = current->next;\r
166     }\r
167     if ( current ) {\r
168         return clib_true;\r
169     }\r
170     return clib_false;\r
171 }\r
172 \r
173 \r