950a3e817ef3b0285b746eb37ce3de3d76802fac
[com/asn1c.git] / tests / tests-skeletons / check-bits.c
1 #include <stdio.h>
2 #include <assert.h>
3
4 #include <asn_bit_data.c>
5
6 static void
7 check_asn_bits_decoding() {
8         uint8_t buf[] = { 0xB7, 0x19, 0x2F, 0xEE, 0xAD };
9         uint8_t tmpbuf[10];
10         int32_t z;
11         asn_bit_data_t pos;
12         memset(&pos, 0, sizeof(pos));
13
14         pos.buffer = buf;
15         pos.nboff = 0;
16         pos.nbits = sizeof(buf) * 8;
17
18         z = asn_get_few_bits(&pos, 32);
19         assert(z == -1);
20         assert(pos.nbits == sizeof(buf) * 8);
21
22         z = asn_get_few_bits(&pos, 0);
23         assert(z == 0);
24         assert(pos.nboff == 0);
25         assert(pos.nbits == sizeof(buf) * 8);
26
27         z = asn_get_few_bits(&pos, 1);
28         assert(z == 1);
29         assert(pos.nboff == 1);
30         assert(pos.nbits == sizeof(buf) * 8);
31
32         z = asn_get_few_bits(&pos, 2);
33         assert(z == 1);
34         assert(pos.nboff == 3);
35         assert(pos.nbits == sizeof(buf) * 8);
36
37         z = asn_get_few_bits(&pos, 2);
38         assert(z == 2);
39         assert(pos.nboff == 5);
40         assert(pos.nbits == sizeof(buf) * 8);
41
42         z = asn_get_few_bits(&pos, 3);
43         assert(z == 7);
44         assert(pos.nboff == 8);
45         assert(pos.nbits == sizeof(buf) * 8);
46
47         z = asn_get_few_bits(&pos, 8);
48         assert(z == 0x19);
49         assert(pos.nboff == 8);
50         assert(pos.nbits == (sizeof(buf) - 1) * 8);
51
52         z = asn_get_few_bits(&pos, 1);
53         assert(z == 0);
54         assert(pos.nboff == 1);
55         assert(pos.nbits == (sizeof(buf) - 2) * 8);
56
57         z = asn_get_few_bits(&pos, 3);
58         assert(z == 2);
59         assert(pos.nboff == 4);
60         assert(pos.nbits == (sizeof(buf) - 2) * 8);
61
62         z = asn_get_few_bits(&pos, 8);
63         assert(z == 254);
64         assert(pos.nboff == 12);
65
66         pos.buffer = buf;
67         pos.nboff = 2;
68         pos.nbits = sizeof(buf) * 8;
69         z = asn_get_few_bits(&pos, 24);
70         assert(z == 14443711);
71
72         pos.buffer = (unsigned char *)"\001";
73         pos.nboff = 7;
74         pos.nbits = 7;
75         z = asn_get_few_bits(&pos, 1);
76         assert(pos.nboff == 7);
77         assert(pos.nbits == 7);
78         assert(z == -1);
79
80         pos.buffer = (unsigned char *)"\001";
81         pos.nboff = 7;
82         pos.nbits = 8;
83         z = asn_get_few_bits(&pos, 1);
84         assert(pos.nboff == 8);
85         assert(pos.nbits == 8);
86         assert(z == 1);
87
88         pos.buffer = (unsigned char *)"\000";
89         pos.nboff = 7;
90         pos.nbits = 8;
91         z = asn_get_few_bits(&pos, 1);
92         assert(pos.nboff == 8);
93         assert(pos.nbits == 8);
94         assert(z == 0);
95         z = asn_get_few_bits(&pos, 1);
96         assert(pos.nboff == 8);
97         assert(pos.nbits == 8);
98         assert(z == -1);
99
100         pos.buffer = (unsigned char *)"\000";
101         pos.nboff = 7;
102         pos.nbits = 9;
103         z = asn_get_few_bits(&pos, 1);
104         assert(pos.nboff == 8);
105         assert(pos.nbits == 9);
106         assert(z == 0);
107         z = asn_get_few_bits(&pos, 1);
108         assert(pos.nboff == 1);
109         assert(pos.nbits == 1);
110         assert(z == 0);
111
112         pos.buffer = (unsigned char *)"\001";
113         pos.nboff = 7;
114         pos.nbits = 9;
115         z = asn_get_few_bits(&pos, 1);
116         assert(pos.nboff == 8);
117         assert(pos.nbits == 9);
118         assert(z == 1);
119         z = asn_get_few_bits(&pos, 1);
120         assert(pos.nboff == 1);
121         assert(pos.nbits == 1);
122         assert(z == 0);
123
124         /* Get full 31-bit range */
125         pos.buffer = buf;
126         pos.nboff = 7;
127         pos.nbits = sizeof(buf) * 8;
128         z = asn_get_few_bits(&pos, 31);
129         assert(z == 1179384747);
130
131         /* Get a bit shifted range */
132         pos.buffer = buf;
133         pos.nboff = 6;
134         pos.nbits = sizeof(buf) * 8;
135         z = asn_get_few_bits(&pos, 31);
136         assert(z == 1663434197);
137
138         pos.buffer = buf;
139         pos.nboff = 0;
140         pos.nbits = sizeof(buf) * 8;
141         z = asn_get_many_bits(&pos, tmpbuf, 0, sizeof(buf) * 8);
142         assert(z == 0);
143         assert(buf[0] == tmpbuf[0]);
144         assert(buf[1] == tmpbuf[1]);
145         assert(buf[2] == tmpbuf[2]);
146         assert(buf[3] == tmpbuf[3]);
147         assert(buf[4] == tmpbuf[4]);
148
149         pos.buffer = buf;
150         pos.nboff = 1;
151         pos.nbits = sizeof(buf) * 8;
152         z = asn_get_many_bits(&pos, tmpbuf, 0, sizeof(buf) * 8);
153         assert(z == -1);
154
155         pos.buffer = buf;
156         pos.nboff = 1;
157         pos.nbits = sizeof(buf) * 8;
158         z = asn_get_many_bits(&pos, tmpbuf, 0, sizeof(buf) * 8 - 1);
159         assert(z == 0);
160         assert(tmpbuf[0] == 110);
161         assert(tmpbuf[1] == 50);
162         assert(tmpbuf[2] == 95);
163         assert(tmpbuf[3] == 221);
164         assert(tmpbuf[4] == 90);
165
166         pos.buffer = buf;
167         pos.nboff = 1;
168         pos.nbits = sizeof(buf) * 8;
169         z = asn_get_many_bits(&pos, tmpbuf, 1, sizeof(buf) * 8 - 1);
170         assert(z == 0);
171         assert(tmpbuf[0] == 55);
172         assert(tmpbuf[0] != buf[0]);
173         assert(tmpbuf[1] == buf[1]);
174         assert(tmpbuf[2] == buf[2]);
175         assert(tmpbuf[3] == buf[3]);
176         assert(tmpbuf[4] == buf[4]);
177 }
178
179 static int Ignore(const void *data, size_t size, void *op_key) {
180     (void)data;
181     (void)size;
182     (void)op_key;
183         return 0;
184 }
185
186 static void
187 check_asn_bits_encoding() {
188         asn_bit_outp_t po;
189         int ret;
190
191         po.buffer = po.tmpspace;
192         po.nboff = 0;
193         po.nbits = 0;
194         po.output = Ignore;
195         po.op_key = 0;
196         po.tmpspace[0] = 0xff;
197
198         ret = asn_put_few_bits(&po, 0, 0);
199         assert(ret == 0);
200         assert(po.nboff == 0);
201         assert(po.buffer == po.tmpspace);
202         assert(po.tmpspace[0] == 0xff);
203
204         ret = asn_put_few_bits(&po, 0, 1);
205         assert(ret == 0);
206         assert(po.nboff == 1);
207         assert(po.nbits == 8 * sizeof(po.tmpspace));
208         assert(po.buffer == po.tmpspace);
209         assert(po.tmpspace[0] == 0x00);
210
211         ret = asn_put_few_bits(&po, 1, 1);
212         assert(ret == 0);
213         assert(po.nboff == 2);
214         assert(po.nbits == 8 * sizeof(po.tmpspace));
215         assert(po.buffer == po.tmpspace);
216         assert(po.tmpspace[0] == 0x40);
217
218         ret = asn_put_few_bits(&po, 1, 1);
219         assert(ret == 0);
220         assert(po.nboff == 3);
221         assert(po.nbits == 8 * sizeof(po.tmpspace));
222         assert(po.buffer == po.tmpspace);
223         assert(po.tmpspace[0] == 0x60);
224
225         ret = asn_put_few_bits(&po, 15, 5);
226         assert(ret == 0);
227         assert(po.nboff == 8);
228         assert(po.nbits == 8 * sizeof(po.tmpspace));
229         assert(po.buffer == po.tmpspace);
230         assert(po.tmpspace[0] == 0x6F);
231
232         ret = asn_put_few_bits(&po, 0xf0ff, 16);
233         assert(ret == 0);
234         assert(po.nboff == 16);
235         assert(po.nbits == 8 * sizeof(po.tmpspace) - 8);
236         assert(po.buffer == po.tmpspace + 1);
237         assert(po.tmpspace[0] == 0x6F);
238         assert(po.tmpspace[1] == 0xf0);
239         assert(po.tmpspace[2] == 0xff);
240
241         po.nboff--;
242
243         ret = asn_put_few_bits(&po, 2, 1);
244         assert(ret == 0);
245         assert(po.nboff == 8);
246         assert(po.nbits == 8 * sizeof(po.tmpspace) - 16);
247         assert(po.buffer == po.tmpspace + 2);
248         assert(po.tmpspace[0] == 0x6F);
249         assert(po.tmpspace[1] == 0xf0);
250         assert(po.tmpspace[2] == 0xfe);
251
252         ret = asn_put_few_bits(&po, 2, 32);
253         assert(ret == -1);
254
255         ret = asn_put_few_bits(&po, 2, -1);
256         assert(ret == -1);
257
258         ret = asn_put_few_bits(&po, -1, 31);
259         assert(ret == 0);
260         assert(po.nboff == 31);
261         assert(po.nbits == 8 * sizeof(po.tmpspace) - 24);
262         assert(po.buffer == po.tmpspace + 3);
263         assert(po.tmpspace[0] == 0x6F);
264         assert(po.tmpspace[1] == 0xf0);
265         assert(po.tmpspace[2] == 0xfe);
266         assert(po.tmpspace[3] == 0xff);
267         assert(po.tmpspace[4] == 0xff);
268         assert(po.tmpspace[5] == 0xff);
269         assert(po.tmpspace[6] == 0xfe);
270
271 }
272
273 /*
274  * Add N bits after P bits. Should result in N+P bits added.
275  */
276 static void
277 check_asn_bits_encoding_auto() {
278     int prior, next;
279     int ret, i;
280
281     for(prior = 0; prior <= 31; prior++) {
282       for(next = 0; next <= 31; next++) {
283         asn_bit_outp_t po;
284         po.buffer = po.tmpspace;
285         po.nboff = 0;
286         po.nbits = 0;
287         po.output = Ignore;
288         po.op_key = 0;
289         po.tmpspace[0] = 0xff;
290
291         ret = asn_put_few_bits(&po, -1, prior);
292         assert(ret == 0);
293
294                 ASN_DEBUG(" (out{nboff=%d,nbits=%d,buf_offset=%d})", (int)po.nboff, (int)po.nbits, (int)(po.buffer - po.tmpspace));
295
296         ret = asn_put_few_bits(&po, -1, next);
297         assert(ret == 0);
298
299                 ASN_DEBUG(" (out{nboff=%d,nbits=%d,buf_offset=%d})", (int)po.nboff, (int)po.nbits, (int)(po.buffer - po.tmpspace));
300
301                 ASN_DEBUG("Putting %d + %d bits (%d/%d), got %d bytes and %d bits",
302             prior, next, (prior + next) / 8, (prior + next) % 8,
303             (int)(po.buffer - po.tmpspace), (int)po.nboff);
304         assert((po.buffer - po.tmpspace) * 8 + po.nboff == (size_t)(prior + next));
305         for(i = 0; i < (po.buffer - po.tmpspace); i++)
306             assert(po.tmpspace[0] == (unsigned char)-1);
307       }
308     }
309 }
310
311 static void
312 check_asn_bits_sweep_with(uint8_t buf[], int already_bits, int add_bits) {
313         size_t buf_size = 8;
314         asn_bit_data_t pos;
315         asn_bit_outp_t out;
316         int32_t d_already;
317         int32_t d_add;
318         int32_t d_left;
319         int left_bits;
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 = asn_get_few_bits(&pos, already_bits);
333         d_add = asn_get_few_bits(&pos, add_bits);
334
335         asn_put_few_bits(&out, d_already, already_bits);
336         asn_put_few_bits(&out, d_add, add_bits);
337         if(out.nboff % 8) {
338                 left_bits = 8 - (out.nboff % 8);
339                 d_left = asn_get_few_bits(&pos, left_bits);
340         } else {
341                 left_bits = 0;
342                 d_left = 0;
343         }
344         asn_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(size_t i = 0; i < buf_size; i++)
350                         printf(" %02x", buf[i]);
351                 printf("\nOUT:");
352                 for(size_t 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
359 static void
360 check_asn_bits_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            check_asn_bits_sweep_with(buf[buf_idx], already_bits, add_bits);
374           }
375          }
376         }
377 }
378
379 int
380 main() {
381         check_asn_bits_decoding();
382         check_asn_bits_encoding();
383         check_asn_bits_encoding_auto();
384         check_asn_bits_sweep();
385         return 0;
386 }