blob: f21398b444c40a3bfee06d290b3f19f60c95127b [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 Walkin4eceeba2007-07-23 06:48:26 +00004#include <per_support.h>
5
Lev Walkin523de9e2006-08-18 01:34:18 +00006static void
7check_per_decoding() {
Lev Walkin59b176e2005-11-26 11:25:14 +00008 uint8_t buf[] = { 0xB7, 0x19, 0x2F, 0xEE, 0xAD };
9 uint8_t tmpbuf[10];
10 int32_t z;
11 asn_per_data_t pos;
Lev Walkinfe3dc602007-06-24 08:47:29 +000012 memset(&pos, 0, sizeof(pos));
Lev Walkin59b176e2005-11-26 11:25:14 +000013
14 pos.buffer = buf;
15 pos.nboff = 0;
16 pos.nbits = sizeof(buf) * 8;
17
18 z = per_get_few_bits(&pos, 32);
19 assert(z == -1);
Lev Walkin60364882005-11-28 06:58:11 +000020 assert(pos.nbits == sizeof(buf) * 8);
Lev Walkin59b176e2005-11-26 11:25:14 +000021
22 z = per_get_few_bits(&pos, 0);
23 assert(z == 0);
24 assert(pos.nboff == 0);
Lev Walkin60364882005-11-28 06:58:11 +000025 assert(pos.nbits == sizeof(buf) * 8);
Lev Walkin59b176e2005-11-26 11:25:14 +000026
27 z = per_get_few_bits(&pos, 1);
28 assert(z == 1);
29 assert(pos.nboff == 1);
Lev Walkin60364882005-11-28 06:58:11 +000030 assert(pos.nbits == sizeof(buf) * 8);
Lev Walkin59b176e2005-11-26 11:25:14 +000031
32 z = per_get_few_bits(&pos, 2);
33 assert(z == 1);
34 assert(pos.nboff == 3);
Lev Walkin60364882005-11-28 06:58:11 +000035 assert(pos.nbits == sizeof(buf) * 8);
Lev Walkin59b176e2005-11-26 11:25:14 +000036
37 z = per_get_few_bits(&pos, 2);
38 assert(z == 2);
39 assert(pos.nboff == 5);
Lev Walkin60364882005-11-28 06:58:11 +000040 assert(pos.nbits == sizeof(buf) * 8);
Lev Walkin59b176e2005-11-26 11:25:14 +000041
42 z = per_get_few_bits(&pos, 3);
43 assert(z == 7);
44 assert(pos.nboff == 8);
45 assert(pos.nbits == sizeof(buf) * 8);
46
47 z = per_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 = per_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 = per_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 = per_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 = per_get_few_bits(&pos, 24);
70 assert(z == 14443711);
71
Lev Walkin60364882005-11-28 06:58:11 +000072 /* Get full 31-bit range */
73 pos.buffer = buf;
74 pos.nboff = 7;
75 pos.nbits = sizeof(buf) * 8;
76 z = per_get_few_bits(&pos, 31);
77 assert(z == 1179384747);
78
79 /* Get a bit shifted range */
80 pos.buffer = buf;
81 pos.nboff = 6;
82 pos.nbits = sizeof(buf) * 8;
83 z = per_get_few_bits(&pos, 31);
84 assert(z == 1663434197);
85
Lev Walkin59b176e2005-11-26 11:25:14 +000086 pos.buffer = buf;
87 pos.nboff = 0;
88 pos.nbits = sizeof(buf) * 8;
89 z = per_get_many_bits(&pos, tmpbuf, 0, sizeof(buf) * 8);
90 assert(z == 0);
91 assert(buf[0] == tmpbuf[0]);
92 assert(buf[1] == tmpbuf[1]);
93 assert(buf[2] == tmpbuf[2]);
94 assert(buf[3] == tmpbuf[3]);
95 assert(buf[4] == tmpbuf[4]);
96
97 pos.buffer = buf;
98 pos.nboff = 1;
99 pos.nbits = sizeof(buf) * 8;
100 z = per_get_many_bits(&pos, tmpbuf, 0, sizeof(buf) * 8);
101 assert(z == -1);
102
103 pos.buffer = buf;
104 pos.nboff = 1;
105 pos.nbits = sizeof(buf) * 8;
106 z = per_get_many_bits(&pos, tmpbuf, 0, sizeof(buf) * 8 - 1);
107 assert(z == 0);
108 assert(tmpbuf[0] == 110);
109 assert(tmpbuf[1] == 50);
110 assert(tmpbuf[2] == 95);
111 assert(tmpbuf[3] == 221);
112 assert(tmpbuf[4] == 90);
113
114 pos.buffer = buf;
115 pos.nboff = 1;
116 pos.nbits = sizeof(buf) * 8;
117 z = per_get_many_bits(&pos, tmpbuf, 1, sizeof(buf) * 8 - 1);
118 assert(z == 0);
119 assert(tmpbuf[0] == 55);
120 assert(tmpbuf[0] != buf[0]);
121 assert(tmpbuf[1] == buf[1]);
122 assert(tmpbuf[2] == buf[2]);
123 assert(tmpbuf[3] == buf[3]);
124 assert(tmpbuf[4] == buf[4]);
Lev Walkin523de9e2006-08-18 01:34:18 +0000125}
Lev Walkin59b176e2005-11-26 11:25:14 +0000126
Lev Walkin523de9e2006-08-18 01:34:18 +0000127static int Ignore(const void *data, size_t size, void *op_key) {
128 return 0;
129}
130
131static void
132check_per_encoding() {
133 asn_per_outp_t po;
Lev Walkin0bcb49d2006-09-18 21:36:30 +0000134 int ret;
135
Lev Walkin523de9e2006-08-18 01:34:18 +0000136 po.buffer = po.tmpspace;
137 po.nboff = 0;
138 po.nbits = 0;
139 po.outper = Ignore;
140 po.op_key = 0;
141 po.tmpspace[0] = 0xff;
Lev Walkin523de9e2006-08-18 01:34:18 +0000142
143 ret = per_put_few_bits(&po, 0, 0);
144 assert(ret == 0);
145 assert(po.nboff == 0);
146 assert(po.buffer == po.tmpspace);
147 assert(po.tmpspace[0] == 0xff);
148
149 ret = per_put_few_bits(&po, 0, 1);
150 assert(ret == 0);
151 assert(po.nboff == 1);
152 assert(po.nbits == 8 * sizeof(po.tmpspace));
153 assert(po.buffer == po.tmpspace);
154 assert(po.tmpspace[0] == 0x00);
155
156 ret = per_put_few_bits(&po, 1, 1);
157 assert(ret == 0);
158 assert(po.nboff == 2);
159 assert(po.nbits == 8 * sizeof(po.tmpspace));
160 assert(po.buffer == po.tmpspace);
161 assert(po.tmpspace[0] == 0x40);
162
163 ret = per_put_few_bits(&po, 1, 1);
164 assert(ret == 0);
165 assert(po.nboff == 3);
166 assert(po.nbits == 8 * sizeof(po.tmpspace));
167 assert(po.buffer == po.tmpspace);
168 assert(po.tmpspace[0] == 0x60);
169
170 ret = per_put_few_bits(&po, 15, 5);
171 assert(ret == 0);
172 assert(po.nboff == 8);
173 assert(po.nbits == 8 * sizeof(po.tmpspace));
174 assert(po.buffer == po.tmpspace);
175 assert(po.tmpspace[0] == 0x6F);
176
177 ret = per_put_few_bits(&po, 0xf0ff, 16);
178 assert(ret == 0);
179 assert(po.nboff == 16);
180 assert(po.nbits == 8 * sizeof(po.tmpspace) - 8);
181 assert(po.buffer == po.tmpspace + 1);
182 assert(po.tmpspace[0] == 0x6F);
183 assert(po.tmpspace[1] == 0xf0);
184 assert(po.tmpspace[2] == 0xff);
185
186 po.nboff--;
187
188 ret = per_put_few_bits(&po, 2, 1);
189 assert(ret == 0);
190 assert(po.nboff == 8);
191 assert(po.nbits == 8 * sizeof(po.tmpspace) - 16);
192 assert(po.buffer == po.tmpspace + 2);
193 assert(po.tmpspace[0] == 0x6F);
194 assert(po.tmpspace[1] == 0xf0);
195 assert(po.tmpspace[2] == 0xfe);
196
197 ret = per_put_few_bits(&po, 2, 32);
198 assert(ret == -1);
199
200 ret = per_put_few_bits(&po, 2, -1);
201 assert(ret == -1);
202
203 ret = per_put_few_bits(&po, -1, 31);
204 assert(ret == 0);
205 assert(po.nboff == 31);
206 assert(po.nbits == 8 * sizeof(po.tmpspace) - 24);
207 assert(po.buffer == po.tmpspace + 3);
208 assert(po.tmpspace[0] == 0x6F);
209 assert(po.tmpspace[1] == 0xf0);
210 assert(po.tmpspace[2] == 0xfe);
211 assert(po.tmpspace[3] == 0xff);
212 assert(po.tmpspace[4] == 0xff);
213 assert(po.tmpspace[5] == 0xff);
214 assert(po.tmpspace[6] == 0xfe);
215
Lev Walkin109ade52010-10-24 20:48:05 -0700216}
Lev Walkin523de9e2006-08-18 01:34:18 +0000217
Lev Walkin15b82432012-01-06 03:19:01 -0800218/*
219 * Add N bits after P bits. Should result in N+P bits added.
220 */
221static void
222check_per_encoding_auto() {
223 int prior, next;
224 int ret, i;
225
226 for(prior = 0; prior <= 31; prior++) {
227 for(next = 0; next <= 31; next++) {
228 asn_per_outp_t po;
229 po.buffer = po.tmpspace;
230 po.nboff = 0;
231 po.nbits = 0;
232 po.outper = Ignore;
233 po.op_key = 0;
234 po.tmpspace[0] = 0xff;
235
236 ret = per_put_few_bits(&po, -1, prior);
237 assert(ret == 0);
238
239 fprintf(stderr, " (out{nboff=%d,nbits=%d,buf_offset=%d})\n", (int)po.nboff, (int)po.nbits, (int)(po.buffer - po.tmpspace));
240
241 ret = per_put_few_bits(&po, -1, next);
242 assert(ret == 0);
243
244 fprintf(stderr, " (out{nboff=%d,nbits=%d,buf_offset=%d})\n", (int)po.nboff, (int)po.nbits, (int)(po.buffer - po.tmpspace));
245
246 fprintf(stderr, "Putting %d + %d bits (%d/%d), got %d bytes and %d bits\n",
247 prior, next, (prior + next) / 8, (prior + next) % 8,
248 (int)(po.buffer - po.tmpspace), (int)po.nboff);
249 assert((po.buffer - po.tmpspace) * 8 + po.nboff == prior + next);
250 for(i = 0; i < (po.buffer - po.tmpspace); i++)
251 assert(po.tmpspace[0] == (unsigned char)-1);
252 }
253 }
254}
255
Lev Walkin109ade52010-10-24 20:48:05 -0700256static void
257check_per_encoding_sweep_with(uint8_t buf[], int already_bits, int add_bits) {
258 size_t buf_size = 8;
259 asn_per_data_t pos;
260 asn_per_outp_t out;
261 int32_t d_already;
262 int32_t d_add;
263 int32_t d_left;
264 int left_bits;
265 int i;
266
267 memset(&pos, 0, sizeof(pos));
268 pos.buffer = buf;
269 pos.nboff = 0;
270 pos.nbits = buf_size * 8;
271
272 memset(&out, 0, sizeof(out));
273 out.buffer = out.tmpspace;
274 out.nbits = 8 * sizeof(out.tmpspace);
275 assert(sizeof(out.tmpspace) >= buf_size);
276 memcpy(out.buffer, buf, buf_size);
277
278 d_already = per_get_few_bits(&pos, already_bits);
279 d_add = per_get_few_bits(&pos, add_bits);
280
281 per_put_few_bits(&out, d_already, already_bits);
282 per_put_few_bits(&out, d_add, add_bits);
283 if(out.nboff % 8) {
284 left_bits = 8 - (out.nboff % 8);
285 d_left = per_get_few_bits(&pos, left_bits);
286 } else {
287 left_bits = 0;
288 d_left = 0;
289 }
290 per_put_few_bits(&out, d_left, left_bits);
291 assert(0 == (out.nboff % 8));
292
293 if(0 != memcmp(out.tmpspace, buf, buf_size)) {
294 printf("IN: ");
295 for(i = 0; i < buf_size; i++)
296 printf(" %02x", buf[i]);
297 printf("\nOUT:");
298 for(i = 0; i < buf_size; i++)
299 printf(" %02x", out.tmpspace[i]);
300 printf(" (out{nboff=%d,left=%d,%02x})\n", (int)out.nboff, left_bits, (int)d_left);
301 assert(0 == memcmp(out.tmpspace, buf, buf_size));
302 }
303}
304
305static void
306check_per_encoding_sweep() {
307 uint8_t buf[3][8] = {
308 { 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA },
309 { 0xB7, 0x19, 0x2F, 0xEE, 0xAD, 0x11, 0xAA, 0x55 },
310 { 0xEE, 0xAD, 0x11, 0xAA, 0x55, 0xB7, 0x19, 0x2F }
311 };
312 int already_bits;
313 int add_bits;
314 int buf_idx;
315
316 for(buf_idx = 0; buf_idx < 3; buf_idx++) {
317 for(already_bits = 0; already_bits < 24; already_bits++) {
318 for(add_bits = 0; add_bits <= 31; add_bits++) {
319 /*fprintf(stderr, "PER %d += %d\n", already_bits, add_bits);*/
320 check_per_encoding_sweep_with(buf[buf_idx], already_bits, add_bits);
321 }
322 }
323 }
Lev Walkin523de9e2006-08-18 01:34:18 +0000324}
325
326int
327main() {
328 check_per_decoding();
329 check_per_encoding();
Lev Walkin15b82432012-01-06 03:19:01 -0800330 check_per_encoding_auto();
Lev Walkin109ade52010-10-24 20:48:05 -0700331 check_per_encoding_sweep();
Lev Walkin59b176e2005-11-26 11:25:14 +0000332 return 0;
333}