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