1 /*
2 bctoolbox
3 Copyright (C) 2016 Belledonne Communications SARL
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22
23 #include "bctoolbox/logging.h"
24 #include "bctoolbox/map.h"
25 #include <map>
26 #include <typeinfo>
27
28 #define LOG_DOMAIN "bctoolbox"
29
30 typedef std::multimap<unsigned long long, void*> mmap_ullong_t;
31 typedef mmap_ullong_t::value_type pair_ullong_t;
32
33 typedef std::multimap<std::string, void*> mmap_cchar_t;
34 typedef mmap_cchar_t::value_type pair_cchar_t;
35
bctbx_mmap_new(void)36 template<typename T> bctbx_map_t * bctbx_mmap_new(void) {
37 return (bctbx_map_t *) new T;
38 }
bctbx_mmap_ullong_new(void)39 extern "C" bctbx_map_t *bctbx_mmap_ullong_new(void) {
40 return bctbx_mmap_new<mmap_ullong_t>();
41 }
bctbx_mmap_cchar_new(void)42 extern "C" bctbx_map_t *bctbx_mmap_cchar_new(void) {
43 return bctbx_mmap_new<mmap_cchar_t>();
44 }
45
bctbx_mmap_delete(bctbx_map_t * mmap)46 template<typename T> void bctbx_mmap_delete(bctbx_map_t *mmap) {
47 delete (T *)mmap;
48 }
bctbx_mmap_ullong_delete(bctbx_map_t * mmap)49 extern "C" void bctbx_mmap_ullong_delete(bctbx_map_t *mmap) {
50 bctbx_mmap_delete<mmap_ullong_t>(mmap);
51 }
bctbx_mmap_cchar_delete(bctbx_map_t * mmap)52 extern "C" void bctbx_mmap_cchar_delete(bctbx_map_t *mmap) {
53 bctbx_mmap_delete<mmap_cchar_t>(mmap);
54 }
bctbx_mmap_ullong_delete_with_data(bctbx_map_t * mmap,bctbx_map_free_func freefunc)55 extern "C" void bctbx_mmap_ullong_delete_with_data(bctbx_map_t *mmap, bctbx_map_free_func freefunc) {
56 bctbx_iterator_t *it = bctbx_map_ullong_begin(mmap);
57 bctbx_iterator_t *end = bctbx_map_ullong_end(mmap);
58
59 while(!bctbx_iterator_ullong_equals(it, end)) {
60 bctbx_pair_t *pair = bctbx_iterator_ullong_get_pair(it);
61 freefunc(bctbx_pair_ullong_get_second(pair));
62 it = bctbx_iterator_ullong_get_next(it);
63 }
64 bctbx_iterator_ullong_delete(it);
65 bctbx_iterator_ullong_delete(end);
66 bctbx_mmap_ullong_delete(mmap);
67 }
bctbx_mmap_cchar_delete_with_data(bctbx_map_t * mmap,bctbx_map_free_func freefunc)68 extern "C" void bctbx_mmap_cchar_delete_with_data(bctbx_map_t *mmap, bctbx_map_free_func freefunc) {
69 bctbx_iterator_t *it = bctbx_map_cchar_begin(mmap);
70 bctbx_iterator_t *end = bctbx_map_cchar_end(mmap);
71
72 while(!bctbx_iterator_cchar_equals(it, end)) {
73 bctbx_pair_t *pair = bctbx_iterator_cchar_get_pair(it);
74 freefunc(bctbx_pair_cchar_get_second(pair));
75 it = bctbx_iterator_cchar_get_next(it);
76 }
77 bctbx_iterator_cchar_delete(it);
78 bctbx_iterator_cchar_delete(end);
79 bctbx_mmap_cchar_delete(mmap);
80 }
81
bctbx_map_insert_base(bctbx_map_t * map,const bctbx_pair_t * pair,bool_t returns_it)82 template<typename T> bctbx_iterator_t *bctbx_map_insert_base(bctbx_map_t *map,const bctbx_pair_t *pair,bool_t returns_it) {
83 typename T::iterator it;
84 it = ((T *)map)->insert(*((typename T::value_type *)pair));
85 if (returns_it) {
86 return (bctbx_iterator_t *) new typename T::iterator(it);
87 } else
88 return NULL;
89 }
bctbx_map_ullong_insert_base(bctbx_map_t * map,const bctbx_pair_t * pair,bool_t returns_it)90 static bctbx_iterator_t * bctbx_map_ullong_insert_base(bctbx_map_t *map,const bctbx_pair_t *pair,bool_t returns_it) {
91 return bctbx_map_insert_base<mmap_ullong_t>(map, pair, returns_it);
92 }
bctbx_map_ullong_insert(bctbx_map_t * map,const bctbx_pair_t * pair)93 extern "C" void bctbx_map_ullong_insert(bctbx_map_t *map,const bctbx_pair_t *pair) {
94 bctbx_map_ullong_insert_base(map,pair,FALSE);
95 }
bctbx_map_cchar_insert_base(bctbx_map_t * map,const bctbx_pair_t * pair,bool_t returns_it)96 static bctbx_iterator_t * bctbx_map_cchar_insert_base(bctbx_map_t *map,const bctbx_pair_t *pair,bool_t returns_it) {
97 return bctbx_map_insert_base<mmap_cchar_t>(map, pair, returns_it);
98 }
bctbx_map_cchar_insert(bctbx_map_t * map,const bctbx_pair_t * pair)99 extern "C" void bctbx_map_cchar_insert(bctbx_map_t *map,const bctbx_pair_t *pair) {
100 bctbx_map_cchar_insert_base(map,pair,FALSE);
101 }
bctbx_map_ullong_insert_and_delete(bctbx_map_t * map,bctbx_pair_t * pair)102 extern "C" void bctbx_map_ullong_insert_and_delete(bctbx_map_t *map, bctbx_pair_t *pair) {
103 bctbx_map_ullong_insert(map,pair);
104 bctbx_pair_ullong_delete(pair);
105 }
bctbx_map_ullong_insert_and_delete_with_returned_it(bctbx_map_t * map,bctbx_pair_t * pair)106 extern "C" bctbx_iterator_t * bctbx_map_ullong_insert_and_delete_with_returned_it(bctbx_map_t *map, bctbx_pair_t *pair) {
107 bctbx_iterator_t * it = bctbx_map_ullong_insert_base(map,pair,TRUE);
108 bctbx_pair_ullong_delete(pair);
109 return it;
110 }
bctbx_map_cchar_insert_and_delete(bctbx_map_t * map,bctbx_pair_t * pair)111 extern "C" void bctbx_map_cchar_insert_and_delete(bctbx_map_t *map, bctbx_pair_t *pair) {
112 bctbx_map_cchar_insert(map,pair);
113 bctbx_pair_cchar_delete(pair);
114 }
bctbx_map_cchar_insert_and_delete_with_returned_it(bctbx_map_t * map,bctbx_pair_t * pair)115 extern "C" bctbx_iterator_t * bctbx_map_cchar_insert_and_delete_with_returned_it(bctbx_map_t *map, bctbx_pair_t *pair) {
116 bctbx_iterator_t * it = bctbx_map_cchar_insert_base(map,pair,TRUE);
117 bctbx_pair_cchar_delete(pair);
118 return it;
119 }
120
bctbx_map_erase_type(bctbx_map_t * map,bctbx_iterator_t * it)121 template<typename T> bctbx_iterator_t *bctbx_map_erase_type(bctbx_map_t *map,bctbx_iterator_t *it) {
122 //bctbx_iterator_t * next = (bctbx_iterator_t *) new mmap_ullong_t::iterator((*(mmap_ullong_t::iterator*)it));
123 //next = bctbx_iterator_get_next(next);
124 ((T *)map)->erase((*(typename T::iterator*)it)++);
125 //bctbx_iterator_delete(it);
126 return it;
127 }
bctbx_map_ullong_erase(bctbx_map_t * map,bctbx_iterator_t * it)128 extern "C" bctbx_iterator_t *bctbx_map_ullong_erase(bctbx_map_t *map,bctbx_iterator_t *it) {
129 return bctbx_map_erase_type<mmap_ullong_t>(map, it);
130 }
bctbx_map_cchar_erase(bctbx_map_t * map,bctbx_iterator_t * it)131 extern "C" bctbx_iterator_t *bctbx_map_cchar_erase(bctbx_map_t *map,bctbx_iterator_t *it) {
132 return bctbx_map_erase_type<mmap_cchar_t>(map, it);
133 }
134
bctbx_map_begin_type(const bctbx_map_t * map)135 template<typename T> bctbx_iterator_t *bctbx_map_begin_type(const bctbx_map_t *map) {
136 return (bctbx_iterator_t *) new typename T::iterator(((T *)map)->begin());
137
138 }
bctbx_map_ullong_begin(const bctbx_map_t * map)139 extern "C" bctbx_iterator_t *bctbx_map_ullong_begin(const bctbx_map_t *map) {
140 return bctbx_map_begin_type<mmap_ullong_t>(map);
141 }
bctbx_map_cchar_begin(const bctbx_map_t * map)142 extern "C" bctbx_iterator_t *bctbx_map_cchar_begin(const bctbx_map_t *map) {
143 return bctbx_map_begin_type<mmap_cchar_t>(map);
144 }
145
bctbx_map_end_type(const bctbx_map_t * map)146 template<typename T> bctbx_iterator_t *bctbx_map_end_type(const bctbx_map_t *map) {
147 return (bctbx_iterator_t *) new typename T::iterator(((T *)map)->end());
148
149 }
bctbx_map_ullong_end(const bctbx_map_t * map)150 extern "C" bctbx_iterator_t *bctbx_map_ullong_end(const bctbx_map_t *map) {
151 return bctbx_map_end_type<mmap_ullong_t>(map);
152 }
bctbx_map_cchar_end(const bctbx_map_t * map)153 extern "C" bctbx_iterator_t *bctbx_map_cchar_end(const bctbx_map_t *map) {
154 return bctbx_map_end_type<mmap_cchar_t>(map);
155 }
156
bctbx_map_find_key_type(bctbx_map_t * map,typename T::key_type key)157 template<typename T> bctbx_iterator_t * bctbx_map_find_key_type(bctbx_map_t *map, typename T::key_type key) {
158 bctbx_iterator_t * it = (bctbx_iterator_t*) new typename T::iterator(((T *)map)->find(key));
159 return it;
160 }
bctbx_map_ullong_find_key(bctbx_map_t * map,unsigned long long key)161 extern "C" bctbx_iterator_t * bctbx_map_ullong_find_key(bctbx_map_t *map, unsigned long long key) {
162 return bctbx_map_find_key_type<mmap_ullong_t>(map, (mmap_ullong_t::key_type)key);
163 }
bctbx_map_cchar_find_key(bctbx_map_t * map,const char * key)164 extern "C" bctbx_iterator_t * bctbx_map_cchar_find_key(bctbx_map_t *map, const char * key) {
165 return bctbx_map_find_key_type<mmap_cchar_t>(map, (mmap_cchar_t::key_type)key);
166 }
167
bctbx_map_size_type(const bctbx_map_t * map)168 template<typename T> size_t bctbx_map_size_type(const bctbx_map_t *map) {
169 return ((T *)map)->size();
170 }
bctbx_map_ullong_size(const bctbx_map_t * map)171 extern "C" size_t bctbx_map_ullong_size(const bctbx_map_t *map) {
172 return bctbx_map_size_type<mmap_ullong_t>(map);
173 }
bctbx_map_cchar_size(const bctbx_map_t * map)174 extern "C" size_t bctbx_map_cchar_size(const bctbx_map_t *map) {
175 return bctbx_map_size_type<mmap_cchar_t>(map);
176 }
177
bctbx_map_ullong_find_custom(bctbx_map_t * map,bctbx_compare_func compare_func,const void * user_data)178 extern "C" bctbx_iterator_t * bctbx_map_ullong_find_custom(bctbx_map_t *map, bctbx_compare_func compare_func, const void *user_data) {
179 bctbx_iterator_t * end = bctbx_map_ullong_end(map);
180
181 for(bctbx_iterator_t * it = bctbx_map_ullong_begin(map);!bctbx_iterator_ullong_equals(it,end);) {
182 if (compare_func(bctbx_pair_ullong_get_second(bctbx_iterator_ullong_get_pair(it)),user_data)==0) {
183 bctbx_iterator_ullong_delete(end);
184 return it;
185 } else {
186 it = bctbx_iterator_ullong_get_next(it);
187 }
188
189 }
190 bctbx_iterator_ullong_delete(end);
191 return NULL;
192 }
bctbx_map_cchar_find_custom(bctbx_map_t * map,bctbx_compare_func compare_func,const void * user_data)193 extern "C" bctbx_iterator_t * bctbx_map_cchar_find_custom(bctbx_map_t *map, bctbx_compare_func compare_func, const void *user_data) {
194 bctbx_iterator_t * end = bctbx_map_cchar_end(map);
195
196 for(bctbx_iterator_t * it = bctbx_map_cchar_begin(map);!bctbx_iterator_cchar_equals(it,end);) {
197 if (compare_func(bctbx_pair_cchar_get_second(bctbx_iterator_cchar_get_pair(it)),user_data)==0) {
198 bctbx_iterator_cchar_delete(end);
199 return it;
200 } else {
201 it = bctbx_iterator_cchar_get_next(it);
202 }
203
204 }
205 bctbx_iterator_cchar_delete(end);
206 return NULL;
207 }
208
209 /*iterator*/
bctbx_iterator_get_pair_type(const bctbx_iterator_t * it)210 template<typename T> bctbx_pair_t *bctbx_iterator_get_pair_type(const bctbx_iterator_t *it) {
211 return (bctbx_pair_t *)&(**((typename T::iterator*)it));
212 }
bctbx_iterator_ullong_get_pair(const bctbx_iterator_t * it)213 extern "C" bctbx_pair_t *bctbx_iterator_ullong_get_pair(const bctbx_iterator_t *it) {
214 return bctbx_iterator_get_pair_type<mmap_ullong_t>(it);
215 }
bctbx_iterator_cchar_get_pair(const bctbx_iterator_t * it)216 extern "C" bctbx_pair_t *bctbx_iterator_cchar_get_pair(const bctbx_iterator_t *it) {
217 return bctbx_iterator_get_pair_type<mmap_cchar_t>(it);
218 }
219
bctbx_iterator_get_next_type(bctbx_iterator_t * it)220 template<typename T> bctbx_iterator_t *bctbx_iterator_get_next_type(bctbx_iterator_t *it) {
221 ((typename T::iterator*)it)->operator++();
222 return it;
223 }
bctbx_iterator_ullong_get_next(bctbx_iterator_t * it)224 extern "C" bctbx_iterator_t *bctbx_iterator_ullong_get_next(bctbx_iterator_t *it) {
225 return bctbx_iterator_get_next_type<mmap_ullong_t>(it);
226 }
bctbx_iterator_cchar_get_next(bctbx_iterator_t * it)227 extern "C" bctbx_iterator_t *bctbx_iterator_cchar_get_next(bctbx_iterator_t *it) {
228 return bctbx_iterator_get_next_type<mmap_cchar_t>(it);
229 }
bctbx_iterator_ullong_get_next_and_delete(bctbx_iterator_t * it)230 extern "C" bctbx_iterator_t *bctbx_iterator_ullong_get_next_and_delete(bctbx_iterator_t *it) {
231 bctbx_iterator_t * next = bctbx_iterator_ullong_get_next(it);
232 bctbx_iterator_ullong_delete(it);
233 return next;
234 }
bctbx_iterator_cchar_get_next_and_delete(bctbx_iterator_t * it)235 extern "C" bctbx_iterator_t *bctbx_iterator_cchar_get_next_and_delete(bctbx_iterator_t *it) {
236 bctbx_iterator_t * next = bctbx_iterator_cchar_get_next(it);
237 bctbx_iterator_cchar_delete(it);
238 return next;
239 }
240
bctbx_iterator_equals_type(const bctbx_iterator_t * a,const bctbx_iterator_t * b)241 template<typename T> bool_t bctbx_iterator_equals_type(const bctbx_iterator_t *a,const bctbx_iterator_t *b) {
242 return *(typename T::iterator*)a == *(typename T::iterator*)b;
243 }
bctbx_iterator_ullong_equals(const bctbx_iterator_t * a,const bctbx_iterator_t * b)244 extern "C" bool_t bctbx_iterator_ullong_equals(const bctbx_iterator_t *a,const bctbx_iterator_t *b) {
245 return bctbx_iterator_equals_type<mmap_ullong_t>(a, b);
246 }
bctbx_iterator_cchar_equals(const bctbx_iterator_t * a,const bctbx_iterator_t * b)247 extern "C" bool_t bctbx_iterator_cchar_equals(const bctbx_iterator_t *a,const bctbx_iterator_t *b) {
248 return bctbx_iterator_equals_type<mmap_cchar_t>(a, b);
249 }
250
bctbx_iterator_delete_type(bctbx_iterator_t * it)251 template<typename T> void bctbx_iterator_delete_type(bctbx_iterator_t *it) {
252 delete ((typename T::iterator*)it);
253 }
bctbx_iterator_ullong_delete(bctbx_iterator_t * it)254 extern "C" void bctbx_iterator_ullong_delete(bctbx_iterator_t *it) {
255 bctbx_iterator_delete_type<mmap_ullong_t>(it);
256 }
bctbx_iterator_cchar_delete(bctbx_iterator_t * it)257 extern "C" void bctbx_iterator_cchar_delete(bctbx_iterator_t *it) {
258 bctbx_iterator_delete_type<mmap_cchar_t>(it);
259 }
260
261 /*pair*/
bctbx_pair_new(typename T::key_type key,void * value)262 template<typename T> typename T::value_type * bctbx_pair_new(typename T::key_type key,void *value) {
263 return (typename T::value_type *) new typename T::value_type(key,value);
264 }
bctbx_pair_ullong_new(unsigned long long key,void * value)265 extern "C" bctbx_pair_ullong_t * bctbx_pair_ullong_new(unsigned long long key,void *value) {
266 return (bctbx_pair_ullong_t *)bctbx_pair_new<mmap_ullong_t>((mmap_ullong_t::key_type)key, value);
267 }
bctbx_pair_cchar_new(const char * key,void * value)268 extern "C" bctbx_pair_cchar_t * bctbx_pair_cchar_new(const char * key,void *value) {
269 return (bctbx_pair_cchar_t *)bctbx_pair_new<mmap_cchar_t>((mmap_cchar_t::key_type)key, value);
270 }
271
bctbx_pair_get_first(const typename T::value_type * pair)272 template<typename T> typename T::key_type bctbx_pair_get_first(const typename T::value_type * pair) {
273 return ((typename T::value_type*)pair)->first;
274 }
bctbx_pair_ullong_get_first(const bctbx_pair_ullong_t * pair)275 extern "C" unsigned long long bctbx_pair_ullong_get_first(const bctbx_pair_ullong_t * pair) {
276 return bctbx_pair_get_first<mmap_ullong_t>((pair_ullong_t *)pair);
277 }
bctbx_pair_cchar_get_first(const bctbx_pair_cchar_t * pair)278 extern "C" const char * bctbx_pair_cchar_get_first(const bctbx_pair_cchar_t * pair) {
279 return bctbx_pair_get_first<mmap_cchar_t>((pair_cchar_t *)pair).c_str();
280 }
281
bctbx_pair_get_second_type(const bctbx_pair_t * pair)282 template<typename T> void* bctbx_pair_get_second_type(const bctbx_pair_t * pair) {
283 return ((T*)pair)->second;
284 }
bctbx_pair_ullong_get_second(const bctbx_pair_t * pair)285 extern "C" void* bctbx_pair_ullong_get_second(const bctbx_pair_t * pair) {
286 return bctbx_pair_get_second_type<pair_ullong_t>(pair);
287 }
bctbx_pair_cchar_get_second(const bctbx_pair_t * pair)288 extern "C" void* bctbx_pair_cchar_get_second(const bctbx_pair_t * pair) {
289 return bctbx_pair_get_second_type<pair_cchar_t>(pair);
290 }
291
bctbx_pair_delete_type(bctbx_pair_t * pair)292 template<typename T> void bctbx_pair_delete_type(bctbx_pair_t * pair) {
293 delete ((T*)pair);
294 }
bctbx_pair_ullong_delete(bctbx_pair_t * pair)295 extern "C" void bctbx_pair_ullong_delete(bctbx_pair_t * pair) {
296 bctbx_pair_delete_type<pair_ullong_t>(pair);
297 }
bctbx_pair_cchar_delete(bctbx_pair_t * pair)298 extern "C" void bctbx_pair_cchar_delete(bctbx_pair_t * pair) {
299 bctbx_pair_delete_type<pair_cchar_t>(pair);
300 }
301