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