blob: 9fc025896156913807f150b4fc0b4b6e2be4c587 [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#define EMIT_ASN_DEBUG 1
5#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 Walkin7f35fd82013-03-28 03:13:38 -070074 pos.buffer = "\001";
75 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
82 pos.buffer = "\001";
83 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
90 pos.buffer = "\000";
91 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
102 pos.buffer = "\000";
103 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
114 pos.buffer = "\001";
115 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) {
182 return 0;
183}
184
185static void
186check_per_encoding() {
187 asn_per_outp_t po;
Lev Walkin0bcb49d2006-09-18 21:36:30 +0000188 int ret;
189
Lev Walkin523de9e2006-08-18 01:34:18 +0000190 po.buffer = po.tmpspace;
191 po.nboff = 0;
192 po.nbits = 0;
193 po.outper = Ignore;
194 po.op_key = 0;
195 po.tmpspace[0] = 0xff;
Lev Walkin523de9e2006-08-18 01:34:18 +0000196
197 ret = per_put_few_bits(&po, 0, 0);
198 assert(ret == 0);
199 assert(po.nboff == 0);
200 assert(po.buffer == po.tmpspace);
201 assert(po.tmpspace[0] == 0xff);
202
203 ret = per_put_few_bits(&po, 0, 1);
204 assert(ret == 0);
205 assert(po.nboff == 1);
206 assert(po.nbits == 8 * sizeof(po.tmpspace));
207 assert(po.buffer == po.tmpspace);
208 assert(po.tmpspace[0] == 0x00);
209
210 ret = per_put_few_bits(&po, 1, 1);
211 assert(ret == 0);
212 assert(po.nboff == 2);
213 assert(po.nbits == 8 * sizeof(po.tmpspace));
214 assert(po.buffer == po.tmpspace);
215 assert(po.tmpspace[0] == 0x40);
216
217 ret = per_put_few_bits(&po, 1, 1);
218 assert(ret == 0);
219 assert(po.nboff == 3);
220 assert(po.nbits == 8 * sizeof(po.tmpspace));
221 assert(po.buffer == po.tmpspace);
222 assert(po.tmpspace[0] == 0x60);
223
224 ret = per_put_few_bits(&po, 15, 5);
225 assert(ret == 0);
226 assert(po.nboff == 8);
227 assert(po.nbits == 8 * sizeof(po.tmpspace));
228 assert(po.buffer == po.tmpspace);
229 assert(po.tmpspace[0] == 0x6F);
230
231 ret = per_put_few_bits(&po, 0xf0ff, 16);
232 assert(ret == 0);
233 assert(po.nboff == 16);
234 assert(po.nbits == 8 * sizeof(po.tmpspace) - 8);
235 assert(po.buffer == po.tmpspace + 1);
236 assert(po.tmpspace[0] == 0x6F);
237 assert(po.tmpspace[1] == 0xf0);
238 assert(po.tmpspace[2] == 0xff);
239
240 po.nboff--;
241
242 ret = per_put_few_bits(&po, 2, 1);
243 assert(ret == 0);
244 assert(po.nboff == 8);
245 assert(po.nbits == 8 * sizeof(po.tmpspace) - 16);
246 assert(po.buffer == po.tmpspace + 2);
247 assert(po.tmpspace[0] == 0x6F);
248 assert(po.tmpspace[1] == 0xf0);
249 assert(po.tmpspace[2] == 0xfe);
250
251 ret = per_put_few_bits(&po, 2, 32);
252 assert(ret == -1);
253
254 ret = per_put_few_bits(&po, 2, -1);
255 assert(ret == -1);
256
257 ret = per_put_few_bits(&po, -1, 31);
258 assert(ret == 0);
259 assert(po.nboff == 31);
260 assert(po.nbits == 8 * sizeof(po.tmpspace) - 24);
261 assert(po.buffer == po.tmpspace + 3);
262 assert(po.tmpspace[0] == 0x6F);
263 assert(po.tmpspace[1] == 0xf0);
264 assert(po.tmpspace[2] == 0xfe);
265 assert(po.tmpspace[3] == 0xff);
266 assert(po.tmpspace[4] == 0xff);
267 assert(po.tmpspace[5] == 0xff);
268 assert(po.tmpspace[6] == 0xfe);
269
Lev Walkin109ade52010-10-24 20:48:05 -0700270}
Lev Walkin523de9e2006-08-18 01:34:18 +0000271
Lev Walkin15b82432012-01-06 03:19:01 -0800272/*
273 * Add N bits after P bits. Should result in N+P bits added.
274 */
275static void
276check_per_encoding_auto() {
277 int prior, next;
278 int ret, i;
279
280 for(prior = 0; prior <= 31; prior++) {
281 for(next = 0; next <= 31; next++) {
282 asn_per_outp_t po;
283 po.buffer = po.tmpspace;
284 po.nboff = 0;
285 po.nbits = 0;
286 po.outper = Ignore;
287 po.op_key = 0;
288 po.tmpspace[0] = 0xff;
289
290 ret = per_put_few_bits(&po, -1, prior);
291 assert(ret == 0);
292
293 fprintf(stderr, " (out{nboff=%d,nbits=%d,buf_offset=%d})\n", (int)po.nboff, (int)po.nbits, (int)(po.buffer - po.tmpspace));
294
295 ret = per_put_few_bits(&po, -1, next);
296 assert(ret == 0);
297
298 fprintf(stderr, " (out{nboff=%d,nbits=%d,buf_offset=%d})\n", (int)po.nboff, (int)po.nbits, (int)(po.buffer - po.tmpspace));
299
300 fprintf(stderr, "Putting %d + %d bits (%d/%d), got %d bytes and %d bits\n",
301 prior, next, (prior + next) / 8, (prior + next) % 8,
302 (int)(po.buffer - po.tmpspace), (int)po.nboff);
303 assert((po.buffer - po.tmpspace) * 8 + po.nboff == prior + next);
304 for(i = 0; i < (po.buffer - po.tmpspace); i++)
305 assert(po.tmpspace[0] == (unsigned char)-1);
306 }
307 }
308}
309
Lev Walkin109ade52010-10-24 20:48:05 -0700310static void
311check_per_encoding_sweep_with(uint8_t buf[], int already_bits, int add_bits) {
312 size_t buf_size = 8;
313 asn_per_data_t pos;
314 asn_per_outp_t out;
315 int32_t d_already;
316 int32_t d_add;
317 int32_t d_left;
318 int left_bits;
319 int i;
320
321 memset(&pos, 0, sizeof(pos));
322 pos.buffer = buf;
323 pos.nboff = 0;
324 pos.nbits = buf_size * 8;
325
326 memset(&out, 0, sizeof(out));
327 out.buffer = out.tmpspace;
328 out.nbits = 8 * sizeof(out.tmpspace);
329 assert(sizeof(out.tmpspace) >= buf_size);
330 memcpy(out.buffer, buf, buf_size);
331
332 d_already = per_get_few_bits(&pos, already_bits);
333 d_add = per_get_few_bits(&pos, add_bits);
334
335 per_put_few_bits(&out, d_already, already_bits);
336 per_put_few_bits(&out, d_add, add_bits);
337 if(out.nboff % 8) {
338 left_bits = 8 - (out.nboff % 8);
339 d_left = per_get_few_bits(&pos, left_bits);
340 } else {
341 left_bits = 0;
342 d_left = 0;
343 }
344 per_put_few_bits(&out, d_left, left_bits);
345 assert(0 == (out.nboff % 8));
346
347 if(0 != memcmp(out.tmpspace, buf, buf_size)) {
348 printf("IN: ");
349 for(i = 0; i < buf_size; i++)
350 printf(" %02x", buf[i]);
351 printf("\nOUT:");
352 for(i = 0; i < buf_size; i++)
353 printf(" %02x", out.tmpspace[i]);
354 printf(" (out{nboff=%d,left=%d,%02x})\n", (int)out.nboff, left_bits, (int)d_left);
355 assert(0 == memcmp(out.tmpspace, buf, buf_size));
356 }
357}
358
359static void
360check_per_encoding_sweep() {
361 uint8_t buf[3][8] = {
362 { 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA },
363 { 0xB7, 0x19, 0x2F, 0xEE, 0xAD, 0x11, 0xAA, 0x55 },
364 { 0xEE, 0xAD, 0x11, 0xAA, 0x55, 0xB7, 0x19, 0x2F }
365 };
366 int already_bits;
367 int add_bits;
368 int buf_idx;
369
370 for(buf_idx = 0; buf_idx < 3; buf_idx++) {
371 for(already_bits = 0; already_bits < 24; already_bits++) {
372 for(add_bits = 0; add_bits <= 31; add_bits++) {
373 /*fprintf(stderr, "PER %d += %d\n", already_bits, add_bits);*/
374 check_per_encoding_sweep_with(buf[buf_idx], already_bits, add_bits);
375 }
376 }
377 }
Lev Walkin523de9e2006-08-18 01:34:18 +0000378}
379
380int
381main() {
382 check_per_decoding();
383 check_per_encoding();
Lev Walkin15b82432012-01-06 03:19:01 -0800384 check_per_encoding_auto();
Lev Walkin109ade52010-10-24 20:48:05 -0700385 check_per_encoding_sweep();
Lev Walkin59b176e2005-11-26 11:25:14 +0000386 return 0;
387}