blob: 29c3e33d6355cf5e777953c7d0713d8b60dfbded [file] [log] [blame]
Jacob Erlbeck5f349be2015-12-21 16:04:03 +01001#include <inttypes.h>
2#include <stdio.h>
3#include <stdlib.h>
4#include <stdint.h>
5#include <string.h>
Max0a59e982016-02-05 13:55:37 +01006#include <time.h>
7#include <stdbool.h>
8#include <errno.h>
Jacob Erlbeck5f349be2015-12-21 16:04:03 +01009
10#include <osmocom/core/utils.h>
11#include <osmocom/core/bitvec.h>
Max0a59e982016-02-05 13:55:37 +010012#include <osmocom/core/bits.h>
13
Max0a59e982016-02-05 13:55:37 +010014static char lol[1024]; // we pollute this with printed vectors
15static inline void test_rl(const struct bitvec *bv)
16{
17 bitvec_to_string_r(bv, lol);
18 printf("%s [%d] RL0=%d, RL1=%d\n", lol, bv->cur_bit, bitvec_rl(bv, false), bitvec_rl(bv, true));
19}
20
21static inline void test_shift(struct bitvec *bv, unsigned n)
22{
23 bitvec_to_string_r(bv, lol);
24 printf("%s << %d:\n", lol, n);
25 bitvec_shiftl(bv, n);
26 bitvec_to_string_r(bv, lol);
27 printf("%s\n", lol);
28}
29
30static inline void test_get(struct bitvec *bv, unsigned n)
31{
32 bitvec_to_string_r(bv, lol);
33 printf("%s [%d]", lol, bv->cur_bit);
34 int16_t x = bitvec_get_int16_msb(bv, n);
35 uint8_t tmp[2];
36 osmo_store16be(x, &tmp);
Max6a5ef462016-02-24 16:05:48 +010037 printf(" -> %d (%u bit) ["OSMO_BIN_SPEC" "OSMO_BIN_SPEC"]:\n", x, n, OSMO_BIN_PRINT(tmp[0]), OSMO_BIN_PRINT(tmp[1]));
Max0a59e982016-02-05 13:55:37 +010038 bitvec_to_string_r(bv, lol);
39 printf("%s [%d]\n", lol, bv->cur_bit);
40}
41
42static inline void test_fill(struct bitvec *bv, unsigned n, enum bit_value val)
43{
44 bitvec_to_string_r(bv, lol);
45 unsigned bvlen = bv->cur_bit;
46 int fi = bitvec_fill(bv, n, val);
47 printf("%c> FILL %s [%d] -%d-> [%d]:\n", bit_value_to_char(val), lol, bvlen, n, fi);
48 bitvec_to_string_r(bv, lol);
49 printf(" %s [%d]\n\n", lol, bv->cur_bit);
50}
51
52static inline void test_spare(struct bitvec *bv, unsigned n)
53{
54 bitvec_to_string_r(bv, lol);
55 unsigned bvlen = bv->cur_bit;
56 int sp = bitvec_spare_padding(bv, n);
57 printf("%c> SPARE %s [%d] -%d-> [%d]:\n", bit_value_to_char(L), lol, bvlen, n, sp);
58 bitvec_to_string_r(bv, lol);
59 printf(" %s [%d]\n\n", lol, bv->cur_bit);
60}
61
62static inline void test_set(struct bitvec *bv, enum bit_value bit)
63{
64 bitvec_to_string_r(bv, lol);
65 unsigned bvlen = bv->cur_bit;
66 int set = bitvec_set_bit(bv, bit);
67 printf("%c> SET %s [%d] ++> [%d]:\n", bit_value_to_char(bit), lol, bvlen, set);
68 bitvec_to_string_r(bv, lol);
69 printf(" %s [%d]\n\n", lol, bv->cur_bit);
70}
Jacob Erlbeck5f349be2015-12-21 16:04:03 +010071
Harald Weltee61d4592022-11-03 11:05:58 +010072static void test_byte_ops(void)
Jacob Erlbeck5f349be2015-12-21 16:04:03 +010073{
74 struct bitvec bv;
75 const uint8_t *in = (const uint8_t *)"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
76 uint8_t out[26 + 2];
77 uint8_t data[64];
78 int i;
79 int rc;
80 int in_size = strlen((const char *)in);
81
82 printf("=== start %s ===\n", __func__);
83
84 bv.data = data;
85 bv.data_len = sizeof(data);
86
87 for (i = 0; i < 32; i++) {
88 /* Write to bitvec */
89 memset(data, 0x00, sizeof(data));
90 bv.cur_bit = i;
91 rc = bitvec_set_uint(&bv, 0x7e, 8);
92 OSMO_ASSERT(rc >= 0);
93 rc = bitvec_set_bytes(&bv, in, in_size);
94 OSMO_ASSERT(rc >= 0);
95 rc = bitvec_set_uint(&bv, 0x7e, 8);
96 OSMO_ASSERT(rc >= 0);
97
Max0a59e982016-02-05 13:55:37 +010098 printf("bitvec: %s\n", osmo_hexdump(bv.data, bv.data_len));
Jacob Erlbeck5f349be2015-12-21 16:04:03 +010099
100 /* Read from bitvec */
101 memset(out, 0xff, sizeof(out));
102 bv.cur_bit = i;
103 rc = bitvec_get_uint(&bv, 8);
104 OSMO_ASSERT(rc == 0x7e);
105 rc = bitvec_get_bytes(&bv, out + 1, in_size);
106 OSMO_ASSERT(rc >= 0);
107 rc = bitvec_get_uint(&bv, 8);
108 OSMO_ASSERT(rc == 0x7e);
109
Max0a59e982016-02-05 13:55:37 +0100110 printf("out: %s\n", osmo_hexdump(out, sizeof(out)));
Jacob Erlbeck5f349be2015-12-21 16:04:03 +0100111
112 OSMO_ASSERT(out[0] == 0xff);
113 OSMO_ASSERT(out[in_size+1] == 0xff);
114 OSMO_ASSERT(memcmp(in, out + 1, in_size) == 0);
115 }
116
117 printf("=== end %s ===\n", __func__);
118}
119
Holger Hans Peter Freythera9301a12016-01-30 10:54:43 +0100120static void test_unhex(const char *hex)
121{
Holger Hans Peter Freyther57108042016-01-30 16:16:28 +0100122 int rc;
Holger Hans Peter Freythera9301a12016-01-30 10:54:43 +0100123 struct bitvec b;
124 uint8_t d[64] = {0};
125 b.data = d;
126 b.data_len = sizeof(d);
127 b.cur_bit = 0;
Holger Hans Peter Freyther57108042016-01-30 16:16:28 +0100128
129 rc = bitvec_unhex(&b, hex);
130 printf("%d -=> cur_bit=%u\n", rc, b.cur_bit);
131 printf("%s\n", osmo_hexdump_nospc(d, 64));
132 printf("%s\n", hex);
Holger Hans Peter Freythera9301a12016-01-30 10:54:43 +0100133}
134
Maxd4793212016-03-17 11:51:08 +0100135static inline void test_array_item(unsigned t, struct bitvec *b, unsigned int n,
136 uint32_t *array, unsigned int p)
137{
138 unsigned int i, x, y;
139 bitvec_zero(b);
140 x = b->cur_bit;
141 i = bitvec_add_array(b, array, n, true, t);
142 y = b->cur_bit;
143 bitvec_add_array(b, array, n, false, t);
144 printf("\nbits: %u, est: %u, real: %u, x: %u, y: %u\n",
145 t, i, b->cur_bit, x, y);
146 for (i = 0; i < p; i++) {
147 printf(OSMO_BIT_SPEC " ", OSMO_BIT_PRINT(b->data[i]));
148 if (0 == (i + 1) % 15)
149 printf("\n");
150 }
151}
152
Pravin Kumarvel848de8f2016-12-02 15:13:03 +0530153static inline void test_bitvec_rl_curbit(struct bitvec *bv, bool b, int max_bits,
154 int result )
155{
156 int num = 0;
157 int readIndex = bv->cur_bit;
158 OSMO_ASSERT(bv->cur_bit < max_bits);
159 num = bitvec_rl_curbit(bv, b, max_bits);
160 readIndex += num;
161 OSMO_ASSERT(bv->cur_bit == readIndex);
162 OSMO_ASSERT(num == result);
163}
164
Harald Weltee61d4592022-11-03 11:05:58 +0100165static void test_array(void)
Maxd4793212016-03-17 11:51:08 +0100166{
167 struct bitvec b;
168 uint8_t d[4096];
169 b.data = d;
170 b.data_len = sizeof(d);
171
172 unsigned int i, n = 64;
173 uint32_t array[n];
174 for (i = 0; i < n; i++) {
175 array[i] = i * i * i + i;
176 printf("0x%x ", array[i]);
177 }
178
179 test_array_item(3, &b, n, array, n);
180 test_array_item(9, &b, n, array, n * 2);
181 test_array_item(17, &b, n, array, n * 3);
182}
183
Harald Weltee61d4592022-11-03 11:05:58 +0100184static void test_used_bytes(void)
Harald Welteae7966d2019-02-03 12:04:46 +0100185{
186 struct bitvec b;
187 uint8_t d[32];
188 unsigned int i;
189
190 b.data = d;
191 b.data_len = sizeof(d);
192 bitvec_zero(&b);
193
194 OSMO_ASSERT(bitvec_used_bytes(&b) == 0);
195
196 for (i = 0; i < 8; i++) {
197 bitvec_set_bit(&b, 1);
198 OSMO_ASSERT(bitvec_used_bytes(&b) == 1);
199 }
200
201 for (i = 8; i < 16; i++) {
202 bitvec_set_bit(&b, 1);
203 OSMO_ASSERT(bitvec_used_bytes(&b) == 2);
204 }
205}
206
Harald Weltee61d4592022-11-03 11:05:58 +0100207static void test_tailroom(void)
Harald Welteb0708d32019-02-04 12:09:05 +0100208{
209 struct bitvec b;
210 uint8_t d[32];
211 unsigned int i;
212
213 b.data = d;
214 b.data_len = sizeof(d);
215 bitvec_zero(&b);
216
217 OSMO_ASSERT(bitvec_tailroom_bits(&b) == sizeof(d)*8);
218
219 for (i = 0; i < 8*sizeof(d); i++) {
220 bitvec_set_bit(&b, 1);
221 OSMO_ASSERT(bitvec_tailroom_bits(&b) == sizeof(d)*8-(i+1));
222 }
223}
224
Vadim Yanitskiy6e270e22020-02-19 05:55:49 +0700225static void test_bitvec_read_field(void)
226{
227 uint8_t data[8] = { 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xeb, 0xda, 0xed };
228 struct bitvec bv = {
229 .data_len = sizeof(data),
230 .data = data,
231 .cur_bit = 0,
232 };
233
234 unsigned int readIndex;
235 uint64_t field;
236
237#define _bitvec_read_field(idx, len) \
238 readIndex = idx; \
239 field = bitvec_read_field(&bv, &readIndex, len); \
Vadim Yanitskiyde3549a2021-11-17 06:34:48 +0300240 printf("bitvec_read_field(idx=%u, len=%u) => %" PRIx64 " (%s)\n", \
241 idx, len, field, errno == 0 ? "success" : "error");
Vadim Yanitskiy6e270e22020-02-19 05:55:49 +0700242
243 _bitvec_read_field(0, 64);
244 _bitvec_read_field(0, 32);
245 _bitvec_read_field(0, 16);
246 _bitvec_read_field(0, 8);
247 _bitvec_read_field(0, 0);
248
249 _bitvec_read_field(8, 8);
250 _bitvec_read_field(8, 4);
251 _bitvec_read_field(8, 0);
252
253 _bitvec_read_field(10, 9);
254 _bitvec_read_field(10, 7);
255 _bitvec_read_field(10, 5);
256 _bitvec_read_field(10, 3);
257 _bitvec_read_field(10, 1);
258
259 /* Out of bounds (see OS#4388) */
260 _bitvec_read_field(8 * 8 * 8, 16); /* index too far */
261 _bitvec_read_field(0, 8 * 8 + 1); /* too many bits */
262 _bitvec_read_field(8 * 8, 16); /* 16 bits past */
263}
264
Jacob Erlbeck5f349be2015-12-21 16:04:03 +0100265int main(int argc, char **argv)
266{
Max0a59e982016-02-05 13:55:37 +0100267 struct bitvec bv;
268 uint8_t i = 8, test[i];
269
270 memset(test, 0, i);
271 bv.data_len = i;
272 bv.data = test;
273 bv.cur_bit = 0;
274
275 printf("test shifting...\n");
276
277 bitvec_set_uint(&bv, 0x0E, 7);
278 test_shift(&bv, 3);
279 test_shift(&bv, 17);
280 bitvec_set_uint(&bv, 0, 32);
281 bitvec_set_uint(&bv, 0x0A, 7);
282 test_shift(&bv, 24);
283
284 printf("checking RL functions...\n");
285
286 bitvec_zero(&bv);
287 test_rl(&bv);
288 bitvec_set_uint(&bv, 0x000F, 32);
289 test_rl(&bv);
290 bitvec_shiftl(&bv, 18);
291 test_rl(&bv);
292 bitvec_set_uint(&bv, 0x0F, 8);
293 test_rl(&bv);
294 bitvec_zero(&bv);
295 bitvec_set_uint(&bv, 0xFF, 8);
296 test_rl(&bv);
297 bitvec_set_uint(&bv, 0xFE, 7);
298 test_rl(&bv);
299 bitvec_set_uint(&bv, 0, 17);
300 test_rl(&bv);
301 bitvec_shiftl(&bv, 18);
302 test_rl(&bv);
303
304 printf("probing bit access...\n");
305
306 bitvec_zero(&bv);
307 bitvec_set_uint(&bv, 0x3747817, 32);
308 bitvec_shiftl(&bv, 10);
309
310 test_get(&bv, 2);
311 test_get(&bv, 7);
312 test_get(&bv, 9);
313 test_get(&bv, 13);
314 test_get(&bv, 16);
315 test_get(&bv, 42);
316
317 printf("feeling bit fills...\n");
318
319 test_set(&bv, ONE);
320 test_fill(&bv, 3, ZERO);
321 test_spare(&bv, 38);
322 test_spare(&bv, 43);
323 test_spare(&bv, 1);
324 test_spare(&bv, 7);
325 test_fill(&bv, 5, ONE);
326 test_fill(&bv, 3, L);
327
328 printf("byte me...\n");
329
Jacob Erlbeck5f349be2015-12-21 16:04:03 +0100330 test_byte_ops();
Holger Hans Peter Freythera9301a12016-01-30 10:54:43 +0100331 test_unhex("48282407a6a074227201000b2b2b2b2b2b2b2b2b2b2b2b");
332 test_unhex("47240c00400000000000000079eb2ac9402b2b2b2b2b2b");
333 test_unhex("47283c367513ba333004242b2b2b2b2b2b2b2b2b2b2b2b");
334 test_unhex("DEADFACE000000000000000000000000000000BEEFFEED");
335 test_unhex("FFFFFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB");
Max0a59e982016-02-05 13:55:37 +0100336
Maxd4793212016-03-17 11:51:08 +0100337 printf("arrr...\n");
338
339 test_array();
340
Pravin Kumarvel848de8f2016-12-02 15:13:03 +0530341 printf("\nbitvec_runlength....\n");
Maxd4793212016-03-17 11:51:08 +0100342
Pravin Kumarvel848de8f2016-12-02 15:13:03 +0530343 bitvec_zero(&bv);
344 bitvec_set_uint(&bv, 0xff, 8);
345 bv.cur_bit -= 8;
346 test_bitvec_rl_curbit(&bv, 1, 64, 8);
347
348 bitvec_zero(&bv);
349 bitvec_set_uint(&bv, 0xfc, 8);
350 bv.cur_bit -= 8;
351 test_bitvec_rl_curbit(&bv, 1, 64, 6);
352
353 bitvec_zero(&bv);
354 test_bitvec_rl_curbit(&bv, 0, 52, 52);
355
356 bitvec_zero(&bv);
357 bitvec_set_uint(&bv, 0xfc, 8);
358 bv.cur_bit -= 2;
359 test_bitvec_rl_curbit(&bv, 0, 64, 58);
360
361 bitvec_zero(&bv);
362 bitvec_set_uint(&bv, 0x07, 8);
363 bitvec_set_uint(&bv, 0xf8, 8);
364 bv.cur_bit -= 11;
365 test_bitvec_rl_curbit(&bv, 1, 64, 8);
366
367 bitvec_zero(&bv);
368 test_bitvec_rl_curbit(&bv, 1, 64, 0);
369
Harald Welteae7966d2019-02-03 12:04:46 +0100370 printf("\nbitvec bytes used.\n");
371 test_used_bytes();
Harald Welteb0708d32019-02-04 12:09:05 +0100372 test_tailroom();
Harald Welteae7966d2019-02-03 12:04:46 +0100373
Vadim Yanitskiy6e270e22020-02-19 05:55:49 +0700374 printf("\ntest bitvec_read_field():\n");
375 test_bitvec_read_field();
376
Pravin Kumarvel848de8f2016-12-02 15:13:03 +0530377 printf("\nbitvec ok.\n");
Jacob Erlbeck5f349be2015-12-21 16:04:03 +0100378 return 0;
379}