blob: 285bec07248e9a17a05f7516c3274aa818f4c38c [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 Walkin7f35fd82013-03-28 03:13:38 -07004#include <per_support.c>
Lev Walkin4eceeba2007-07-23 06:48:26 +00005#include <per_support.h>
6
Lev Walkin523de9e2006-08-18 01:34:18 +00007static void
8check_per_decoding() {
Lev Walkin59b176e2005-11-26 11:25:14 +00009 uint8_t buf[] = { 0xB7, 0x19, 0x2F, 0xEE, 0xAD };
10 uint8_t tmpbuf[10];
11 int32_t z;
12 asn_per_data_t pos;
Lev Walkinfe3dc602007-06-24 08:47:29 +000013 memset(&pos, 0, sizeof(pos));
Lev Walkin59b176e2005-11-26 11:25:14 +000014
15 pos.buffer = buf;
16 pos.nboff = 0;
17 pos.nbits = sizeof(buf) * 8;
18
19 z = per_get_few_bits(&pos, 32);
20 assert(z == -1);
Lev Walkin60364882005-11-28 06:58:11 +000021 assert(pos.nbits == sizeof(buf) * 8);
Lev Walkin59b176e2005-11-26 11:25:14 +000022
23 z = per_get_few_bits(&pos, 0);
24 assert(z == 0);
25 assert(pos.nboff == 0);
Lev Walkin60364882005-11-28 06:58:11 +000026 assert(pos.nbits == sizeof(buf) * 8);
Lev Walkin59b176e2005-11-26 11:25:14 +000027
28 z = per_get_few_bits(&pos, 1);
29 assert(z == 1);
30 assert(pos.nboff == 1);
Lev Walkin60364882005-11-28 06:58:11 +000031 assert(pos.nbits == sizeof(buf) * 8);
Lev Walkin59b176e2005-11-26 11:25:14 +000032
33 z = per_get_few_bits(&pos, 2);
34 assert(z == 1);
35 assert(pos.nboff == 3);
Lev Walkin60364882005-11-28 06:58:11 +000036 assert(pos.nbits == sizeof(buf) * 8);
Lev Walkin59b176e2005-11-26 11:25:14 +000037
38 z = per_get_few_bits(&pos, 2);
39 assert(z == 2);
40 assert(pos.nboff == 5);
Lev Walkin60364882005-11-28 06:58:11 +000041 assert(pos.nbits == sizeof(buf) * 8);
Lev Walkin59b176e2005-11-26 11:25:14 +000042
43 z = per_get_few_bits(&pos, 3);
44 assert(z == 7);
45 assert(pos.nboff == 8);
46 assert(pos.nbits == sizeof(buf) * 8);
47
48 z = per_get_few_bits(&pos, 8);
49 assert(z == 0x19);
50 assert(pos.nboff == 8);
51 assert(pos.nbits == (sizeof(buf) - 1) * 8);
52
53 z = per_get_few_bits(&pos, 1);
54 assert(z == 0);
55 assert(pos.nboff == 1);
56 assert(pos.nbits == (sizeof(buf) - 2) * 8);
57
58 z = per_get_few_bits(&pos, 3);
59 assert(z == 2);
60 assert(pos.nboff == 4);
61 assert(pos.nbits == (sizeof(buf) - 2) * 8);
62
63 z = per_get_few_bits(&pos, 8);
64 assert(z == 254);
65 assert(pos.nboff == 12);
66
67 pos.buffer = buf;
68 pos.nboff = 2;
69 pos.nbits = sizeof(buf) * 8;
70 z = per_get_few_bits(&pos, 24);
71 assert(z == 14443711);
72
Lev Walkind2fab922013-12-07 10:58:10 -080073 pos.buffer = (unsigned char *)"\001";
Lev Walkin7f35fd82013-03-28 03:13:38 -070074 pos.nboff = 7;
75 pos.nbits = 7;
76 z = per_get_few_bits(&pos, 1);
77 assert(pos.nboff == 7);
78 assert(pos.nbits == 7);
79 assert(z == -1);
80
Lev Walkind2fab922013-12-07 10:58:10 -080081 pos.buffer = (unsigned char *)"\001";
Lev Walkin7f35fd82013-03-28 03:13:38 -070082 pos.nboff = 7;
83 pos.nbits = 8;
84 z = per_get_few_bits(&pos, 1);
85 assert(pos.nboff == 8);
86 assert(pos.nbits == 8);
87 assert(z == 1);
88
Lev Walkind2fab922013-12-07 10:58:10 -080089 pos.buffer = (unsigned char *)"\000";
Lev Walkin7f35fd82013-03-28 03:13:38 -070090 pos.nboff = 7;
91 pos.nbits = 8;
92 z = per_get_few_bits(&pos, 1);
93 assert(pos.nboff == 8);
94 assert(pos.nbits == 8);
95 assert(z == 0);
96 z = per_get_few_bits(&pos, 1);
97 assert(pos.nboff == 8);
98 assert(pos.nbits == 8);
99 assert(z == -1);
100
Lev Walkind2fab922013-12-07 10:58:10 -0800101 pos.buffer = (unsigned char *)"\000";
Lev Walkin7f35fd82013-03-28 03:13:38 -0700102 pos.nboff = 7;
103 pos.nbits = 9;
104 z = per_get_few_bits(&pos, 1);
105 assert(pos.nboff == 8);
106 assert(pos.nbits == 9);
107 assert(z == 0);
108 z = per_get_few_bits(&pos, 1);
109 assert(pos.nboff == 1);
110 assert(pos.nbits == 1);
111 assert(z == 0);
112
Lev Walkind2fab922013-12-07 10:58:10 -0800113 pos.buffer = (unsigned char *)"\001";
Lev Walkin7f35fd82013-03-28 03:13:38 -0700114 pos.nboff = 7;
115 pos.nbits = 9;
116 z = per_get_few_bits(&pos, 1);
117 assert(pos.nboff == 8);
118 assert(pos.nbits == 9);
119 assert(z == 1);
120 z = per_get_few_bits(&pos, 1);
121 assert(pos.nboff == 1);
122 assert(pos.nbits == 1);
123 assert(z == 0);
124
Lev Walkin60364882005-11-28 06:58:11 +0000125 /* Get full 31-bit range */
126 pos.buffer = buf;
127 pos.nboff = 7;
128 pos.nbits = sizeof(buf) * 8;
129 z = per_get_few_bits(&pos, 31);
130 assert(z == 1179384747);
131
132 /* Get a bit shifted range */
133 pos.buffer = buf;
134 pos.nboff = 6;
135 pos.nbits = sizeof(buf) * 8;
136 z = per_get_few_bits(&pos, 31);
137 assert(z == 1663434197);
138
Lev Walkin59b176e2005-11-26 11:25:14 +0000139 pos.buffer = buf;
140 pos.nboff = 0;
141 pos.nbits = sizeof(buf) * 8;
142 z = per_get_many_bits(&pos, tmpbuf, 0, sizeof(buf) * 8);
143 assert(z == 0);
144 assert(buf[0] == tmpbuf[0]);
145 assert(buf[1] == tmpbuf[1]);
146 assert(buf[2] == tmpbuf[2]);
147 assert(buf[3] == tmpbuf[3]);
148 assert(buf[4] == tmpbuf[4]);
149
150 pos.buffer = buf;
151 pos.nboff = 1;
152 pos.nbits = sizeof(buf) * 8;
153 z = per_get_many_bits(&pos, tmpbuf, 0, sizeof(buf) * 8);
154 assert(z == -1);
155
156 pos.buffer = buf;
157 pos.nboff = 1;
158 pos.nbits = sizeof(buf) * 8;
159 z = per_get_many_bits(&pos, tmpbuf, 0, sizeof(buf) * 8 - 1);
160 assert(z == 0);
161 assert(tmpbuf[0] == 110);
162 assert(tmpbuf[1] == 50);
163 assert(tmpbuf[2] == 95);
164 assert(tmpbuf[3] == 221);
165 assert(tmpbuf[4] == 90);
166
167 pos.buffer = buf;
168 pos.nboff = 1;
169 pos.nbits = sizeof(buf) * 8;
170 z = per_get_many_bits(&pos, tmpbuf, 1, sizeof(buf) * 8 - 1);
171 assert(z == 0);
172 assert(tmpbuf[0] == 55);
173 assert(tmpbuf[0] != buf[0]);
174 assert(tmpbuf[1] == buf[1]);
175 assert(tmpbuf[2] == buf[2]);
176 assert(tmpbuf[3] == buf[3]);
177 assert(tmpbuf[4] == buf[4]);
Lev Walkin523de9e2006-08-18 01:34:18 +0000178}
Lev Walkin59b176e2005-11-26 11:25:14 +0000179
Lev Walkin523de9e2006-08-18 01:34:18 +0000180static int Ignore(const void *data, size_t size, void *op_key) {
Lev Walkin97363482016-01-24 19:23:02 -0800181 (void)data;
182 (void)size;
183 (void)op_key;
Lev Walkin523de9e2006-08-18 01:34:18 +0000184 return 0;
185}
186
187static void
188check_per_encoding() {
189 asn_per_outp_t po;
Lev Walkin0bcb49d2006-09-18 21:36:30 +0000190 int ret;
191
Lev Walkin523de9e2006-08-18 01:34:18 +0000192 po.buffer = po.tmpspace;
193 po.nboff = 0;
194 po.nbits = 0;
195 po.outper = Ignore;
196 po.op_key = 0;
197 po.tmpspace[0] = 0xff;
Lev Walkin523de9e2006-08-18 01:34:18 +0000198
199 ret = per_put_few_bits(&po, 0, 0);
200 assert(ret == 0);
201 assert(po.nboff == 0);
202 assert(po.buffer == po.tmpspace);
203 assert(po.tmpspace[0] == 0xff);
204
205 ret = per_put_few_bits(&po, 0, 1);
206 assert(ret == 0);
207 assert(po.nboff == 1);
208 assert(po.nbits == 8 * sizeof(po.tmpspace));
209 assert(po.buffer == po.tmpspace);
210 assert(po.tmpspace[0] == 0x00);
211
212 ret = per_put_few_bits(&po, 1, 1);
213 assert(ret == 0);
214 assert(po.nboff == 2);
215 assert(po.nbits == 8 * sizeof(po.tmpspace));
216 assert(po.buffer == po.tmpspace);
217 assert(po.tmpspace[0] == 0x40);
218
219 ret = per_put_few_bits(&po, 1, 1);
220 assert(ret == 0);
221 assert(po.nboff == 3);
222 assert(po.nbits == 8 * sizeof(po.tmpspace));
223 assert(po.buffer == po.tmpspace);
224 assert(po.tmpspace[0] == 0x60);
225
226 ret = per_put_few_bits(&po, 15, 5);
227 assert(ret == 0);
228 assert(po.nboff == 8);
229 assert(po.nbits == 8 * sizeof(po.tmpspace));
230 assert(po.buffer == po.tmpspace);
231 assert(po.tmpspace[0] == 0x6F);
232
233 ret = per_put_few_bits(&po, 0xf0ff, 16);
234 assert(ret == 0);
235 assert(po.nboff == 16);
236 assert(po.nbits == 8 * sizeof(po.tmpspace) - 8);
237 assert(po.buffer == po.tmpspace + 1);
238 assert(po.tmpspace[0] == 0x6F);
239 assert(po.tmpspace[1] == 0xf0);
240 assert(po.tmpspace[2] == 0xff);
241
242 po.nboff--;
243
244 ret = per_put_few_bits(&po, 2, 1);
245 assert(ret == 0);
246 assert(po.nboff == 8);
247 assert(po.nbits == 8 * sizeof(po.tmpspace) - 16);
248 assert(po.buffer == po.tmpspace + 2);
249 assert(po.tmpspace[0] == 0x6F);
250 assert(po.tmpspace[1] == 0xf0);
251 assert(po.tmpspace[2] == 0xfe);
252
253 ret = per_put_few_bits(&po, 2, 32);
254 assert(ret == -1);
255
256 ret = per_put_few_bits(&po, 2, -1);
257 assert(ret == -1);
258
259 ret = per_put_few_bits(&po, -1, 31);
260 assert(ret == 0);
261 assert(po.nboff == 31);
262 assert(po.nbits == 8 * sizeof(po.tmpspace) - 24);
263 assert(po.buffer == po.tmpspace + 3);
264 assert(po.tmpspace[0] == 0x6F);
265 assert(po.tmpspace[1] == 0xf0);
266 assert(po.tmpspace[2] == 0xfe);
267 assert(po.tmpspace[3] == 0xff);
268 assert(po.tmpspace[4] == 0xff);
269 assert(po.tmpspace[5] == 0xff);
270 assert(po.tmpspace[6] == 0xfe);
271
Lev Walkin109ade52010-10-24 20:48:05 -0700272}
Lev Walkin523de9e2006-08-18 01:34:18 +0000273
Lev Walkin15b82432012-01-06 03:19:01 -0800274/*
275 * Add N bits after P bits. Should result in N+P bits added.
276 */
277static void
278check_per_encoding_auto() {
279 int prior, next;
280 int ret, i;
281
282 for(prior = 0; prior <= 31; prior++) {
283 for(next = 0; next <= 31; next++) {
284 asn_per_outp_t po;
285 po.buffer = po.tmpspace;
286 po.nboff = 0;
287 po.nbits = 0;
288 po.outper = Ignore;
289 po.op_key = 0;
290 po.tmpspace[0] = 0xff;
291
292 ret = per_put_few_bits(&po, -1, prior);
293 assert(ret == 0);
294
Lev Walkin15d38f42014-09-17 01:19:31 -0700295 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 -0800296
297 ret = per_put_few_bits(&po, -1, next);
298 assert(ret == 0);
299
Lev Walkin15d38f42014-09-17 01:19:31 -0700300 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 -0800301
Lev Walkin15d38f42014-09-17 01:19:31 -0700302 ASN_DEBUG("Putting %d + %d bits (%d/%d), got %d bytes and %d bits",
Lev Walkin15b82432012-01-06 03:19:01 -0800303 prior, next, (prior + next) / 8, (prior + next) % 8,
304 (int)(po.buffer - po.tmpspace), (int)po.nboff);
Lev Walkin97363482016-01-24 19:23:02 -0800305 assert((po.buffer - po.tmpspace) * 8 + po.nboff == (size_t)(prior + next));
Lev Walkin15b82432012-01-06 03:19:01 -0800306 for(i = 0; i < (po.buffer - po.tmpspace); i++)
307 assert(po.tmpspace[0] == (unsigned char)-1);
308 }
309 }
310}
311
Lev Walkin109ade52010-10-24 20:48:05 -0700312static void
313check_per_encoding_sweep_with(uint8_t buf[], int already_bits, int add_bits) {
314 size_t buf_size = 8;
315 asn_per_data_t pos;
316 asn_per_outp_t out;
317 int32_t d_already;
318 int32_t d_add;
319 int32_t d_left;
320 int left_bits;
Lev Walkin109ade52010-10-24 20:48:05 -0700321
322 memset(&pos, 0, sizeof(pos));
323 pos.buffer = buf;
324 pos.nboff = 0;
325 pos.nbits = buf_size * 8;
326
327 memset(&out, 0, sizeof(out));
328 out.buffer = out.tmpspace;
329 out.nbits = 8 * sizeof(out.tmpspace);
330 assert(sizeof(out.tmpspace) >= buf_size);
331 memcpy(out.buffer, buf, buf_size);
332
333 d_already = per_get_few_bits(&pos, already_bits);
334 d_add = per_get_few_bits(&pos, add_bits);
335
336 per_put_few_bits(&out, d_already, already_bits);
337 per_put_few_bits(&out, d_add, add_bits);
338 if(out.nboff % 8) {
339 left_bits = 8 - (out.nboff % 8);
340 d_left = per_get_few_bits(&pos, left_bits);
341 } else {
342 left_bits = 0;
343 d_left = 0;
344 }
345 per_put_few_bits(&out, d_left, left_bits);
346 assert(0 == (out.nboff % 8));
347
348 if(0 != memcmp(out.tmpspace, buf, buf_size)) {
349 printf("IN: ");
Lev Walkin97363482016-01-24 19:23:02 -0800350 for(size_t i = 0; i < buf_size; i++)
Lev Walkin109ade52010-10-24 20:48:05 -0700351 printf(" %02x", buf[i]);
352 printf("\nOUT:");
Lev Walkin97363482016-01-24 19:23:02 -0800353 for(size_t i = 0; i < buf_size; i++)
Lev Walkin109ade52010-10-24 20:48:05 -0700354 printf(" %02x", out.tmpspace[i]);
355 printf(" (out{nboff=%d,left=%d,%02x})\n", (int)out.nboff, left_bits, (int)d_left);
356 assert(0 == memcmp(out.tmpspace, buf, buf_size));
357 }
358}
359
360static void
361check_per_encoding_sweep() {
362 uint8_t buf[3][8] = {
363 { 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA },
364 { 0xB7, 0x19, 0x2F, 0xEE, 0xAD, 0x11, 0xAA, 0x55 },
365 { 0xEE, 0xAD, 0x11, 0xAA, 0x55, 0xB7, 0x19, 0x2F }
366 };
367 int already_bits;
368 int add_bits;
369 int buf_idx;
370
371 for(buf_idx = 0; buf_idx < 3; buf_idx++) {
372 for(already_bits = 0; already_bits < 24; already_bits++) {
373 for(add_bits = 0; add_bits <= 31; add_bits++) {
374 /*fprintf(stderr, "PER %d += %d\n", already_bits, add_bits);*/
375 check_per_encoding_sweep_with(buf[buf_idx], already_bits, add_bits);
376 }
377 }
378 }
Lev Walkin523de9e2006-08-18 01:34:18 +0000379}
380
381int
382main() {
383 check_per_decoding();
384 check_per_encoding();
Lev Walkin15b82432012-01-06 03:19:01 -0800385 check_per_encoding_auto();
Lev Walkin109ade52010-10-24 20:48:05 -0700386 check_per_encoding_sweep();
Lev Walkin59b176e2005-11-26 11:25:14 +0000387 return 0;
388}