blob: 950a3e817ef3b0285b746eb37ce3de3d76802fac [file] [log] [blame]
Lev Walkine0d9f2b2017-10-02 23:15:32 -07001#include <stdio.h>
2#include <assert.h>
3
4#include <asn_bit_data.c>
5
6static void
7check_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
179static 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
186static void
187check_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 */
276static void
277check_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
311static void
312check_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
359static void
360check_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
379int
380main() {
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}