/src/ndpi/src/lib/ndpi_bitmap.c
Line | Count | Source |
1 | | /* |
2 | | * ndpi_bitmap.c |
3 | | * |
4 | | * Copyright (C) 2011-25 - ntop.org and contributors |
5 | | * |
6 | | * nDPI is free software: you can redistribute it and/or modify |
7 | | * it under the terms of the GNU Lesser General Public License as published by |
8 | | * the Free Software Foundation, either version 3 of the License, or |
9 | | * (at your option) any later version. |
10 | | * |
11 | | * nDPI is distributed in the hope that it will be useful, |
12 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | | * GNU Lesser General Public License for more details. |
15 | | * |
16 | | * You should have received a copy of the GNU Lesser General Public License |
17 | | * along with nDPI. If not, see <http://www.gnu.org/licenses/>. |
18 | | * |
19 | | */ |
20 | | |
21 | | |
22 | | #include <stdlib.h> |
23 | | #include <errno.h> |
24 | | #include <math.h> |
25 | | #include <sys/types.h> |
26 | | |
27 | | |
28 | | #define NDPI_CURRENT_PROTO NDPI_PROTOCOL_UNKNOWN |
29 | | |
30 | | #include "ndpi_config.h" |
31 | | #include "ndpi_api.h" |
32 | | #include "ndpi_includes.h" |
33 | | #include "ndpi_encryption.h" |
34 | | |
35 | | #ifdef USE_OLD_ROARING |
36 | | #include "third_party/include/roaring_v2.h" |
37 | | #else |
38 | | #include "third_party/include/roaring.h" |
39 | | #endif |
40 | | |
41 | | /* ******************************************* */ |
42 | | |
43 | 0 | ndpi_bitmap* ndpi_bitmap_alloc() { |
44 | | #ifdef USE_OLD_ROARING |
45 | | return((ndpi_bitmap*)roaring_bitmap_create()); |
46 | | #else |
47 | 0 | return((ndpi_bitmap*)roaring64_bitmap_create()); |
48 | 0 | #endif |
49 | 0 | } |
50 | | |
51 | | /* ******************************************* */ |
52 | | |
53 | 0 | void ndpi_bitmap_free(ndpi_bitmap* b) { |
54 | | #ifdef USE_OLD_ROARING |
55 | | roaring_bitmap_free((const roaring_bitmap_t *)b); |
56 | | #else |
57 | 0 | roaring64_bitmap_free((roaring64_bitmap_t *)b); |
58 | 0 | #endif |
59 | 0 | } |
60 | | |
61 | | /* ******************************************* */ |
62 | | |
63 | 0 | ndpi_bitmap* ndpi_bitmap_copy(ndpi_bitmap* b) { |
64 | | #ifdef USE_OLD_ROARING |
65 | | return(roaring_bitmap_copy(b)); |
66 | | #else |
67 | 0 | return(roaring64_bitmap_copy(b)); |
68 | 0 | #endif |
69 | 0 | } |
70 | | |
71 | | /* ******************************************* */ |
72 | | |
73 | 0 | u_int64_t ndpi_bitmap_cardinality(ndpi_bitmap* b) { |
74 | | #ifdef USE_OLD_ROARING |
75 | | return(roaring_bitmap_get_cardinality((const roaring_bitmap_t *)b)); |
76 | | #else |
77 | 0 | return(roaring64_bitmap_get_cardinality((roaring64_bitmap_t *)b)); |
78 | 0 | #endif |
79 | 0 | } |
80 | | |
81 | | /* ******************************************* */ |
82 | | |
83 | 0 | void ndpi_bitmap_set(ndpi_bitmap* b, u_int64_t value) { |
84 | | #ifdef USE_OLD_ROARING |
85 | | roaring_bitmap_add((roaring_bitmap_t *)b, value); |
86 | | #else |
87 | 0 | roaring64_bitmap_add((roaring64_bitmap_t *)b, value); |
88 | 0 | #endif |
89 | 0 | } |
90 | | |
91 | | /* ******************************************* */ |
92 | | |
93 | 0 | void ndpi_bitmap_unset(ndpi_bitmap* b, u_int64_t value) { |
94 | | #ifdef USE_OLD_ROARING |
95 | | roaring_bitmap_remove((roaring_bitmap_t *)b, value); |
96 | | #else |
97 | 0 | roaring64_bitmap_remove((roaring64_bitmap_t *)b, value); |
98 | 0 | #endif |
99 | 0 | } |
100 | | |
101 | | /* ******************************************* */ |
102 | | |
103 | 0 | bool ndpi_bitmap_isset(ndpi_bitmap* b, u_int64_t value) { |
104 | 0 | bool ret; |
105 | | |
106 | | #ifdef USE_OLD_ROARING |
107 | | ret = roaring_bitmap_contains((const roaring_bitmap_t *)b, value); |
108 | | #else |
109 | 0 | ret = roaring64_bitmap_contains((const roaring64_bitmap_t *)b, value); |
110 | 0 | #endif |
111 | |
|
112 | 0 | return(ret); |
113 | 0 | } |
114 | | |
115 | | /* ******************************************* */ |
116 | | |
117 | 0 | size_t ndpi_bitmap_serialize(ndpi_bitmap* b, char **buf) { |
118 | 0 | size_t s; |
119 | |
|
120 | | #ifdef USE_OLD_ROARING |
121 | | const roaring_bitmap_t *r = (const roaring_bitmap_t *)b; |
122 | | |
123 | | s = roaring_bitmap_portable_size_in_bytes(r); |
124 | | #else |
125 | 0 | const roaring64_bitmap_t *r = (const roaring64_bitmap_t *)b; |
126 | | |
127 | 0 | s = roaring64_bitmap_portable_size_in_bytes(r); |
128 | 0 | #endif |
129 | | |
130 | 0 | *buf = (char*)ndpi_malloc(s); |
131 | |
|
132 | 0 | if((*buf) == NULL) return(0); |
133 | | |
134 | | #ifdef USE_OLD_ROARING |
135 | | return(roaring_bitmap_portable_serialize(r, *buf)); |
136 | | #else |
137 | 0 | return(roaring64_bitmap_portable_serialize(r, *buf)); |
138 | 0 | #endif |
139 | 0 | } |
140 | | |
141 | | /* ******************************************* */ |
142 | | |
143 | 0 | ndpi_bitmap* ndpi_bitmap_deserialize(char *buf, size_t buf_len) { |
144 | | #ifdef USE_OLD_ROARING |
145 | | return((ndpi_bitmap*)roaring_bitmap_portable_deserialize_safe(buf, buf_len)); |
146 | | #else |
147 | 0 | return((ndpi_bitmap*)roaring64_bitmap_portable_deserialize_safe(buf, buf_len)); |
148 | 0 | #endif |
149 | 0 | } |
150 | | |
151 | | /* ******************************************* */ |
152 | | |
153 | | /* b = b & b_and */ |
154 | 0 | void ndpi_bitmap_and(ndpi_bitmap* a, ndpi_bitmap* b_and) { |
155 | | #ifdef USE_OLD_ROARING |
156 | | roaring_bitmap_and_inplace((roaring_bitmap_t*)a, (roaring_bitmap_t*)b_and); |
157 | | #else |
158 | 0 | roaring64_bitmap_and_inplace((roaring64_bitmap_t*)a, (roaring64_bitmap_t*)b_and); |
159 | 0 | #endif |
160 | 0 | } |
161 | | |
162 | | /* ******************************************* */ |
163 | | |
164 | | /* b = b & b_and */ |
165 | 0 | ndpi_bitmap* ndpi_bitmap_and_alloc(ndpi_bitmap* a, ndpi_bitmap* b_and) { |
166 | | #ifdef USE_OLD_ROARING |
167 | | return((ndpi_bitmap*)roaring_bitmap_and((roaring_bitmap_t*)a, (roaring_bitmap_t*)b_and)); |
168 | | #else |
169 | 0 | return((ndpi_bitmap*)roaring64_bitmap_and((roaring64_bitmap_t*)a, (roaring64_bitmap_t*)b_and)); |
170 | 0 | #endif |
171 | 0 | } |
172 | | |
173 | | /* ******************************************* */ |
174 | | |
175 | | /* b = b & !b_and */ |
176 | 0 | void ndpi_bitmap_andnot(ndpi_bitmap* a, ndpi_bitmap* b_and) { |
177 | | #ifdef USE_OLD_ROARING |
178 | | roaring_bitmap_andnot_inplace((roaring_bitmap_t*)a, (roaring_bitmap_t*)b_and); |
179 | | #else |
180 | 0 | roaring64_bitmap_andnot_inplace((roaring64_bitmap_t*)a, (roaring64_bitmap_t*)b_and); |
181 | 0 | #endif |
182 | 0 | } |
183 | | |
184 | | /* ******************************************* */ |
185 | | |
186 | | /* b = b | b_or */ |
187 | 0 | void ndpi_bitmap_or(ndpi_bitmap* a, ndpi_bitmap* b_or) { |
188 | | #ifdef USE_OLD_ROARING |
189 | | roaring_bitmap_or_inplace((roaring_bitmap_t*)a, (roaring_bitmap_t*)b_or); |
190 | | #else |
191 | 0 | roaring64_bitmap_or_inplace((roaring64_bitmap_t*)a, (roaring64_bitmap_t*)b_or); |
192 | 0 | #endif |
193 | 0 | } |
194 | | |
195 | | /* ******************************************* */ |
196 | | |
197 | | /* b = b | b_or */ |
198 | 0 | ndpi_bitmap* ndpi_bitmap_or_alloc(ndpi_bitmap* a, ndpi_bitmap* b_or) { |
199 | | #ifdef USE_OLD_ROARING |
200 | | return((ndpi_bitmap*)roaring_bitmap_or((roaring_bitmap_t*)a, (roaring_bitmap_t*)b_or)); |
201 | | #else |
202 | 0 | return((ndpi_bitmap*)roaring64_bitmap_or((roaring64_bitmap_t*)a, (roaring64_bitmap_t*)b_or)); |
203 | 0 | #endif |
204 | 0 | } |
205 | | |
206 | | /* ******************************************* */ |
207 | | |
208 | | /* b = b ^ b_xor */ |
209 | 0 | void ndpi_bitmap_xor(ndpi_bitmap* a, ndpi_bitmap* b_xor) { |
210 | | #ifdef USE_OLD_ROARING |
211 | | roaring_bitmap_xor_inplace((roaring_bitmap_t*)a, (roaring_bitmap_t*)b_xor); |
212 | | #else |
213 | 0 | roaring64_bitmap_xor_inplace((roaring64_bitmap_t*)a, (roaring64_bitmap_t*)b_xor); |
214 | 0 | #endif |
215 | 0 | } |
216 | | |
217 | | /* ******************************************* */ |
218 | | |
219 | 0 | void ndpi_bitmap_optimize(ndpi_bitmap* a) { |
220 | | #ifdef USE_OLD_ROARING |
221 | | roaring_bitmap_run_optimize(a); |
222 | | #else |
223 | 0 | roaring64_bitmap_run_optimize(a); |
224 | 0 | #endif |
225 | 0 | } |
226 | | |
227 | | /* ******************************************* */ |
228 | | |
229 | 0 | ndpi_bitmap_iterator* ndpi_bitmap_iterator_alloc(ndpi_bitmap* b) { |
230 | | #ifdef USE_OLD_ROARING |
231 | | return((ndpi_bitmap_iterator*)roaring_create_iterator((roaring_bitmap_t*)b)); |
232 | | #else |
233 | 0 | return((ndpi_bitmap_iterator*)roaring64_iterator_create((const roaring64_bitmap_t*)b)); |
234 | 0 | #endif |
235 | 0 | } |
236 | | |
237 | | /* ******************************************* */ |
238 | | |
239 | 0 | void ndpi_bitmap_iterator_free(ndpi_bitmap* b) { |
240 | | #ifdef USE_OLD_ROARING |
241 | | roaring_free_uint32_iterator((roaring_uint32_iterator_t*)b); |
242 | | #else |
243 | 0 | roaring64_iterator_free((roaring64_iterator_t*)b); |
244 | 0 | #endif |
245 | 0 | } |
246 | | |
247 | | /* ******************************************* */ |
248 | | |
249 | 0 | bool ndpi_bitmap_is_empty(ndpi_bitmap* b) { |
250 | | #ifdef USE_OLD_ROARING |
251 | | return(roaring_bitmap_is_empty((roaring_bitmap_t*)b)); |
252 | | #else |
253 | 0 | return(roaring64_bitmap_is_empty((roaring64_bitmap_t*)b)); |
254 | 0 | #endif |
255 | 0 | } |
256 | | |
257 | | /* ******************************************* */ |
258 | | |
259 | | /* Return the next value in the bitmap iterator |
260 | | |
261 | | true is returned when a value is present, false when we reached the end |
262 | | */ |
263 | 0 | bool ndpi_bitmap_iterator_next(ndpi_bitmap_iterator* i, u_int64_t *value) { |
264 | | #ifdef USE_OLD_ROARING |
265 | | uint32_t ret; |
266 | | uint32_t num = roaring_read_uint32_iterator((roaring_uint32_iterator_t*)i, &ret, 1); |
267 | | |
268 | | *value = (uint32_t)ret; |
269 | | #else |
270 | 0 | uint64_t num = roaring64_iterator_read((roaring64_iterator_t*)i, value, 1); |
271 | 0 | #endif |
272 | | |
273 | 0 | return((num == 1) ? true /* found */ : false /* not found */); |
274 | 0 | } |