mem: add memends_str() helper for symmetry
[ccan] / junkcode / dongre.avinash@gmail.com-clibutils / src / c_array.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 #include <string.h>\r
26 #include <stdio.h>\r
27 \r
28 \r
29 static struct clib_array* \r
30 array_check_and_grow ( struct clib_array* pArray) {\r
31     if ( pArray->no_of_elements >= pArray->no_max_elements ) {\r
32         pArray->no_max_elements  = 2 * pArray->no_max_elements;\r
33         pArray->pElements        = (struct clib_object**) realloc ( pArray->pElements, \r
34                                       pArray->no_max_elements * sizeof ( struct clib_object*));\r
35     }\r
36     return pArray;\r
37 }\r
38 \r
39 struct clib_array* \r
40 new_clib_array(int array_size, clib_compare fn_c, clib_destroy fn_d) {\r
41 \r
42     struct clib_array* pArray = (struct clib_array*)malloc(sizeof(struct clib_array));\r
43     if ( ! pArray )\r
44         return (struct clib_array*)0;\r
45 \r
46     pArray->no_max_elements = array_size < 8 ? 8 : array_size;\r
47     pArray->pElements = (struct clib_object**) malloc(pArray->no_max_elements * sizeof(struct clib_object*));\r
48     if ( ! pArray->pElements ){\r
49         free ( pArray );\r
50         return (struct clib_array*)0;\r
51     }\r
52     pArray->compare_fn      = fn_c;\r
53     pArray->destruct_fn     = fn_d;\r
54     pArray->no_of_elements  = 0;\r
55 \r
56     return pArray;\r
57 }\r
58 \r
59 static clib_error \r
60 insert_clib_array ( struct clib_array* pArray, int index, void *elem, size_t elem_size) {\r
61 \r
62     clib_error rc           = CLIB_ERROR_SUCCESS;\r
63     struct clib_object* pObject = new_clib_object ( elem, elem_size );\r
64     if ( ! pObject )\r
65         return CLIB_ARRAY_INSERT_FAILED;\r
66 \r
67     pArray->pElements[index] = pObject;\r
68     pArray->no_of_elements++;\r
69     return rc;\r
70 }\r
71 \r
72 clib_error \r
73 push_back_clib_array (struct clib_array* pArray, void *elem, size_t elem_size) {\r
74     clib_error rc = CLIB_ERROR_SUCCESS; \r
75 \r
76     if ( ! pArray)\r
77         return CLIB_ARRAY_NOT_INITIALIZED;\r
78 \r
79     array_check_and_grow ( pArray);\r
80 \r
81     rc = insert_clib_array( pArray, pArray->no_of_elements, elem, elem_size);\r
82 \r
83     return rc;\r
84 }\r
85 \r
86 clib_error \r
87 element_at_clib_array (struct clib_array* pArray, int index, void** elem) {\r
88     clib_error rc = CLIB_ERROR_SUCCESS;\r
89 \r
90     if ( ! pArray )\r
91         return CLIB_ARRAY_NOT_INITIALIZED;\r
92 \r
93         if ( index < 0 || index >= pArray->no_of_elements )\r
94         return CLIB_ARRAY_INDEX_OUT_OF_BOUND;\r
95 \r
96     get_raw_clib_object ( pArray->pElements[index], elem );\r
97     return rc;\r
98 }\r
99 \r
100 int\r
101 size_clib_array ( struct clib_array* pArray ) {\r
102         if ( pArray == (struct clib_array*)0 )\r
103                 return 0;\r
104         return pArray->no_of_elements;\r
105 }\r
106 \r
107 int\r
108 capacity_clib_array ( struct clib_array* pArray ) {\r
109         if ( pArray == (struct clib_array*)0 )\r
110                 return 0;\r
111         return pArray->no_max_elements;\r
112 }\r
113 \r
114 clib_bool  \r
115 empty_clib_array ( struct clib_array* pArray) {\r
116         if ( pArray == (struct clib_array*)0 )\r
117                 return 0;\r
118         if ( pArray->no_of_elements == 0 )\r
119                 return clib_true;\r
120         else\r
121                 return clib_false;\r
122 }\r
123 \r
124 clib_error \r
125 reserve_clib_array ( struct clib_array* pArray, int new_size) {\r
126         if ( pArray == (struct clib_array*)0 )\r
127                 return CLIB_ARRAY_NOT_INITIALIZED;\r
128 \r
129         if ( new_size <= pArray->no_max_elements )\r
130                 return CLIB_ERROR_SUCCESS;\r
131 \r
132         array_check_and_grow ( pArray);\r
133         return CLIB_ERROR_SUCCESS;\r
134 \r
135 }\r
136 \r
137 clib_error \r
138 front_clib_array ( struct clib_array* pArray,void *elem) {\r
139     return element_at_clib_array ( pArray, 0, elem );\r
140 }\r
141 \r
142 clib_error \r
143 back_clib_array ( struct clib_array* pArray,void *elem) {\r
144     return element_at_clib_array ( pArray, pArray->no_of_elements - 1, elem );\r
145 }\r
146 \r
147 clib_error \r
148 insert_at_clib_array ( struct clib_array* pArray, int index, void *elem, size_t elem_size) {\r
149     clib_error rc = CLIB_ERROR_SUCCESS;\r
150     if ( ! pArray )\r
151         return CLIB_ARRAY_NOT_INITIALIZED;\r
152 \r
153     if ( index < 0 || index > pArray->no_max_elements )\r
154         return CLIB_ARRAY_INDEX_OUT_OF_BOUND;\r
155 \r
156     array_check_and_grow ( pArray);\r
157 \r
158     memmove ( &(pArray->pElements[index + 1]),\r
159               &pArray->pElements[index],\r
160               (pArray->no_of_elements - index ) * sizeof(struct clib_object*));\r
161 \r
162     rc = insert_clib_array ( pArray, index, elem , elem_size);\r
163 \r
164     return rc;\r
165 }\r
166 \r
167 clib_error     \r
168 remove_clib_array ( struct clib_array* pArray, int index) {\r
169     clib_error   rc = CLIB_ERROR_SUCCESS;\r
170 \r
171     if ( ! pArray )\r
172         return rc;\r
173         if ( index < 0 || index >= pArray->no_of_elements )\r
174         return CLIB_ARRAY_INDEX_OUT_OF_BOUND;\r
175 \r
176     if ( pArray->destruct_fn ) {\r
177         void *elem;\r
178         if ( CLIB_ERROR_SUCCESS == element_at_clib_array ( pArray, index , &elem ) ) {\r
179             pArray->destruct_fn(elem);\r
180         }\r
181     }\r
182     delete_clib_object ( pArray->pElements[index]);\r
183 \r
184         if ( index != pArray->no_of_elements - 1 ) {\r
185             memmove ( &(pArray->pElements[index]),\r
186                           &pArray->pElements[index + 1],\r
187                               (pArray->no_of_elements - index ) * sizeof(struct clib_object*));\r
188         }\r
189     pArray->no_of_elements--;\r
190     return rc;\r
191 }\r
192 \r
193 clib_error \r
194 delete_clib_array( struct clib_array* pArray) {\r
195     clib_error rc = CLIB_ERROR_SUCCESS;\r
196     int i = 0;\r
197 \r
198     if ( pArray == (struct clib_array*)0 )\r
199         return rc;\r
200 \r
201     if ( pArray->destruct_fn ) {\r
202         for ( i = 0; i < pArray->no_of_elements; i++) {\r
203             void *elem;\r
204             if ( CLIB_ERROR_SUCCESS == element_at_clib_array ( pArray, i , &elem ) )\r
205                 pArray->destruct_fn(elem);\r
206         }\r
207     }\r
208     for ( i = 0; i < pArray->no_of_elements; i++) \r
209         delete_clib_object ( pArray->pElements[i]);    \r
210 \r
211     free ( pArray->pElements);\r
212     free ( pArray );\r
213     return rc;\r
214 }\r
215 \r
216 void \r
217 swap_element_clib_array ( struct clib_array *pArray, int left, int right) {\r
218         struct clib_object *temp = pArray->pElements[left];\r
219         pArray->pElements[left] = pArray->pElements[right];\r
220         pArray->pElements[right] = temp;\r
221 }\r
222 \r
223 void for_each_clib_array ( struct clib_array *pArray, void (*fn)(void*)) {\r
224         int size = pArray->no_of_elements;\r
225         int i = 0;\r
226         for ( i = 0; i < size; i++ ) {\r
227                 void *elem;\r
228                 element_at_clib_array ( pArray, i , &elem);\r
229                 (fn)(elem);\r
230                 free ( elem );\r
231         }\r
232 }