11 32 | 17, /* [UNIVERSAL 17], constructed */
14 /* b CHOICE { b2 ObjectDescriptor }*/
15 7, /* [UNIVERSAL 7] */
20 1, /* [UNIVERSAL 1] */
24 18, /* [UNIVERSAL 18] */
31 /* d.r-oid RELATIVE-OID */
32 13, /* [UNIVERSAL 13] */
39 uint8_t buf1_reconstr[] = {
40 32 | 17, /* [UNIVERSAL 17], constructed */
44 1, /* [UNIVERSAL 1] */
48 /* b CHOICE { b2 ObjectDescriptor }*/
49 7, /* [UNIVERSAL 7] */
53 /* d.r-oid RELATIVE-OID */
54 13, /* [UNIVERSAL 1] */
60 18, /* [UNIVERSAL 18] */
69 32 | 17, /* [UNIVERSAL 17], constructed */
73 18, /* [UNIVERSAL 18] */
81 1, /* [UNIVERSAL 1] */
85 /* b CHOICE { b1 IA5String }*/
86 22, /* [UNIVERSAL 22] */
90 /* d.oid RELATIVE-OID */
91 6, /* [UNIVERSAL 6] */
97 uint8_t buf2_reconstr[] = {
98 32 | 17, /* [UNIVERSAL 17], constructed */
102 1, /* [UNIVERSAL 1] */
104 0xff, /* Canonical True */
106 /* d.oid RELATIVE-OID */
107 6, /* [UNIVERSAL 6] */
111 /* a NumericString */
112 18, /* [UNIVERSAL 18] */
119 /* b CHOICE { b1 IA5String }*/
120 22, /* [UNIVERSAL 22] */
126 check(T_t *tp, uint8_t *buf, size_t size, size_t consumed) {
129 tp = memset(tp, 0, sizeof(*tp));
131 fprintf(stderr, "Buf %p (%zd)\n", buf, size);
132 rval = ber_decode(0, &asn_DEF_T, (void **)&tp, buf, size);
133 fprintf(stderr, "Returned code %d, consumed %zd\n",
134 (int)rval.code, rval.consumed);
136 assert(rval.code == RC_OK);
137 assert(rval.consumed == consumed);
139 assert(strcmp((char *)tp->a.buf, "=<&>") == 0);
140 assert(strcmp((char *)tp->b.choice.b1.buf, "z") == 0
141 && strcmp((char *)tp->b.choice.b2.buf, "z") == 0);
143 asn_fprint(stderr, &asn_DEF_T, tp);
144 xer_fprint(stderr, &asn_DEF_T, tp);
152 buf_fill(const void *buffer, size_t size, void *app_key) {
156 if(buf_pos + size > buf_size) {
157 fprintf(stderr, "%zd + %zd > %zd\n",
158 buf_pos, size, buf_size);
162 memcpy(buf + buf_pos, buffer, size);
164 fprintf(stderr, " written %zd (%zd)\n", size, buf_pos);
170 compare(T_t *tp, uint8_t *cmp_buf, size_t cmp_buf_size) {
171 asn_enc_rval_t erval;
174 buf_size = cmp_buf_size + 100;
175 uint8_t scratch[buf_size];
180 * Try to re-create using DER encoding.
182 erval = der_encode(&asn_DEF_T, tp, buf_fill, 0);
183 assert(erval.encoded != -1);
184 if(erval.encoded != (ssize_t)cmp_buf_size) {
185 printf("%zd != %zd\n", erval.encoded, cmp_buf_size);
187 assert(erval.encoded == (ssize_t)cmp_buf_size);
188 for(i = 0; i < cmp_buf_size; i++) {
189 if(buf[i] != cmp_buf[i]) {
190 fprintf(stderr, "Recreated buffer content mismatch:\n");
191 fprintf(stderr, "Byte %d, %x != %x (%d != %d)\n",
197 assert(buf[i] == cmp_buf[i]);
202 partial_read(uint8_t *data, size_t size) {
210 fprintf(stderr, "\nPartial read sequence...\n");
213 * Divide the space (size) into three blocks in various combinations:
214 * |<----->i1<----->i2<----->|
216 * Try to read block by block.
218 for(i1 = 0; i1 < size; i1++) {
219 for(i2 = i1; i2 < size; i2++) {
220 uint8_t *chunk1 = data;
222 uint8_t *chunk2 = data + size1;
223 size_t size2 = i2 - i1;
224 uint8_t *chunk3 = data + size1 + size2;
225 size_t size3 = size - size1 - size2;
227 fprintf(stderr, "\n%zd:{%zd, %zd, %zd}...\n",
228 size, size1, size2, size3);
230 memset(data1, 0, size);
231 memset(data2, 0, size);
232 memset(data3, 0, size);
233 memcpy(data1, chunk1, size1);
234 memcpy(data2, chunk2, size2);
235 memcpy(data3, chunk3, size3);
237 tp = memset(&t, 0, sizeof(t));
239 fprintf(stderr, "=> Chunk 1 (%zd):\n", size1);
240 rval = ber_decode(0, &asn_DEF_T, (void **)&tp,
242 assert(rval.code == RC_WMORE);
243 assert(rval.consumed <= size1);
244 if(rval.consumed < size1) {
245 int leftover = size1 - rval.consumed;
246 memcpy(data2, data1 + rval.consumed, leftover);
247 memcpy(data2 + leftover, chunk2, size2);
251 fprintf(stderr, "=> Chunk 2 (%zd):\n", size2);
252 rval = ber_decode(0, &asn_DEF_T, (void **)&tp,
254 assert(rval.code == RC_WMORE);
255 assert(rval.consumed <= size2);
256 if(rval.consumed < size2) {
257 int leftover = size2 - rval.consumed;
258 memcpy(data3, data2 + rval.consumed, leftover);
259 memcpy(data3 + leftover, chunk3, size3);
263 fprintf(stderr, "=> Chunk 3 (%zd):\n", size3);
264 rval = ber_decode(0, &asn_DEF_T, (void **)&tp,
266 assert(rval.code == RC_OK);
267 assert(rval.consumed == size3);
269 ASN_STRUCT_RESET(asn_DEF_T, &t);
274 static char xer_buf[128];
275 static size_t xer_off;
278 xer_cb(const void *buffer, size_t size, void *key) {
280 assert(xer_off + size < sizeof(xer_buf));
281 memcpy(xer_buf + xer_off, buffer, size);
287 check_xer(uint8_t *data, uint8_t size, char *xer_sample) {
291 size_t xer_sample_len = strlen(xer_sample);
293 rval = ber_decode(0, &asn_DEF_T, (void **)&tp, data, size);
294 assert(rval.code == RC_OK);
295 assert(rval.consumed == size);
299 er = xer_encode(&asn_DEF_T, tp, XER_F_CANONICAL, xer_cb, 0);
301 xer_buf[xer_off] = 0;
302 printf("[%s] (%zd/%zd) vs [%s] (%zd)\n",
303 xer_buf, er.encoded, xer_off, xer_sample, xer_sample_len);
304 assert(er.encoded == (ssize_t)xer_off);
305 assert(xer_off == xer_sample_len);
306 assert(memcmp(xer_buf, xer_sample, xer_off) == 0);
308 ASN_STRUCT_FREE(asn_DEF_T, tp);
313 main(int ac, char **av) {
316 (void)ac; /* Unused argument */
317 (void)av; /* Unused argument */
319 check(&t, buf1, sizeof(buf1) + 10, sizeof(buf1));
320 compare(&t, buf1_reconstr, sizeof(buf1_reconstr));
321 ASN_STRUCT_RESET(asn_DEF_T, &t);
322 check_xer(buf1, sizeof(buf1), "<T><c><false/></c><b><b2>z</b2></b><a>=<&></a><d><r-oid>85.79</r-oid></d></T>");
324 check(&t, buf2, sizeof(buf2) + 10, sizeof(buf2));
325 compare(&t, buf2_reconstr, sizeof(buf2_reconstr));
326 ASN_STRUCT_RESET(asn_DEF_T, &t);
327 check_xer(buf2, sizeof(buf2), "<T><c><true/></c><b><b1>z</b1></b><a>=<&></a><d><oid>2.1</oid></d></T>");
329 /* Split the buffer in parts and check decoder restartability */
330 partial_read(buf1, sizeof(buf1));