blob: 8f629f3c45abe196a2a78ef7dfa6be39e9684e99 [file] [log] [blame]
Lev Walkin4eceeba2007-07-23 06:48:26 +00001#include <stdio.h>
Lev Walkin59b176e2005-11-26 11:25:14 +00002#include <assert.h>
3
Lev Walkin6cd0d562017-08-25 11:57:01 -07004#include <asn_bit_data.c>
Lev Walkin7f35fd82013-03-28 03:13:38 -07005#include <per_support.c>
Lev Walkin4eceeba2007-07-23 06:48:26 +00006#include <per_support.h>
7
Lev Walkin523de9e2006-08-18 01:34:18 +00008static void
9check_per_decoding() {
Lev Walkin59b176e2005-11-26 11:25:14 +000010 uint8_t buf[] = { 0xB7, 0x19, 0x2F, 0xEE, 0xAD };
11 uint8_t tmpbuf[10];
12 int32_t z;
13 asn_per_data_t pos;
Lev Walkinfe3dc602007-06-24 08:47:29 +000014 memset(&pos, 0, sizeof(pos));
Lev Walkin59b176e2005-11-26 11:25:14 +000015
16 pos.buffer = buf;
17 pos.nboff = 0;
18 pos.nbits = sizeof(buf) * 8;
19
20 z = per_get_few_bits(&pos, 32);
21 assert(z == -1);
Lev Walkin60364882005-11-28 06:58:11 +000022 assert(pos.nbits == sizeof(buf) * 8);
Lev Walkin59b176e2005-11-26 11:25:14 +000023
24 z = per_get_few_bits(&pos, 0);
25 assert(z == 0);
26 assert(pos.nboff == 0);
Lev Walkin60364882005-11-28 06:58:11 +000027 assert(pos.nbits == sizeof(buf) * 8);
Lev Walkin59b176e2005-11-26 11:25:14 +000028
29 z = per_get_few_bits(&pos, 1);
30 assert(z == 1);
31 assert(pos.nboff == 1);
Lev Walkin60364882005-11-28 06:58:11 +000032 assert(pos.nbits == sizeof(buf) * 8);
Lev Walkin59b176e2005-11-26 11:25:14 +000033
34 z = per_get_few_bits(&pos, 2);
35 assert(z == 1);
36 assert(pos.nboff == 3);
Lev Walkin60364882005-11-28 06:58:11 +000037 assert(pos.nbits == sizeof(buf) * 8);
Lev Walkin59b176e2005-11-26 11:25:14 +000038
39 z = per_get_few_bits(&pos, 2);
40 assert(z == 2);
41 assert(pos.nboff == 5);
Lev Walkin60364882005-11-28 06:58:11 +000042 assert(pos.nbits == sizeof(buf) * 8);
Lev Walkin59b176e2005-11-26 11:25:14 +000043
44 z = per_get_few_bits(&pos, 3);
45 assert(z == 7);
46 assert(pos.nboff == 8);
47 assert(pos.nbits == sizeof(buf) * 8);
48
49 z = per_get_few_bits(&pos, 8);
50 assert(z == 0x19);
51 assert(pos.nboff == 8);
52 assert(pos.nbits == (sizeof(buf) - 1) * 8);
53
54 z = per_get_few_bits(&pos, 1);
55 assert(z == 0);
56 assert(pos.nboff == 1);
57 assert(pos.nbits == (sizeof(buf) - 2) * 8);
58
59 z = per_get_few_bits(&pos, 3);
60 assert(z == 2);
61 assert(pos.nboff == 4);
62 assert(pos.nbits == (sizeof(buf) - 2) * 8);
63
64 z = per_get_few_bits(&pos, 8);
65 assert(z == 254);
66 assert(pos.nboff == 12);
67
68 pos.buffer = buf;
69 pos.nboff = 2;
70 pos.nbits = sizeof(buf) * 8;
71 z = per_get_few_bits(&pos, 24);
72 assert(z == 14443711);
73
Lev Walkind2fab922013-12-07 10:58:10 -080074 pos.buffer = (unsigned char *)"\001";
Lev Walkin7f35fd82013-03-28 03:13:38 -070075 pos.nboff = 7;
76 pos.nbits = 7;
77 z = per_get_few_bits(&pos, 1);
78 assert(pos.nboff == 7);
79 assert(pos.nbits == 7);
80 assert(z == -1);
81
Lev Walkind2fab922013-12-07 10:58:10 -080082 pos.buffer = (unsigned char *)"\001";
Lev Walkin7f35fd82013-03-28 03:13:38 -070083 pos.nboff = 7;
84 pos.nbits = 8;
85 z = per_get_few_bits(&pos, 1);
86 assert(pos.nboff == 8);
87 assert(pos.nbits == 8);
88 assert(z == 1);
89
Lev Walkind2fab922013-12-07 10:58:10 -080090 pos.buffer = (unsigned char *)"\000";
Lev Walkin7f35fd82013-03-28 03:13:38 -070091 pos.nboff = 7;
92 pos.nbits = 8;
93 z = per_get_few_bits(&pos, 1);
94 assert(pos.nboff == 8);
95 assert(pos.nbits == 8);
96 assert(z == 0);
97 z = per_get_few_bits(&pos, 1);
98 assert(pos.nboff == 8);
99 assert(pos.nbits == 8);
100 assert(z == -1);
101
Lev Walkind2fab922013-12-07 10:58:10 -0800102 pos.buffer = (unsigned char *)"\000";
Lev Walkin7f35fd82013-03-28 03:13:38 -0700103 pos.nboff = 7;
104 pos.nbits = 9;
105 z = per_get_few_bits(&pos, 1);
106 assert(pos.nboff == 8);
107 assert(pos.nbits == 9);
108 assert(z == 0);
109 z = per_get_few_bits(&pos, 1);
110 assert(pos.nboff == 1);
111 assert(pos.nbits == 1);
112 assert(z == 0);
113
Lev Walkind2fab922013-12-07 10:58:10 -0800114 pos.buffer = (unsigned char *)"\001";
Lev Walkin7f35fd82013-03-28 03:13:38 -0700115 pos.nboff = 7;
116 pos.nbits = 9;
117 z = per_get_few_bits(&pos, 1);
118 assert(pos.nboff == 8);
119 assert(pos.nbits == 9);
120 assert(z == 1);
121 z = per_get_few_bits(&pos, 1);
122 assert(pos.nboff == 1);
123 assert(pos.nbits == 1);
124 assert(z == 0);
125
Lev Walkin60364882005-11-28 06:58:11 +0000126 /* Get full 31-bit range */
127 pos.buffer = buf;
128 pos.nboff = 7;
129 pos.nbits = sizeof(buf) * 8;
130 z = per_get_few_bits(&pos, 31);
131 assert(z == 1179384747);
132
133 /* Get a bit shifted range */
134 pos.buffer = buf;
135 pos.nboff = 6;
136 pos.nbits = sizeof(buf) * 8;
137 z = per_get_few_bits(&pos, 31);
138 assert(z == 1663434197);
139
Lev Walkin59b176e2005-11-26 11:25:14 +0000140 pos.buffer = buf;
141 pos.nboff = 0;
142 pos.nbits = sizeof(buf) * 8;
143 z = per_get_many_bits(&pos, tmpbuf, 0, sizeof(buf) * 8);
144 assert(z == 0);
145 assert(buf[0] == tmpbuf[0]);
146 assert(buf[1] == tmpbuf[1]);
147 assert(buf[2] == tmpbuf[2]);
148 assert(buf[3] == tmpbuf[3]);
149 assert(buf[4] == tmpbuf[4]);
150
151 pos.buffer = buf;
152 pos.nboff = 1;
153 pos.nbits = sizeof(buf) * 8;
154 z = per_get_many_bits(&pos, tmpbuf, 0, sizeof(buf) * 8);
155 assert(z == -1);
156
157 pos.buffer = buf;
158 pos.nboff = 1;
159 pos.nbits = sizeof(buf) * 8;
160 z = per_get_many_bits(&pos, tmpbuf, 0, sizeof(buf) * 8 - 1);
161 assert(z == 0);
162 assert(tmpbuf[0] == 110);
163 assert(tmpbuf[1] == 50);
164 assert(tmpbuf[2] == 95);
165 assert(tmpbuf[3] == 221);
166 assert(tmpbuf[4] == 90);
167
168 pos.buffer = buf;
169 pos.nboff = 1;
170 pos.nbits = sizeof(buf) * 8;
171 z = per_get_many_bits(&pos, tmpbuf, 1, sizeof(buf) * 8 - 1);
172 assert(z == 0);
173 assert(tmpbuf[0] == 55);
174 assert(tmpbuf[0] != buf[0]);
175 assert(tmpbuf[1] == buf[1]);
176 assert(tmpbuf[2] == buf[2]);
177 assert(tmpbuf[3] == buf[3]);
178 assert(tmpbuf[4] == buf[4]);
Lev Walkin523de9e2006-08-18 01:34:18 +0000179}
Lev Walkin59b176e2005-11-26 11:25:14 +0000180
Lev Walkin523de9e2006-08-18 01:34:18 +0000181static int Ignore(const void *data, size_t size, void *op_key) {
Lev Walkin97363482016-01-24 19:23:02 -0800182 (void)data;
183 (void)size;
184 (void)op_key;
Lev Walkin523de9e2006-08-18 01:34:18 +0000185 return 0;
186}
187
188static void
189check_per_encoding() {
190 asn_per_outp_t po;
Lev Walkin0bcb49d2006-09-18 21:36:30 +0000191 int ret;
192
Lev Walkin523de9e2006-08-18 01:34:18 +0000193 po.buffer = po.tmpspace;
194 po.nboff = 0;
195 po.nbits = 0;
Lev Walkin6cd0d562017-08-25 11:57:01 -0700196 po.output = Ignore;
Lev Walkin523de9e2006-08-18 01:34:18 +0000197 po.op_key = 0;
198 po.tmpspace[0] = 0xff;
Lev Walkin523de9e2006-08-18 01:34:18 +0000199
200 ret = per_put_few_bits(&po, 0, 0);
201 assert(ret == 0);
202 assert(po.nboff == 0);
203 assert(po.buffer == po.tmpspace);
204 assert(po.tmpspace[0] == 0xff);
205
206 ret = per_put_few_bits(&po, 0, 1);
207 assert(ret == 0);
208 assert(po.nboff == 1);
209 assert(po.nbits == 8 * sizeof(po.tmpspace));
210 assert(po.buffer == po.tmpspace);
211 assert(po.tmpspace[0] == 0x00);
212
213 ret = per_put_few_bits(&po, 1, 1);
214 assert(ret == 0);
215 assert(po.nboff == 2);
216 assert(po.nbits == 8 * sizeof(po.tmpspace));
217 assert(po.buffer == po.tmpspace);
218 assert(po.tmpspace[0] == 0x40);
219
220 ret = per_put_few_bits(&po, 1, 1);
221 assert(ret == 0);
222 assert(po.nboff == 3);
223 assert(po.nbits == 8 * sizeof(po.tmpspace));
224 assert(po.buffer == po.tmpspace);
225 assert(po.tmpspace[0] == 0x60);
226
227 ret = per_put_few_bits(&po, 15, 5);
228 assert(ret == 0);
229 assert(po.nboff == 8);
230 assert(po.nbits == 8 * sizeof(po.tmpspace));
231 assert(po.buffer == po.tmpspace);
232 assert(po.tmpspace[0] == 0x6F);
233
234 ret = per_put_few_bits(&po, 0xf0ff, 16);
235 assert(ret == 0);
236 assert(po.nboff == 16);
237 assert(po.nbits == 8 * sizeof(po.tmpspace) - 8);
238 assert(po.buffer == po.tmpspace + 1);
239 assert(po.tmpspace[0] == 0x6F);
240 assert(po.tmpspace[1] == 0xf0);
241 assert(po.tmpspace[2] == 0xff);
242
243 po.nboff--;
244
245 ret = per_put_few_bits(&po, 2, 1);
246 assert(ret == 0);
247 assert(po.nboff == 8);
248 assert(po.nbits == 8 * sizeof(po.tmpspace) - 16);
249 assert(po.buffer == po.tmpspace + 2);
250 assert(po.tmpspace[0] == 0x6F);
251 assert(po.tmpspace[1] == 0xf0);
252 assert(po.tmpspace[2] == 0xfe);
253
254 ret = per_put_few_bits(&po, 2, 32);
255 assert(ret == -1);
256
257 ret = per_put_few_bits(&po, 2, -1);
258 assert(ret == -1);
259
260 ret = per_put_few_bits(&po, -1, 31);
261 assert(ret == 0);
262 assert(po.nboff == 31);
263 assert(po.nbits == 8 * sizeof(po.tmpspace) - 24);
264 assert(po.buffer == po.tmpspace + 3);
265 assert(po.tmpspace[0] == 0x6F);
266 assert(po.tmpspace[1] == 0xf0);
267 assert(po.tmpspace[2] == 0xfe);
268 assert(po.tmpspace[3] == 0xff);
269 assert(po.tmpspace[4] == 0xff);
270 assert(po.tmpspace[5] == 0xff);
271 assert(po.tmpspace[6] == 0xfe);
272
Lev Walkin109ade52010-10-24 20:48:05 -0700273}
Lev Walkin523de9e2006-08-18 01:34:18 +0000274
Lev Walkin15b82432012-01-06 03:19:01 -0800275/*
276 * Add N bits after P bits. Should result in N+P bits added.
277 */
278static void
279check_per_encoding_auto() {
280 int prior, next;
281 int ret, i;
282
283 for(prior = 0; prior <= 31; prior++) {
284 for(next = 0; next <= 31; next++) {
285 asn_per_outp_t po;
286 po.buffer = po.tmpspace;
287 po.nboff = 0;
288 po.nbits = 0;
Lev Walkin6cd0d562017-08-25 11:57:01 -0700289 po.output = Ignore;
Lev Walkin15b82432012-01-06 03:19:01 -0800290 po.op_key = 0;
291 po.tmpspace[0] = 0xff;
292
293 ret = per_put_few_bits(&po, -1, prior);
294 assert(ret == 0);
295
Lev Walkin15d38f42014-09-17 01:19:31 -0700296 ASN_DEBUG(" (out{nboff=%d,nbits=%d,buf_offset=%d})", (int)po.nboff, (int)po.nbits, (int)(po.buffer - po.tmpspace));
Lev Walkin15b82432012-01-06 03:19:01 -0800297
298 ret = per_put_few_bits(&po, -1, next);
299 assert(ret == 0);
300
Lev Walkin15d38f42014-09-17 01:19:31 -0700301 ASN_DEBUG(" (out{nboff=%d,nbits=%d,buf_offset=%d})", (int)po.nboff, (int)po.nbits, (int)(po.buffer - po.tmpspace));
Lev Walkin15b82432012-01-06 03:19:01 -0800302
Lev Walkin15d38f42014-09-17 01:19:31 -0700303 ASN_DEBUG("Putting %d + %d bits (%d/%d), got %d bytes and %d bits",
Lev Walkin15b82432012-01-06 03:19:01 -0800304 prior, next, (prior + next) / 8, (prior + next) % 8,
305 (int)(po.buffer - po.tmpspace), (int)po.nboff);
Lev Walkin97363482016-01-24 19:23:02 -0800306 assert((po.buffer - po.tmpspace) * 8 + po.nboff == (size_t)(prior + next));
Lev Walkin15b82432012-01-06 03:19:01 -0800307 for(i = 0; i < (po.buffer - po.tmpspace); i++)
308 assert(po.tmpspace[0] == (unsigned char)-1);
309 }
310 }
311}
312
Lev Walkin109ade52010-10-24 20:48:05 -0700313static void
314check_per_encoding_sweep_with(uint8_t buf[], int already_bits, int add_bits) {
315 size_t buf_size = 8;
316 asn_per_data_t pos;
317 asn_per_outp_t out;
318 int32_t d_already;
319 int32_t d_add;
320 int32_t d_left;
321 int left_bits;
Lev Walkin109ade52010-10-24 20:48:05 -0700322
323 memset(&pos, 0, sizeof(pos));
324 pos.buffer = buf;
325 pos.nboff = 0;
326 pos.nbits = buf_size * 8;
327
328 memset(&out, 0, sizeof(out));
329 out.buffer = out.tmpspace;
330 out.nbits = 8 * sizeof(out.tmpspace);
331 assert(sizeof(out.tmpspace) >= buf_size);
332 memcpy(out.buffer, buf, buf_size);
333
334 d_already = per_get_few_bits(&pos, already_bits);
335 d_add = per_get_few_bits(&pos, add_bits);
336
337 per_put_few_bits(&out, d_already, already_bits);
338 per_put_few_bits(&out, d_add, add_bits);
339 if(out.nboff % 8) {
340 left_bits = 8 - (out.nboff % 8);
341 d_left = per_get_few_bits(&pos, left_bits);
342 } else {
343 left_bits = 0;
344 d_left = 0;
345 }
346 per_put_few_bits(&out, d_left, left_bits);
347 assert(0 == (out.nboff % 8));
348
349 if(0 != memcmp(out.tmpspace, buf, buf_size)) {
350 printf("IN: ");
Lev Walkin97363482016-01-24 19:23:02 -0800351 for(size_t i = 0; i < buf_size; i++)
Lev Walkin109ade52010-10-24 20:48:05 -0700352 printf(" %02x", buf[i]);
353 printf("\nOUT:");
Lev Walkin97363482016-01-24 19:23:02 -0800354 for(size_t i = 0; i < buf_size; i++)
Lev Walkin109ade52010-10-24 20:48:05 -0700355 printf(" %02x", out.tmpspace[i]);
356 printf(" (out{nboff=%d,left=%d,%02x})\n", (int)out.nboff, left_bits, (int)d_left);
357 assert(0 == memcmp(out.tmpspace, buf, buf_size));
358 }
359}
360
361static void
362check_per_encoding_sweep() {
363 uint8_t buf[3][8] = {
364 { 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA },
365 { 0xB7, 0x19, 0x2F, 0xEE, 0xAD, 0x11, 0xAA, 0x55 },
366 { 0xEE, 0xAD, 0x11, 0xAA, 0x55, 0xB7, 0x19, 0x2F }
367 };
368 int already_bits;
369 int add_bits;
370 int buf_idx;
371
372 for(buf_idx = 0; buf_idx < 3; buf_idx++) {
373 for(already_bits = 0; already_bits < 24; already_bits++) {
374 for(add_bits = 0; add_bits <= 31; add_bits++) {
375 /*fprintf(stderr, "PER %d += %d\n", already_bits, add_bits);*/
376 check_per_encoding_sweep_with(buf[buf_idx], already_bits, add_bits);
377 }
378 }
379 }
Lev Walkin523de9e2006-08-18 01:34:18 +0000380}
381
382int
383main() {
384 check_per_decoding();
385 check_per_encoding();
Lev Walkin15b82432012-01-06 03:19:01 -0800386 check_per_encoding_auto();
Lev Walkin109ade52010-10-24 20:48:05 -0700387 check_per_encoding_sweep();
Lev Walkin59b176e2005-11-26 11:25:14 +0000388 return 0;
389}