Sync from Azure to LF
[ric-plt/resource-status-manager.git] / RSM / asn1codec / e2ap_engine / constr_SEQUENCE.c
1
2 /*
3  * Copyright (c) 2003-2017 Lev Walkin <vlm@lionet.info>.
4  * All rights reserved.
5  * Redistribution and modifications are permitted subject to BSD license.
6  */
7 #include <asn_internal.h>
8 #include <constr_SEQUENCE.h>
9 #include <OPEN_TYPE.h>
10 #include <per_opentype.h>
11
12 /*
13  * Number of bytes left for this structure.
14  * (ctx->left) indicates the number of bytes _transferred_ for the structure.
15  * (size) contains the number of bytes in the buffer passed.
16  */
17 #define LEFT    ((size<(size_t)ctx->left)?size:(size_t)ctx->left)
18
19 /*
20  * If the subprocessor function returns with an indication that it wants
21  * more data, it may well be a fatal decoding problem, because the
22  * size is constrained by the <TLV>'s L, even if the buffer size allows
23  * reading more data.
24  * For example, consider the buffer containing the following TLVs:
25  * <T:5><L:1><V> <T:6>...
26  * The TLV length clearly indicates that one byte is expected in V, but
27  * if the V processor returns with "want more data" even if the buffer
28  * contains way more data than the V processor have seen.
29  */
30 #define SIZE_VIOLATION  (ctx->left >= 0 && (size_t)ctx->left <= size)
31
32 /*
33  * This macro "eats" the part of the buffer which is definitely "consumed",
34  * i.e. was correctly converted into local representation or rightfully skipped.
35  */
36 #undef  ADVANCE
37 #define ADVANCE(num_bytes)      do {            \
38                 size_t num = num_bytes;         \
39                 ptr = ((const char *)ptr) + num; \
40                 size -= num;                    \
41                 if(ctx->left >= 0)              \
42                         ctx->left -= num;       \
43                 consumed_myself += num;         \
44         } while(0)
45
46 /*
47  * Switch to the next phase of parsing.
48  */
49 #undef  NEXT_PHASE
50 #undef  PHASE_OUT
51 #define NEXT_PHASE(ctx) do {                    \
52                 ctx->phase++;                   \
53                 ctx->step = 0;                  \
54         } while(0)
55 #define PHASE_OUT(ctx)  do { ctx->phase = 10; } while(0)
56
57 /*
58  * Return a standardized complex structure.
59  */
60 #undef  RETURN
61 #define RETURN(_code)   do {                    \
62                 rval.code = _code;              \
63                 rval.consumed = consumed_myself;\
64                 return rval;                    \
65         } while(0)
66
67 /*
68  * Check whether we are inside the extensions group.
69  */
70 #define IN_EXTENSION_GROUP(specs, memb_idx) \
71     ((specs)->first_extension >= 0          \
72      && (unsigned)(specs)->first_extension <= (memb_idx))
73
74 /*
75  * Tags are canonically sorted in the tag2element map.
76  */
77 static int
78 _t2e_cmp(const void *ap, const void *bp) {
79         const asn_TYPE_tag2member_t *a = (const asn_TYPE_tag2member_t *)ap;
80         const asn_TYPE_tag2member_t *b = (const asn_TYPE_tag2member_t *)bp;
81
82         int a_class = BER_TAG_CLASS(a->el_tag);
83         int b_class = BER_TAG_CLASS(b->el_tag);
84
85         if(a_class == b_class) {
86                 ber_tlv_tag_t a_value = BER_TAG_VALUE(a->el_tag);
87                 ber_tlv_tag_t b_value = BER_TAG_VALUE(b->el_tag);
88
89                 if(a_value == b_value) {
90                         if(a->el_no > b->el_no)
91                                 return 1;
92                         /*
93                          * Important: we do not check
94                          * for a->el_no <= b->el_no!
95                          */
96                         return 0;
97                 } else if(a_value < b_value)
98                         return -1;
99                 else
100                         return 1;
101         } else if(a_class < b_class) {
102                 return -1;
103         } else {
104                 return 1;
105         }
106 }
107
108
109 /*
110  * The decoder of the SEQUENCE type.
111  */
112 asn_dec_rval_t
113 SEQUENCE_decode_ber(const asn_codec_ctx_t *opt_codec_ctx,
114                     const asn_TYPE_descriptor_t *td, void **struct_ptr,
115                     const void *ptr, size_t size, int tag_mode) {
116     /*
117          * Bring closer parts of structure description.
118          */
119         const asn_SEQUENCE_specifics_t *specs = (const asn_SEQUENCE_specifics_t *)td->specifics;
120     const asn_TYPE_member_t *elements = td->elements;
121
122     /*
123          * Parts of the structure being constructed.
124          */
125         void *st = *struct_ptr; /* Target structure. */
126         asn_struct_ctx_t *ctx;  /* Decoder context */
127
128         ber_tlv_tag_t tlv_tag;  /* T from TLV */
129         asn_dec_rval_t rval;    /* Return code from subparsers */
130
131         ssize_t consumed_myself = 0;    /* Consumed bytes from ptr */
132         size_t edx;                     /* SEQUENCE element's index */
133
134         ASN_DEBUG("Decoding %s as SEQUENCE", td->name);
135         
136         /*
137          * Create the target structure if it is not present already.
138          */
139         if(st == 0) {
140                 st = *struct_ptr = CALLOC(1, specs->struct_size);
141                 if(st == 0) {
142                         RETURN(RC_FAIL);
143                 }
144         }
145
146         /*
147          * Restore parsing context.
148          */
149         ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
150         
151         /*
152          * Start to parse where left previously
153          */
154         switch(ctx->phase) {
155         case 0:
156                 /*
157                  * PHASE 0.
158                  * Check that the set of tags associated with given structure
159                  * perfectly fits our expectations.
160                  */
161
162                 rval = ber_check_tags(opt_codec_ctx, td, ctx, ptr, size,
163                         tag_mode, 1, &ctx->left, 0);
164                 if(rval.code != RC_OK) {
165                         ASN_DEBUG("%s tagging check failed: %d",
166                                 td->name, rval.code);
167                         return rval;
168                 }
169
170                 if(ctx->left >= 0)
171                         ctx->left += rval.consumed; /* ?Substracted below! */
172                 ADVANCE(rval.consumed);
173
174                 NEXT_PHASE(ctx);
175
176                 ASN_DEBUG("Structure consumes %ld bytes, buffer %ld",
177                         (long)ctx->left, (long)size);
178
179                 /* Fall through */
180         case 1:
181                 /*
182                  * PHASE 1.
183                  * From the place where we've left it previously,
184                  * try to decode the next member from the list of
185                  * this structure's elements.
186                  * (ctx->step) stores the member being processed
187                  * between invocations and the microphase {0,1} of parsing
188                  * that member:
189                  *      step = (<member_number> * 2 + <microphase>).
190                  */
191           for(edx = ((size_t)ctx->step >> 1); edx < td->elements_count;
192                         edx++, ctx->step = (ctx->step & ~1) + 2) {
193                 void *memb_ptr;         /* Pointer to the member */
194                 void **memb_ptr2;       /* Pointer to that pointer */
195                 ssize_t tag_len;        /* Length of TLV's T */
196                 size_t opt_edx_end;     /* Next non-optional element */
197                 size_t n;
198                 int use_bsearch;
199
200                 if(ctx->step & 1)
201                         goto microphase2;
202
203                 /*
204                  * MICROPHASE 1: Synchronize decoding.
205                  */
206                 ASN_DEBUG("In %s SEQUENCE left %d, edx=%" ASN_PRI_SIZE " flags=%d"
207                                 " opt=%d ec=%d",
208                         td->name, (int)ctx->left, edx,
209                         elements[edx].flags, elements[edx].optional,
210                         td->elements_count);
211
212         if(ctx->left == 0 /* No more stuff is expected */
213            && (
214                   /* Explicit OPTIONAL specification reaches the end */
215                   (edx + elements[edx].optional == td->elements_count) ||
216                   /* All extensions are optional */
217                   IN_EXTENSION_GROUP(specs, edx))) {
218             ASN_DEBUG("End of SEQUENCE %s", td->name);
219             /*
220              * Found the legitimate end of the structure.
221              */
222             PHASE_OUT(ctx);
223             RETURN(RC_OK);
224         }
225
226                 /*
227                  * Fetch the T from TLV.
228                  */
229                 tag_len = ber_fetch_tag(ptr, LEFT, &tlv_tag);
230                 ASN_DEBUG("Current tag in %s SEQUENCE for element %" ASN_PRI_SIZE " "
231                         "(%s) is %s encoded in %d bytes, of frame %ld",
232                         td->name, edx, elements[edx].name,
233                         ber_tlv_tag_string(tlv_tag), (int)tag_len, (long)LEFT);
234                 switch(tag_len) {
235                 case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
236                         /* Fall through */
237                 case -1: RETURN(RC_FAIL);
238                 }
239
240         if(ctx->left < 0 && ((const uint8_t *)ptr)[0] == 0) {
241             if(LEFT < 2) {
242                 if(SIZE_VIOLATION) {
243                     RETURN(RC_FAIL);
244                 } else {
245                     RETURN(RC_WMORE);
246                 }
247             } else if(((const uint8_t *)ptr)[1] == 0) {
248                 ASN_DEBUG("edx = %" ASN_PRI_SIZE ", opt = %d, ec=%d", edx,
249                           elements[edx].optional, td->elements_count);
250                 if((edx + elements[edx].optional == td->elements_count)
251                    || IN_EXTENSION_GROUP(specs, edx)) {
252                     /*
253                      * Yeah, baby! Found the terminator
254                      * of the indefinite length structure.
255                      */
256                     /*
257                      * Proceed to the canonical
258                      * finalization function.
259                      * No advancing is necessary.
260                      */
261                     goto phase3;
262                 }
263             }
264         }
265
266                 /*
267                  * Find the next available type with this tag.
268                  */
269                 use_bsearch = 0;
270                 opt_edx_end = edx + elements[edx].optional + 1;
271                 if(opt_edx_end > td->elements_count)
272                         opt_edx_end = td->elements_count;       /* Cap */
273                 else if(opt_edx_end - edx > 8) {
274                         /* Limit the scope of linear search... */
275                         opt_edx_end = edx + 8;
276                         use_bsearch = 1;
277                         /* ... and resort to bsearch() */
278                 }
279                 for(n = edx; n < opt_edx_end; n++) {
280                         if(BER_TAGS_EQUAL(tlv_tag, elements[n].tag)) {
281                                 /*
282                                  * Found element corresponding to the tag
283                                  * being looked at.
284                                  * Reposition over the right element.
285                                  */
286                                 edx = n;
287                                 ctx->step = 1 + 2 * edx;        /* Remember! */
288                                 goto microphase2;
289                         } else if(elements[n].flags & ATF_ANY_TYPE) {
290                                 /*
291                                  * This is the ANY type, which may bear
292                                  * any flag whatsoever.
293                                  */
294                                 edx = n;
295                                 ctx->step = 1 + 2 * edx;        /* Remember! */
296                                 goto microphase2;
297                         } else if(elements[n].tag == (ber_tlv_tag_t)-1) {
298                                 use_bsearch = 1;
299                                 break;
300                         }
301                 }
302                 if(use_bsearch) {
303                         /*
304                          * Resort to a binary search over
305                          * sorted array of tags.
306                          */
307                         const asn_TYPE_tag2member_t *t2m;
308                         asn_TYPE_tag2member_t key = {0, 0, 0, 0};
309                         key.el_tag = tlv_tag;
310                         key.el_no = edx;
311                         t2m = (const asn_TYPE_tag2member_t *)bsearch(&key,
312                                 specs->tag2el, specs->tag2el_count,
313                                 sizeof(specs->tag2el[0]), _t2e_cmp);
314                         if(t2m) {
315                                 const asn_TYPE_tag2member_t *best = 0;
316                                 const asn_TYPE_tag2member_t *t2m_f, *t2m_l;
317                                 size_t edx_max = edx + elements[edx].optional;
318                                 /*
319                                  * Rewind to the first element with that tag,
320                                  * `cause bsearch() does not guarantee order.
321                                  */
322                                 t2m_f = t2m + t2m->toff_first;
323                                 t2m_l = t2m + t2m->toff_last;
324                                 for(t2m = t2m_f; t2m <= t2m_l; t2m++) {
325                                         if(t2m->el_no > edx_max) break;
326                                         if(t2m->el_no < edx) continue;
327                                         best = t2m;
328                                 }
329                                 if(best) {
330                                         edx = best->el_no;
331                                         ctx->step = 1 + 2 * edx;
332                                         goto microphase2;
333                                 }
334                         }
335                         n = opt_edx_end;
336                 }
337                 if(n == opt_edx_end) {
338                         /*
339                          * If tag is unknown, it may be either
340                          * an unknown (thus, incorrect) tag,
341                          * or an extension (...),
342                          * or an end of the indefinite-length structure.
343                          */
344                         if(!IN_EXTENSION_GROUP(specs,
345                                 edx + elements[edx].optional)) {
346                                 ASN_DEBUG("Unexpected tag %s (at %" ASN_PRI_SIZE ")",
347                                         ber_tlv_tag_string(tlv_tag), edx);
348                                 ASN_DEBUG("Expected tag %s (%s)%s",
349                                         ber_tlv_tag_string(elements[edx].tag),
350                                         elements[edx].name,
351                                         elements[edx].optional
352                                                 ?" or alternatives":"");
353                                 RETURN(RC_FAIL);
354                         } else {
355                                 /* Skip this tag */
356                                 ssize_t skip;
357                                 edx += elements[edx].optional;
358
359                                 ASN_DEBUG("Skipping unexpected %s (at %" ASN_PRI_SIZE ")",
360                                         ber_tlv_tag_string(tlv_tag), edx);
361                                 skip = ber_skip_length(opt_codec_ctx,
362                                         BER_TLV_CONSTRUCTED(ptr),
363                                         (const char *)ptr + tag_len,
364                                         LEFT - tag_len);
365                                 ASN_DEBUG("Skip length %d in %s",
366                                         (int)skip, td->name);
367                                 switch(skip) {
368                                 case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
369                                         /* Fall through */
370                                 case -1: RETURN(RC_FAIL);
371                                 }
372
373                                 ADVANCE(skip + tag_len);
374                                 ctx->step -= 2;
375                                 edx--;
376                                 continue;  /* Try again with the next tag */
377                         }
378                 }
379
380                 /*
381                  * MICROPHASE 2: Invoke the member-specific decoder.
382                  */
383                 ctx->step |= 1;         /* Confirm entering next microphase */
384         microphase2:
385                 ASN_DEBUG("Inside SEQUENCE %s MF2", td->name);
386                 
387                 /*
388                  * Compute the position of the member inside a structure,
389                  * and also a type of containment (it may be contained
390                  * as pointer or using inline inclusion).
391                  */
392                 if(elements[edx].flags & ATF_POINTER) {
393                         /* Member is a pointer to another structure */
394                         memb_ptr2 = (void **)((char *)st + elements[edx].memb_offset);
395                 } else {
396                         /*
397                          * A pointer to a pointer
398                          * holding the start of the structure
399                          */
400                         memb_ptr = (char *)st + elements[edx].memb_offset;
401                         memb_ptr2 = &memb_ptr;
402                 }
403                 /*
404                  * Invoke the member fetch routine according to member's type
405                  */
406                 if(elements[edx].flags & ATF_OPEN_TYPE) {
407                         rval = OPEN_TYPE_ber_get(opt_codec_ctx, td, st, &elements[edx], ptr, LEFT);
408         } else {
409                         rval = elements[edx].type->op->ber_decoder(opt_codec_ctx,
410                                         elements[edx].type,
411                                         memb_ptr2, ptr, LEFT,
412                                         elements[edx].tag_mode);
413                 }
414                 ASN_DEBUG("In %s SEQUENCE decoded %" ASN_PRI_SIZE " %s of %d "
415                         "in %d bytes rval.code %d, size=%d",
416                         td->name, edx, elements[edx].type->name,
417                         (int)LEFT, (int)rval.consumed, rval.code, (int)size);
418                 switch(rval.code) {
419                 case RC_OK:
420                         break;
421                 case RC_WMORE: /* More data expected */
422                         if(!SIZE_VIOLATION) {
423                                 ADVANCE(rval.consumed);
424                                 RETURN(RC_WMORE);
425                         }
426                         ASN_DEBUG("Size violation (c->l=%ld <= s=%ld)",
427                                 (long)ctx->left, (long)size);
428                         /* Fall through */
429                 case RC_FAIL: /* Fatal error */
430                         RETURN(RC_FAIL);
431                 } /* switch(rval) */
432                 
433                 ADVANCE(rval.consumed);
434           }     /* for(all structure members) */
435
436         phase3:
437                 ctx->phase = 3;
438         /* Fall through */
439         case 3: /* 00 and other tags expected */
440         case 4: /* only 00's expected */
441
442                 ASN_DEBUG("SEQUENCE %s Leftover: %ld, size = %ld",
443                         td->name, (long)ctx->left, (long)size);
444
445                 /*
446                  * Skip everything until the end of the SEQUENCE.
447                  */
448                 while(ctx->left) {
449                         ssize_t tl, ll;
450
451                         tl = ber_fetch_tag(ptr, LEFT, &tlv_tag);
452                         switch(tl) {
453                         case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
454                                 /* Fall through */
455                         case -1: RETURN(RC_FAIL);
456                         }
457
458                         /*
459                          * If expected <0><0>...
460                          */
461                         if(ctx->left < 0
462                                 && ((const uint8_t *)ptr)[0] == 0) {
463                                 if(LEFT < 2) {
464                                         if(SIZE_VIOLATION)
465                                                 RETURN(RC_FAIL);
466                                         else
467                                                 RETURN(RC_WMORE);
468                                 } else if(((const uint8_t *)ptr)[1] == 0) {
469                                         /*
470                                          * Correctly finished with <0><0>.
471                                          */
472                                         ADVANCE(2);
473                                         ctx->left++;
474                                         ctx->phase = 4;
475                                         continue;
476                                 }
477                         }
478
479                         if(!IN_EXTENSION_GROUP(specs, td->elements_count)
480                         || ctx->phase == 4) {
481                                 ASN_DEBUG("Unexpected continuation "
482                                         "of a non-extensible type "
483                                         "%s (SEQUENCE): %s",
484                                         td->name,
485                                         ber_tlv_tag_string(tlv_tag));
486                                 RETURN(RC_FAIL);
487                         }
488
489                         ll = ber_skip_length(opt_codec_ctx,
490                                 BER_TLV_CONSTRUCTED(ptr),
491                                 (const char *)ptr + tl, LEFT - tl);
492                         switch(ll) {
493                         case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
494                                 /* Fall through */
495                         case -1: RETURN(RC_FAIL);
496                         }
497
498                         ADVANCE(tl + ll);
499                 }
500
501                 PHASE_OUT(ctx);
502         }
503         
504         RETURN(RC_OK);
505 }
506
507
508 /*
509  * The DER encoder of the SEQUENCE type.
510  */
511 asn_enc_rval_t
512 SEQUENCE_encode_der(const asn_TYPE_descriptor_t *td, const void *sptr,
513                     int tag_mode, ber_tlv_tag_t tag,
514                     asn_app_consume_bytes_f *cb, void *app_key) {
515     size_t computed_size = 0;
516         asn_enc_rval_t erval = {0,0,0};
517         ssize_t ret;
518         size_t edx;
519
520         ASN_DEBUG("%s %s as SEQUENCE",
521                 cb?"Encoding":"Estimating", td->name);
522
523         /*
524          * Gather the length of the underlying members sequence.
525          */
526         for(edx = 0; edx < td->elements_count; edx++) {
527                 asn_TYPE_member_t *elm = &td->elements[edx];
528
529                 const void *memb_ptr;           /* Pointer to the member */
530         const void *const *memb_ptr2; /* Pointer to that pointer */
531
532         if(elm->flags & ATF_POINTER) {
533             memb_ptr2 =
534                 (const void *const *)((const char *)sptr + elm->memb_offset);
535             if(!*memb_ptr2) {
536                                 ASN_DEBUG("Element %s %" ASN_PRI_SIZE " not present",
537                                         elm->name, edx);
538                                 if(elm->optional)
539                                         continue;
540                                 /* Mandatory element is missing */
541                                 ASN__ENCODE_FAILED;
542                         }
543                 } else {
544             memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
545             memb_ptr2 = &memb_ptr;
546                 }
547
548                 /* Eliminate default values */
549                 if(elm->default_value_cmp && elm->default_value_cmp(*memb_ptr2) == 0)
550                         continue;
551
552                 erval = elm->type->op->der_encoder(elm->type, *memb_ptr2,
553                         elm->tag_mode, elm->tag,
554                         0, 0);
555                 if(erval.encoded == -1)
556                         return erval;
557                 computed_size += erval.encoded;
558                 ASN_DEBUG("Member %" ASN_PRI_SIZE " %s estimated %ld bytes",
559                         edx, elm->name, (long)erval.encoded);
560         }
561
562         /*
563          * Encode the TLV for the sequence itself.
564          */
565         ret = der_write_tags(td, computed_size, tag_mode, 1, tag, cb, app_key);
566         ASN_DEBUG("Wrote tags: %ld (+%ld)", (long)ret, (long)computed_size);
567         if(ret == -1)
568                 ASN__ENCODE_FAILED;
569         erval.encoded = computed_size + ret;
570
571         if(!cb) ASN__ENCODED_OK(erval);
572
573         /*
574          * Encode all members.
575          */
576         for(edx = 0; edx < td->elements_count; edx++) {
577                 asn_TYPE_member_t *elm = &td->elements[edx];
578                 asn_enc_rval_t tmperval = {0,0,0};
579         const void *memb_ptr;           /* Pointer to the member */
580         const void *const *memb_ptr2;   /* Pointer to that pointer */
581
582         if(elm->flags & ATF_POINTER) {
583             memb_ptr2 =
584                 (const void *const *)((const char *)sptr + elm->memb_offset);
585             if(!*memb_ptr2) continue;
586                 } else {
587             memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
588             memb_ptr2 = &memb_ptr;
589                 }
590
591                 /* Eliminate default values */
592         if(elm->default_value_cmp && elm->default_value_cmp(*memb_ptr2) == 0)
593             continue;
594
595                 tmperval = elm->type->op->der_encoder(elm->type, *memb_ptr2,
596                         elm->tag_mode, elm->tag, cb, app_key);
597                 if(tmperval.encoded == -1)
598                         return tmperval;
599                 computed_size -= tmperval.encoded;
600                 ASN_DEBUG("Member %" ASN_PRI_SIZE " %s of SEQUENCE %s encoded in %ld bytes",
601                         edx, elm->name, td->name, (long)tmperval.encoded);
602         }
603
604         if(computed_size != 0)
605                 /*
606                  * Encoded size is not equal to the computed size.
607                  */
608                 ASN__ENCODE_FAILED;
609
610         ASN__ENCODED_OK(erval);
611 }
612
613
614 #undef  XER_ADVANCE
615 #define XER_ADVANCE(num_bytes)           \
616     do {                                 \
617         size_t num = (num_bytes);        \
618         ptr = ((const char *)ptr) + num; \
619         size -= num;                     \
620         consumed_myself += num;          \
621     } while(0)
622
623 /*
624  * Decode the XER (XML) data.
625  */
626 asn_dec_rval_t
627 SEQUENCE_decode_xer(const asn_codec_ctx_t *opt_codec_ctx,
628                     const asn_TYPE_descriptor_t *td, void **struct_ptr,
629                     const char *opt_mname, const void *ptr, size_t size) {
630     /*
631          * Bring closer parts of structure description.
632          */
633         const asn_SEQUENCE_specifics_t *specs
634                 = (const asn_SEQUENCE_specifics_t *)td->specifics;
635         asn_TYPE_member_t *elements = td->elements;
636         const char *xml_tag = opt_mname ? opt_mname : td->xml_tag;
637
638         /*
639          * ... and parts of the structure being constructed.
640          */
641         void *st = *struct_ptr; /* Target structure. */
642         asn_struct_ctx_t *ctx;  /* Decoder context */
643
644         asn_dec_rval_t rval;            /* Return value from a decoder */
645         ssize_t consumed_myself = 0;    /* Consumed bytes from ptr */
646         size_t edx;                     /* Element index */
647
648         /*
649          * Create the target structure if it is not present already.
650          */
651         if(st == 0) {
652                 st = *struct_ptr = CALLOC(1, specs->struct_size);
653                 if(st == 0) RETURN(RC_FAIL);
654         }
655
656         /*
657          * Restore parsing context.
658          */
659         ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
660
661
662         /*
663          * Phases of XER/XML processing:
664          * Phase 0: Check that the opening tag matches our expectations.
665          * Phase 1: Processing body and reacting on closing tag.
666          * Phase 2: Processing inner type.
667          * Phase 3: Skipping unknown extensions.
668          * Phase 4: PHASED OUT
669          */
670         for(edx = ctx->step; ctx->phase <= 3;) {
671                 pxer_chunk_type_e ch_type;      /* XER chunk type */
672                 ssize_t ch_size;                /* Chunk size */
673                 xer_check_tag_e tcv;            /* Tag check value */
674                 asn_TYPE_member_t *elm;
675
676                 /*
677                  * Go inside the inner member of a sequence.
678                  */
679                 if(ctx->phase == 2) {
680                         asn_dec_rval_t tmprval;
681                         void *memb_ptr_dontuse;         /* Pointer to the member */
682                         void **memb_ptr2;       /* Pointer to that pointer */
683
684                         elm = &td->elements[edx];
685
686                         if(elm->flags & ATF_POINTER) {
687                                 /* Member is a pointer to another structure */
688                                 memb_ptr2 = (void **)((char *)st + elm->memb_offset);
689                         } else {
690                                 memb_ptr_dontuse = (char *)st + elm->memb_offset;
691                                 memb_ptr2 = &memb_ptr_dontuse;  /* Only use of memb_ptr_dontuse */
692                         }
693
694                         if(elm->flags & ATF_OPEN_TYPE) {
695                                 tmprval = OPEN_TYPE_xer_get(opt_codec_ctx, td, st, elm, ptr, size);
696                         } else {
697                                 /* Invoke the inner type decoder, m.b. multiple times */
698                                 tmprval = elm->type->op->xer_decoder(opt_codec_ctx,
699                                                 elm->type, memb_ptr2, elm->name,
700                                                 ptr, size);
701                         }
702                         XER_ADVANCE(tmprval.consumed);
703                         if(tmprval.code != RC_OK)
704                                 RETURN(tmprval.code);
705                         ctx->phase = 1; /* Back to body processing */
706                         ctx->step = ++edx;
707                         ASN_DEBUG("XER/SEQUENCE phase => %d, step => %d",
708                                 ctx->phase, ctx->step);
709                         /* Fall through */
710                 }
711
712                 /*
713                  * Get the next part of the XML stream.
714                  */
715                 ch_size = xer_next_token(&ctx->context, ptr, size,
716                         &ch_type);
717                 if(ch_size == -1) {
718                     RETURN(RC_FAIL);
719                 } else {
720                         switch(ch_type) {
721                         case PXER_WMORE:
722                                 RETURN(RC_WMORE);
723                         case PXER_COMMENT:      /* Got XML comment */
724                         case PXER_TEXT:         /* Ignore free-standing text */
725                                 XER_ADVANCE(ch_size);   /* Skip silently */
726                                 continue;
727                         case PXER_TAG:
728                                 break;  /* Check the rest down there */
729                         }
730                 }
731
732                 tcv = xer_check_tag(ptr, ch_size, xml_tag);
733                 ASN_DEBUG("XER/SEQUENCE: tcv = %d, ph=%d [%s]",
734                         tcv, ctx->phase, xml_tag);
735
736                 /* Skip the extensions section */
737                 if(ctx->phase == 3) {
738                         switch(xer_skip_unknown(tcv, &ctx->left)) {
739                         case -1:
740                                 ctx->phase = 4;
741                                 RETURN(RC_FAIL);
742                         case 0:
743                                 XER_ADVANCE(ch_size);
744                                 continue;
745                         case 1:
746                                 XER_ADVANCE(ch_size);
747                                 ctx->phase = 1;
748                                 continue;
749                         case 2:
750                                 ctx->phase = 1;
751                                 break;
752                         }
753                 }
754
755                 switch(tcv) {
756                 case XCT_CLOSING:
757                         if(ctx->phase == 0) break;
758                         ctx->phase = 0;
759                         /* Fall through */
760                 case XCT_BOTH:
761             if(ctx->phase == 0) {
762                 if(edx >= td->elements_count ||
763                    /* Explicit OPTIONAL specs reaches the end */
764                    (edx + elements[edx].optional == td->elements_count) ||
765                    /* All extensions are optional */
766                    IN_EXTENSION_GROUP(specs, edx)) {
767                     XER_ADVANCE(ch_size);
768                                         ctx->phase = 4; /* Phase out */
769                                         RETURN(RC_OK);
770                                 } else {
771                                         ASN_DEBUG("Premature end of XER SEQUENCE");
772                                         RETURN(RC_FAIL);
773                                 }
774                         }
775                         /* Fall through */
776                 case XCT_OPENING:
777                         if(ctx->phase == 0) {
778                                 XER_ADVANCE(ch_size);
779                                 ctx->phase = 1; /* Processing body phase */
780                                 continue;
781                         }
782                         /* Fall through */
783                 case XCT_UNKNOWN_OP:
784                 case XCT_UNKNOWN_BO:
785
786                         ASN_DEBUG("XER/SEQUENCE: tcv=%d, ph=%d, edx=%" ASN_PRI_SIZE "",
787                                 tcv, ctx->phase, edx);
788                         if(ctx->phase != 1) {
789                                 break;  /* Really unexpected */
790                         }
791
792                         if(edx < td->elements_count) {
793                                 /*
794                                  * Search which member corresponds to this tag.
795                                  */
796                                 size_t n;
797                                 size_t edx_end = edx + elements[edx].optional + 1;
798                                 if(edx_end > td->elements_count)
799                                         edx_end = td->elements_count;
800                                 for(n = edx; n < edx_end; n++) {
801                                         elm = &td->elements[n];
802                                         tcv = xer_check_tag(ptr, ch_size, elm->name);
803                                         switch(tcv) {
804                                         case XCT_BOTH:
805                                         case XCT_OPENING:
806                                                 /*
807                                                  * Process this member.
808                                                  */
809                                                 ctx->step = edx = n;
810                                                 ctx->phase = 2;
811                                                 break;
812                                         case XCT_UNKNOWN_OP:
813                                         case XCT_UNKNOWN_BO:
814                                                 continue;
815                                         default:
816                                                 n = edx_end;
817                                                 break;  /* Phase out */
818                                         }
819                                         break;
820                                 }
821                                 if(n != edx_end)
822                                         continue;
823                         } else {
824                                 ASN_DEBUG("Out of defined members: %" ASN_PRI_SIZE "/%u",
825                                         edx, td->elements_count);
826                         }
827
828                         /* It is expected extension */
829                         if(IN_EXTENSION_GROUP(specs,
830                                 edx + (edx < td->elements_count
831                                         ? elements[edx].optional : 0))) {
832                                 ASN_DEBUG("Got anticipated extension at %" ASN_PRI_SIZE "",
833                                         edx);
834                                 /*
835                                  * Check for (XCT_BOTH or XCT_UNKNOWN_BO)
836                                  * By using a mask. Only record a pure
837                                  * <opening> tags.
838                                  */
839                                 if(tcv & XCT_CLOSING) {
840                                         /* Found </extension> without body */
841                                 } else {
842                                         ctx->left = 1;
843                                         ctx->phase = 3; /* Skip ...'s */
844                                 }
845                                 XER_ADVANCE(ch_size);
846                                 continue;
847                         }
848
849                         /* Fall through */
850                 default:
851                         break;
852                 }
853
854                 ASN_DEBUG("Unexpected XML tag in SEQUENCE [%c%c%c%c%c%c]",
855                         size>0?((const char *)ptr)[0]:'.',
856                         size>1?((const char *)ptr)[1]:'.',
857                         size>2?((const char *)ptr)[2]:'.',
858                         size>3?((const char *)ptr)[3]:'.',
859                         size>4?((const char *)ptr)[4]:'.',
860                         size>5?((const char *)ptr)[5]:'.');
861                 break;
862         }
863
864         ctx->phase = 4; /* "Phase out" on hard failure */
865         RETURN(RC_FAIL);
866 }
867
868 asn_enc_rval_t
869 SEQUENCE_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr,
870                     int ilevel, enum xer_encoder_flags_e flags,
871                     asn_app_consume_bytes_f *cb, void *app_key) {
872     asn_enc_rval_t er = {0,0,0};
873     int xcan = (flags & XER_F_CANONICAL);
874     asn_TYPE_descriptor_t *tmp_def_val_td = 0;
875     void *tmp_def_val = 0;
876     size_t edx;
877
878     if(!sptr) ASN__ENCODE_FAILED;
879
880     er.encoded = 0;
881
882     for(edx = 0; edx < td->elements_count; edx++) {
883         asn_enc_rval_t tmper = {0,0,0};
884         asn_TYPE_member_t *elm = &td->elements[edx];
885         const void *memb_ptr;
886         const char *mname = elm->name;
887         unsigned int mlen = strlen(mname);
888
889         if(elm->flags & ATF_POINTER) {
890             memb_ptr =
891                 *(const void *const *)((const char *)sptr + elm->memb_offset);
892             if(!memb_ptr) {
893                 assert(tmp_def_val == 0);
894                 if(elm->default_value_set) {
895                     if(elm->default_value_set(&tmp_def_val)) {
896                         ASN__ENCODE_FAILED;
897                     } else {
898                         memb_ptr = tmp_def_val;
899                         tmp_def_val_td = elm->type;
900                     }
901                 } else if(elm->optional) {
902                     continue;
903                 } else {
904                     /* Mandatory element is missing */
905                     ASN__ENCODE_FAILED;
906                 }
907             }
908         } else {
909             memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
910         }
911
912         if(!xcan) ASN__TEXT_INDENT(1, ilevel);
913         ASN__CALLBACK3("<", 1, mname, mlen, ">", 1);
914
915         /* Print the member itself */
916         tmper = elm->type->op->xer_encoder(elm->type, memb_ptr, ilevel + 1,
917                                            flags, cb, app_key);
918         if(tmp_def_val) {
919             ASN_STRUCT_FREE(*tmp_def_val_td, tmp_def_val);
920             tmp_def_val = 0;
921         }
922         if(tmper.encoded == -1) return tmper;
923         er.encoded += tmper.encoded;
924
925         ASN__CALLBACK3("</", 2, mname, mlen, ">", 1);
926     }
927
928     if(!xcan) ASN__TEXT_INDENT(1, ilevel - 1);
929
930     ASN__ENCODED_OK(er);
931 cb_failed:
932     if(tmp_def_val) ASN_STRUCT_FREE(*tmp_def_val_td, tmp_def_val);
933     ASN__ENCODE_FAILED;
934 }
935
936 int
937 SEQUENCE_print(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
938                asn_app_consume_bytes_f *cb, void *app_key) {
939     size_t edx;
940         int ret;
941
942         if(!sptr) return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
943
944         /* Dump preamble */
945         if(cb(td->name, strlen(td->name), app_key) < 0
946         || cb(" ::= {", 6, app_key) < 0)
947                 return -1;
948
949         for(edx = 0; edx < td->elements_count; edx++) {
950                 asn_TYPE_member_t *elm = &td->elements[edx];
951                 const void *memb_ptr;
952
953                 if(elm->flags & ATF_POINTER) {
954                         memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset);
955                         if(!memb_ptr) {
956                                 if(elm->optional) continue;
957                                 /* Print <absent> line */
958                                 /* Fall through */
959                         }
960                 } else {
961                         memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
962                 }
963
964                 /* Indentation */
965                 _i_INDENT(1);
966
967                 /* Print the member's name and stuff */
968                 if(cb(elm->name, strlen(elm->name), app_key) < 0
969                 || cb(": ", 2, app_key) < 0)
970                         return -1;
971
972                 /* Print the member itself */
973                 ret = elm->type->op->print_struct(elm->type, memb_ptr, ilevel + 1,
974                         cb, app_key);
975                 if(ret) return ret;
976         }
977
978         ilevel--;
979         _i_INDENT(1);
980
981         return (cb("}", 1, app_key) < 0) ? -1 : 0;
982 }
983
984 void
985 SEQUENCE_free(const asn_TYPE_descriptor_t *td, void *sptr,
986               enum asn_struct_free_method method) {
987     size_t edx;
988     const asn_SEQUENCE_specifics_t *specs =
989         (const asn_SEQUENCE_specifics_t *)td->specifics;
990     asn_struct_ctx_t *ctx; /* Decoder context */
991
992         if(!td || !sptr)
993                 return;
994
995         ASN_DEBUG("Freeing %s as SEQUENCE", td->name);
996
997         for(edx = 0; edx < td->elements_count; edx++) {
998                 asn_TYPE_member_t *elm = &td->elements[edx];
999                 void *memb_ptr;
1000                 if(elm->flags & ATF_POINTER) {
1001                         memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
1002                         if(memb_ptr)
1003                                 ASN_STRUCT_FREE(*elm->type, memb_ptr);
1004                 } else {
1005                         memb_ptr = (void *)((char *)sptr + elm->memb_offset);
1006                         ASN_STRUCT_FREE_CONTENTS_ONLY(*elm->type, memb_ptr);
1007                 }
1008         }
1009
1010         /* Clean parsing context */
1011         ctx = (asn_struct_ctx_t *)((char *)sptr + specs->ctx_offset);
1012         FREEMEM(ctx->ptr);
1013
1014     switch(method) {
1015     case ASFM_FREE_EVERYTHING:
1016         FREEMEM(sptr);
1017         break;
1018     case ASFM_FREE_UNDERLYING:
1019         break;
1020     case ASFM_FREE_UNDERLYING_AND_RESET:
1021         memset(
1022             sptr, 0,
1023             ((const asn_SEQUENCE_specifics_t *)(td->specifics))->struct_size);
1024         break;
1025     }
1026 }
1027
1028 int
1029 SEQUENCE_constraint(const asn_TYPE_descriptor_t *td, const void *sptr,
1030                     asn_app_constraint_failed_f *ctfailcb, void *app_key) {
1031     size_t edx;
1032
1033         if(!sptr) {
1034                 ASN__CTFAIL(app_key, td, sptr,
1035                         "%s: value not given (%s:%d)",
1036                         td->name, __FILE__, __LINE__);
1037                 return -1;
1038         }
1039
1040         /*
1041          * Iterate over structure members and check their validity.
1042          */
1043         for(edx = 0; edx < td->elements_count; edx++) {
1044                 asn_TYPE_member_t *elm = &td->elements[edx];
1045                 const void *memb_ptr;
1046
1047                 if(elm->flags & ATF_POINTER) {
1048                         memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset);
1049                         if(!memb_ptr) {
1050                                 if(elm->optional)
1051                                         continue;
1052                                 ASN__CTFAIL(app_key, td, sptr,
1053                                 "%s: mandatory element %s absent (%s:%d)",
1054                                 td->name, elm->name, __FILE__, __LINE__);
1055                                 return -1;
1056                         }
1057                 } else {
1058                         memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
1059                 }
1060
1061                 if(elm->encoding_constraints.general_constraints) {
1062                         int ret = elm->encoding_constraints.general_constraints(elm->type, memb_ptr,
1063                                 ctfailcb, app_key);
1064                         if(ret) return ret;
1065                 } else {
1066                         return elm->type->encoding_constraints.general_constraints(elm->type,
1067                                 memb_ptr, ctfailcb, app_key);
1068                 }
1069         }
1070
1071         return 0;
1072 }
1073
1074 #ifndef ASN_DISABLE_PER_SUPPORT
1075
1076 asn_dec_rval_t
1077 SEQUENCE_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
1078                      const asn_TYPE_descriptor_t *td,
1079                      const asn_per_constraints_t *constraints, void **sptr,
1080                      asn_per_data_t *pd) {
1081     const asn_SEQUENCE_specifics_t *specs = (const asn_SEQUENCE_specifics_t *)td->specifics;
1082         void *st = *sptr;       /* Target structure. */
1083         int extpresent;         /* Extension additions are present */
1084         uint8_t *opres;         /* Presence of optional root members */
1085         asn_per_data_t opmd;
1086         asn_dec_rval_t rv;
1087         size_t edx;
1088
1089         (void)constraints;
1090
1091         if(ASN__STACK_OVERFLOW_CHECK(opt_codec_ctx))
1092                 ASN__DECODE_FAILED;
1093
1094         if(!st) {
1095                 st = *sptr = CALLOC(1, specs->struct_size);
1096                 if(!st) ASN__DECODE_FAILED;
1097         }
1098
1099         ASN_DEBUG("Decoding %s as SEQUENCE (UPER)", td->name);
1100
1101         /* Handle extensions */
1102         if(specs->first_extension < 0) {
1103                 extpresent = 0;
1104         } else {
1105                 extpresent = per_get_few_bits(pd, 1);
1106                 if(extpresent < 0) ASN__DECODE_STARVED;
1107         }
1108
1109         /* Prepare a place and read-in the presence bitmap */
1110         memset(&opmd, 0, sizeof(opmd));
1111         if(specs->roms_count) {
1112                 opres = (uint8_t *)MALLOC(((specs->roms_count + 7) >> 3) + 1);
1113                 if(!opres) ASN__DECODE_FAILED;
1114                 /* Get the presence map */
1115                 if(per_get_many_bits(pd, opres, 0, specs->roms_count)) {
1116                         FREEMEM(opres);
1117                         ASN__DECODE_STARVED;
1118                 }
1119                 opmd.buffer = opres;
1120                 opmd.nbits = specs->roms_count;
1121                 ASN_DEBUG("Read in presence bitmap for %s of %d bits (%x..)",
1122                         td->name, specs->roms_count, *opres);
1123         } else {
1124                 opres = 0;
1125         }
1126
1127         /*
1128          * Get the sequence ROOT elements.
1129          */
1130     for(edx = 0;
1131         edx < (specs->first_extension < 0 ? td->elements_count
1132                                           : (size_t)specs->first_extension);
1133         edx++) {
1134         asn_TYPE_member_t *elm = &td->elements[edx];
1135                 void *memb_ptr;         /* Pointer to the member */
1136                 void **memb_ptr2;       /* Pointer to that pointer */
1137
1138                 assert(!IN_EXTENSION_GROUP(specs, edx));
1139
1140                 /* Fetch the pointer to this member */
1141                 if(elm->flags & ATF_POINTER) {
1142                         memb_ptr2 = (void **)((char *)st + elm->memb_offset);
1143                 } else {
1144                         memb_ptr = (char *)st + elm->memb_offset;
1145                         memb_ptr2 = &memb_ptr;
1146                 }
1147
1148                 /* Deal with optionality */
1149                 if(elm->optional) {
1150                         int present = per_get_few_bits(&opmd, 1);
1151                         ASN_DEBUG("Member %s->%s is optional, p=%d (%d->%d)",
1152                                 td->name, elm->name, present,
1153                                 (int)opmd.nboff, (int)opmd.nbits);
1154                         if(present == 0) {
1155                                 /* This element is not present */
1156                                 if(elm->default_value_set) {
1157                                         /* Fill-in DEFAULT */
1158                                         if(elm->default_value_set(memb_ptr2)) {
1159                                                 FREEMEM(opres);
1160                                                 ASN__DECODE_FAILED;
1161                                         }
1162                                         ASN_DEBUG("Filled-in default");
1163                                 }
1164                                 /* The member is just not present */
1165                                 continue;
1166                         }
1167                         /* Fall through */
1168                 }
1169
1170                 /* Fetch the member from the stream */
1171                 ASN_DEBUG("Decoding member \"%s\" in %s", elm->name, td->name);
1172
1173                 if(elm->flags & ATF_OPEN_TYPE) {
1174                         rv = OPEN_TYPE_uper_get(opt_codec_ctx, td, st, elm, pd);
1175                 } else {
1176                         rv = elm->type->op->uper_decoder(opt_codec_ctx, elm->type,
1177                                         elm->encoding_constraints.per_constraints, memb_ptr2, pd);
1178                 }
1179                 if(rv.code != RC_OK) {
1180                         ASN_DEBUG("Failed decode %s in %s",
1181                                 elm->name, td->name);
1182                         FREEMEM(opres);
1183                         return rv;
1184                 }
1185         }
1186
1187         /* Optionality map is not needed anymore */
1188         FREEMEM(opres);
1189
1190         /*
1191          * Deal with extensions.
1192          */
1193         if(extpresent) {
1194                 ssize_t bmlength;
1195                 uint8_t *epres;         /* Presence of extension members */
1196                 asn_per_data_t epmd;
1197
1198                 bmlength = uper_get_nslength(pd);
1199                 if(bmlength < 0) ASN__DECODE_STARVED;
1200
1201                 ASN_DEBUG("Extensions %" ASN_PRI_SSIZE " present in %s", bmlength, td->name);
1202
1203                 epres = (uint8_t *)MALLOC((bmlength + 15) >> 3);
1204                 if(!epres) ASN__DECODE_STARVED;
1205
1206                 /* Get the extensions map */
1207                 if(per_get_many_bits(pd, epres, 0, bmlength)) {
1208                         FREEMEM(epres);
1209                         ASN__DECODE_STARVED;
1210                 }
1211
1212                 memset(&epmd, 0, sizeof(epmd));
1213                 epmd.buffer = epres;
1214                 epmd.nbits = bmlength;
1215                 ASN_DEBUG("Read in extensions bitmap for %s of %ld bits (%x..)",
1216                         td->name, (long)bmlength, *epres);
1217
1218             /* Go over extensions and read them in */
1219         for(edx = specs->first_extension; edx < td->elements_count; edx++) {
1220             asn_TYPE_member_t *elm = &td->elements[edx];
1221             void *memb_ptr;   /* Pointer to the member */
1222             void **memb_ptr2; /* Pointer to that pointer */
1223             int present;
1224
1225             /* Fetch the pointer to this member */
1226             if(elm->flags & ATF_POINTER) {
1227                 memb_ptr2 = (void **)((char *)st + elm->memb_offset);
1228             } else {
1229                 memb_ptr = (void *)((char *)st + elm->memb_offset);
1230                 memb_ptr2 = &memb_ptr;
1231             }
1232
1233             present = per_get_few_bits(&epmd, 1);
1234             if(present <= 0) {
1235                 if(present < 0) break; /* No more extensions */
1236                 continue;
1237             }
1238
1239             ASN_DEBUG("Decoding member %s in %s %p", elm->name, td->name,
1240                       *memb_ptr2);
1241             rv = uper_open_type_get(opt_codec_ctx, elm->type,
1242                                     elm->encoding_constraints.per_constraints,
1243                                     memb_ptr2, pd);
1244             if(rv.code != RC_OK) {
1245                 FREEMEM(epres);
1246                 return rv;
1247             }
1248             }
1249
1250                 /* Skip over overflow extensions which aren't present
1251                  * in this system's version of the protocol */
1252                 for(;;) {
1253                         ASN_DEBUG("Getting overflow extensions");
1254                         switch(per_get_few_bits(&epmd, 1)) {
1255                         case -1: break;
1256                         case 0: continue;
1257                         default:
1258                                 if(uper_open_type_skip(opt_codec_ctx, pd)) {
1259                                         FREEMEM(epres);
1260                                         ASN__DECODE_STARVED;
1261                                 }
1262                 ASN_DEBUG("Skipped overflow extension");
1263                 continue;
1264                         }
1265                         break;
1266                 }
1267
1268                 FREEMEM(epres);
1269         }
1270
1271     if(specs->first_extension >= 0) {
1272         unsigned i;
1273         /* Fill DEFAULT members in extensions */
1274         for(i = specs->roms_count; i < specs->roms_count + specs->aoms_count;
1275             i++) {
1276             asn_TYPE_member_t *elm;
1277             void **memb_ptr2; /* Pointer to member pointer */
1278
1279             edx = specs->oms[i];
1280             elm = &td->elements[edx];
1281
1282             if(!elm->default_value_set) continue;
1283
1284             /* Fetch the pointer to this member */
1285             if(elm->flags & ATF_POINTER) {
1286                 memb_ptr2 = (void **)((char *)st + elm->memb_offset);
1287                 if(*memb_ptr2) continue;
1288             } else {
1289                 continue; /* Extensions are all optionals */
1290             }
1291
1292             /* Set default value */
1293             if(elm->default_value_set(memb_ptr2)) {
1294                 ASN__DECODE_FAILED;
1295             }
1296         }
1297     }
1298
1299         rv.consumed = 0;
1300         rv.code = RC_OK;
1301         return rv;
1302 }
1303
1304 static int
1305 SEQUENCE__handle_extensions(const asn_TYPE_descriptor_t *td, const void *sptr,
1306                             asn_per_outp_t *po1, asn_per_outp_t *po2) {
1307     const asn_SEQUENCE_specifics_t *specs =
1308         (const asn_SEQUENCE_specifics_t *)td->specifics;
1309     int exts_present = 0;
1310     int exts_count = 0;
1311     size_t edx;
1312
1313     if(specs->first_extension < 0) {
1314         return 0;
1315     }
1316
1317     /* Find out which extensions are present */
1318     for(edx = specs->first_extension; edx < td->elements_count; edx++) {
1319         asn_TYPE_member_t *elm = &td->elements[edx];
1320         const void *memb_ptr;         /* Pointer to the member */
1321         const void *const *memb_ptr2; /* Pointer to that pointer */
1322         int present;
1323
1324         /* Fetch the pointer to this member */
1325         if(elm->flags & ATF_POINTER) {
1326             memb_ptr2 =
1327                 (const void *const *)((const char *)sptr + elm->memb_offset);
1328             present = (*memb_ptr2 != 0);
1329         } else {
1330             memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
1331             memb_ptr2 = &memb_ptr;
1332                         present = 1;
1333                 }
1334
1335         ASN_DEBUG("checking %s:%s (@%" ASN_PRI_SIZE ") present => %d", elm->name,
1336                   elm->type->name, edx, present);
1337         exts_count++;
1338         exts_present += present;
1339
1340         /* Encode as presence marker */
1341         if(po1 && per_put_few_bits(po1, present, 1)) {
1342             return -1;
1343         }
1344         /* Encode as open type field */
1345         if(po2 && present
1346            && uper_open_type_put(elm->type,
1347                                  elm->encoding_constraints.per_constraints,
1348                                  *memb_ptr2, po2))
1349             return -1;
1350     }
1351
1352     return exts_present ? exts_count : 0;
1353 }
1354
1355 asn_enc_rval_t
1356 SEQUENCE_encode_uper(const asn_TYPE_descriptor_t *td,
1357                      const asn_per_constraints_t *constraints, const void *sptr,
1358                      asn_per_outp_t *po) {
1359     const asn_SEQUENCE_specifics_t *specs
1360                 = (const asn_SEQUENCE_specifics_t *)td->specifics;
1361         asn_enc_rval_t er = {0,0,0};
1362         int n_extensions;
1363         size_t edx;
1364         size_t i;
1365
1366         (void)constraints;
1367
1368         if(!sptr)
1369                 ASN__ENCODE_FAILED;
1370
1371         er.encoded = 0;
1372
1373         ASN_DEBUG("Encoding %s as SEQUENCE (UPER)", td->name);
1374
1375         /*
1376          * X.691#18.1 Whether structure is extensible
1377          * and whether to encode extensions
1378          */
1379     if(specs->first_extension < 0) {
1380         n_extensions = 0; /* There are no extensions to encode */
1381     } else {
1382         n_extensions = SEQUENCE__handle_extensions(td, sptr, 0, 0);
1383         if(n_extensions < 0) ASN__ENCODE_FAILED;
1384         if(per_put_few_bits(po, n_extensions ? 1 : 0, 1)) {
1385             ASN__ENCODE_FAILED;
1386         }
1387     }
1388
1389         /* Encode a presence bitmap */
1390         for(i = 0; i < specs->roms_count; i++) {
1391                 asn_TYPE_member_t *elm;
1392                 const void *memb_ptr;           /* Pointer to the member */
1393         const void *const *memb_ptr2; /* Pointer to that pointer */
1394         int present;
1395
1396                 edx = specs->oms[i];
1397                 elm = &td->elements[edx];
1398
1399                 /* Fetch the pointer to this member */
1400                 if(elm->flags & ATF_POINTER) {
1401             memb_ptr2 =
1402                 (const void *const *)((const char *)sptr + elm->memb_offset);
1403             present = (*memb_ptr2 != 0);
1404                 } else {
1405             memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
1406             memb_ptr2 = &memb_ptr;
1407                         present = 1;
1408                 }
1409
1410                 /* Eliminate default values */
1411         if(present && elm->default_value_cmp
1412            && elm->default_value_cmp(*memb_ptr2) == 0)
1413             present = 0;
1414
1415                 ASN_DEBUG("Element %s %s %s->%s is %s",
1416                         elm->flags & ATF_POINTER ? "ptr" : "inline",
1417                         elm->default_value_cmp ? "def" : "wtv",
1418                         td->name, elm->name, present ? "present" : "absent");
1419                 if(per_put_few_bits(po, present, 1))
1420                         ASN__ENCODE_FAILED;
1421         }
1422
1423         /*
1424          * Encode the sequence ROOT elements.
1425          */
1426     ASN_DEBUG("first_extension = %d, elements = %d", specs->first_extension,
1427               td->elements_count);
1428         for(edx = 0;
1429                 edx < ((specs->first_extension < 0) ? td->elements_count
1430                                             : (size_t)specs->first_extension);
1431                 edx++) {
1432                 asn_TYPE_member_t *elm = &td->elements[edx];
1433                 const void *memb_ptr;         /* Pointer to the member */
1434                 const void *const *memb_ptr2; /* Pointer to that pointer */
1435
1436                 ASN_DEBUG("About to encode %s", elm->type->name);
1437
1438                 /* Fetch the pointer to this member */
1439                 if(elm->flags & ATF_POINTER) {
1440             memb_ptr2 =
1441                 (const void *const *)((const char *)sptr + elm->memb_offset);
1442             if(!*memb_ptr2) {
1443                                 ASN_DEBUG("Element %s %" ASN_PRI_SIZE " not present",
1444                                         elm->name, edx);
1445                                 if(elm->optional)
1446                                         continue;
1447                                 /* Mandatory element is missing */
1448                                 ASN__ENCODE_FAILED;
1449                         }
1450                 } else {
1451             memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
1452             memb_ptr2 = &memb_ptr;
1453                 }
1454
1455                 /* Eliminate default values */
1456                 if(elm->default_value_cmp && elm->default_value_cmp(*memb_ptr2) == 0)
1457                         continue;
1458
1459         ASN_DEBUG("Encoding %s->%s:%s", td->name, elm->name, elm->type->name);
1460         er = elm->type->op->uper_encoder(
1461             elm->type, elm->encoding_constraints.per_constraints, *memb_ptr2,
1462             po);
1463         if(er.encoded == -1) return er;
1464     }
1465
1466         /* No extensions to encode */
1467         if(!n_extensions) ASN__ENCODED_OK(er);
1468
1469         ASN_DEBUG("Length of extensions %d bit-map", n_extensions);
1470         /* #18.8. Write down the presence bit-map length. */
1471         if(uper_put_nslength(po, n_extensions))
1472                 ASN__ENCODE_FAILED;
1473
1474         ASN_DEBUG("Bit-map of %d elements", n_extensions);
1475         /* #18.7. Encoding the extensions presence bit-map. */
1476         /* TODO: act upon NOTE in #18.7 for canonical PER */
1477         if(SEQUENCE__handle_extensions(td, sptr, po, 0) != n_extensions)
1478                 ASN__ENCODE_FAILED;
1479
1480         ASN_DEBUG("Writing %d extensions", n_extensions);
1481         /* #18.9. Encode extensions as open type fields. */
1482         if(SEQUENCE__handle_extensions(td, sptr, 0, po) != n_extensions)
1483                 ASN__ENCODE_FAILED;
1484
1485         ASN__ENCODED_OK(er);
1486 }
1487
1488 asn_dec_rval_t
1489 SEQUENCE_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
1490                      const asn_TYPE_descriptor_t *td,
1491                      const asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
1492         const asn_SEQUENCE_specifics_t *specs = (const asn_SEQUENCE_specifics_t *)td->specifics;
1493         void *st = *sptr;       /* Target structure. */
1494         int extpresent;         /* Extension additions are present */
1495         uint8_t *opres;         /* Presence of optional root members */
1496         asn_per_data_t opmd;
1497         asn_dec_rval_t rv;
1498         size_t edx;
1499
1500         (void)constraints;
1501
1502         if(ASN__STACK_OVERFLOW_CHECK(opt_codec_ctx))
1503                 ASN__DECODE_FAILED;
1504
1505         if(!st) {
1506                 st = *sptr = CALLOC(1, specs->struct_size);
1507                 if(!st) ASN__DECODE_FAILED;
1508         }
1509
1510         ASN_DEBUG("Decoding %s as SEQUENCE (APER)", td->name);
1511
1512         /* Handle extensions */
1513         if(specs->first_extension < 0) {
1514                 extpresent = 0;
1515         } else {
1516                 extpresent = per_get_few_bits(pd, 1);
1517                 if(extpresent < 0) ASN__DECODE_STARVED;
1518         }
1519
1520         /* Prepare a place and read-in the presence bitmap */
1521         memset(&opmd, 0, sizeof(opmd));
1522         if(specs->roms_count) {
1523                 opres = (uint8_t *)MALLOC(((specs->roms_count + 7) >> 3) + 1);
1524                 if(!opres) ASN__DECODE_FAILED;
1525                 /* Get the presence map */
1526                 if(per_get_many_bits(pd, opres, 0, specs->roms_count)) {
1527                         FREEMEM(opres);
1528                         ASN__DECODE_STARVED;
1529                 }
1530                 opmd.buffer = opres;
1531                 opmd.nbits = specs->roms_count;
1532                 ASN_DEBUG("Read in presence bitmap for %s of %d bits (%x..)",
1533                           td->name, specs->roms_count, *opres);
1534         } else {
1535                 opres = 0;
1536         }
1537
1538         /*
1539          * Get the sequence ROOT elements.
1540          */
1541         for(edx = 0; edx < td->elements_count; edx++) {
1542                 asn_TYPE_member_t *elm = &td->elements[edx];
1543                 void *memb_ptr;         /* Pointer to the member */
1544                 void **memb_ptr2;       /* Pointer to that pointer */
1545 #if 0
1546                 int padding;
1547 #endif
1548
1549                 if(IN_EXTENSION_GROUP(specs, edx))
1550                         continue;
1551
1552                 /* Fetch the pointer to this member */
1553                 if(elm->flags & ATF_POINTER) {
1554                         memb_ptr2 = (void **)((char *)st + elm->memb_offset);
1555                 } else {
1556                         memb_ptr = (char *)st + elm->memb_offset;
1557                         memb_ptr2 = &memb_ptr;
1558                 }
1559 #if 0
1560                 /* Get Padding */
1561                 padding = (8 - (pd->moved % 8)) % 8;
1562                 if(padding > 0)
1563                         ASN_DEBUG("For element %s,offset= %ld Padding bits = %d", td->name, pd->moved, padding);
1564 #if 0 /* old way of removing padding */
1565                 per_get_few_bits(pd, padding);
1566 #else /* Experimental fix proposed by @mhanna123 */
1567                 if(edx != (td->elements_count-1))
1568                         per_get_few_bits(pd, padding);
1569                 else {
1570                         if(specs->roms_count && (padding > 0))
1571                                 ASN_DEBUG(">>>>> not skipping padding of %d bits for element:%ld out of %d", padding, edx, td->elements_count);
1572                         else
1573                                 per_get_few_bits(pd, padding);
1574                 }
1575 #endif /* dealing with padding */
1576 #endif
1577                 /* Deal with optionality */
1578                 if(elm->optional) {
1579                         int present = per_get_few_bits(&opmd, 1);
1580                         ASN_DEBUG("Member %s->%s is optional, p=%d (%d->%d)",
1581                                   td->name, elm->name, present,
1582                                   (int)opmd.nboff, (int)opmd.nbits);
1583                         if(present == 0) {
1584                                 /* This element is not present */
1585                                 if(elm->default_value_set) {
1586                                         /* Fill-in DEFAULT */
1587                                         if(elm->default_value_set(memb_ptr2)) {
1588                                                 FREEMEM(opres);
1589                                                 ASN__DECODE_FAILED;
1590                                         }
1591                                         ASN_DEBUG("Filled-in default");
1592                                 }
1593                                 /* The member is just not present */
1594                                 continue;
1595                         }
1596                         /* Fall through */
1597                 }
1598
1599                 /* Fetch the member from the stream */
1600                 ASN_DEBUG("Decoding member \"%s\" in %s", elm->name, td->name);
1601
1602                 if(elm->flags & ATF_OPEN_TYPE) {
1603                         rv = OPEN_TYPE_aper_get(opt_codec_ctx, td, st, elm, pd);
1604                 } else {
1605                         rv = elm->type->op->aper_decoder(opt_codec_ctx, elm->type,
1606                                         elm->encoding_constraints.per_constraints, memb_ptr2, pd);
1607                 }
1608                 if(rv.code != RC_OK) {
1609                         ASN_DEBUG("Failed decode %s in %s",
1610                                   elm->name, td->name);
1611                         FREEMEM(opres);
1612                         return rv;
1613                 }
1614         }
1615
1616         /* Optionality map is not needed anymore */
1617         FREEMEM(opres);
1618
1619         /*
1620          * Deal with extensions.
1621          */
1622         if(extpresent) {
1623                 ssize_t bmlength;
1624                 uint8_t *epres;         /* Presence of extension members */
1625                 asn_per_data_t epmd;
1626
1627                 bmlength = aper_get_nslength(pd);
1628                 if(bmlength < 0) ASN__DECODE_STARVED;
1629
1630                 ASN_DEBUG("Extensions %" ASN_PRI_SSIZE " present in %s", bmlength, td->name);
1631
1632                 epres = (uint8_t *)MALLOC((bmlength + 15) >> 3);
1633                 if(!epres) ASN__DECODE_STARVED;
1634
1635                 /* Get the extensions map */
1636                 if(per_get_many_bits(pd, epres, 0, bmlength))
1637                         ASN__DECODE_STARVED;
1638
1639                 memset(&epmd, 0, sizeof(epmd));
1640                 epmd.buffer = epres;
1641                 epmd.nbits = bmlength;
1642                 ASN_DEBUG("Read in extensions bitmap for %s of %ld bits (%x..)",
1643                           td->name, bmlength, *epres);
1644
1645                 /* Go over extensions and read them in */
1646                 for(edx = specs->first_extension; edx < td->elements_count; edx++) {
1647                         asn_TYPE_member_t *elm = &td->elements[edx];
1648                         void *memb_ptr;         /* Pointer to the member */
1649                         void **memb_ptr2;       /* Pointer to that pointer */
1650                         int present;
1651
1652                         if(!IN_EXTENSION_GROUP(specs, edx)) {
1653                                 ASN_DEBUG("%ld is not extension", edx);
1654                                 continue;
1655                         }
1656
1657                         /* Fetch the pointer to this member */
1658                         if(elm->flags & ATF_POINTER) {
1659                                 memb_ptr2 = (void **)((char *)st + elm->memb_offset);
1660                         } else {
1661                                 memb_ptr = (void *)((char *)st + elm->memb_offset);
1662                                 memb_ptr2 = &memb_ptr;
1663                         }
1664
1665                         present = per_get_few_bits(&epmd, 1);
1666                         if(present <= 0) {
1667                                 if(present < 0) break;  /* No more extensions */
1668                                 continue;
1669                         }
1670
1671                         ASN_DEBUG("Decoding member %s in %s %p", elm->name, td->name, *memb_ptr2);
1672                         rv = aper_open_type_get(opt_codec_ctx, elm->type,
1673                                                 elm->encoding_constraints.per_constraints, memb_ptr2, pd);
1674                         if(rv.code != RC_OK) {
1675                                 FREEMEM(epres);
1676                                 return rv;
1677                         }
1678                 }
1679
1680                 /* Skip over overflow extensions which aren't present
1681                  * in this system's version of the protocol */
1682                 for(;;) {
1683                         ASN_DEBUG("Getting overflow extensions");
1684                         switch(per_get_few_bits(&epmd, 1)) {
1685                         case -1:
1686                                 break;
1687                         case 0:
1688                                 continue;
1689                         default:
1690                                 if(aper_open_type_skip(opt_codec_ctx, pd)) {
1691                                         FREEMEM(epres);
1692                                         ASN__DECODE_STARVED;
1693                                 }
1694                         }
1695                         break;
1696                 }
1697
1698                 FREEMEM(epres);
1699         }
1700
1701         /* Fill DEFAULT members in extensions */
1702         for(edx = specs->roms_count; edx < specs->roms_count
1703                 + specs->aoms_count; edx++) {
1704                 asn_TYPE_member_t *elm = &td->elements[edx];
1705                 void **memb_ptr2;       /* Pointer to member pointer */
1706
1707                 if(!elm->default_value_set) continue;
1708
1709                 /* Fetch the pointer to this member */
1710                 if(elm->flags & ATF_POINTER) {
1711                         memb_ptr2 = (void **)((char *)st
1712                                               + elm->memb_offset);
1713                         if(*memb_ptr2) continue;
1714                 } else {
1715                         continue;       /* Extensions are all optionals */
1716                 }
1717
1718                 /* Set default value */
1719                 if(elm->default_value_set(memb_ptr2)) {
1720                         ASN__DECODE_FAILED;
1721                 }
1722         }
1723
1724         rv.consumed = 0;
1725         rv.code = RC_OK;
1726         return rv;
1727 }
1728
1729 static int
1730 SEQUENCE_handle_extensions_aper(const asn_TYPE_descriptor_t *td,
1731                                 const void *sptr,
1732                                 asn_per_outp_t *po1, asn_per_outp_t *po2) {
1733         const asn_SEQUENCE_specifics_t *specs
1734             = (const asn_SEQUENCE_specifics_t *)td->specifics;
1735         int exts_present = 0;
1736         int exts_count = 0;
1737         size_t edx;
1738
1739         if(specs->first_extension < 0) {
1740                 return 0;
1741         }
1742
1743         /* Find out which extensions are present */
1744         for(edx = specs->first_extension; edx < td->elements_count; edx++) {
1745                 asn_TYPE_member_t *elm = &td->elements[edx];
1746                 const void *memb_ptr;           /* Pointer to the member */
1747                 const void * const *memb_ptr2;  /* Pointer to that pointer */
1748                 int present;
1749
1750                 if(!IN_EXTENSION_GROUP(specs, edx)) {
1751                         ASN_DEBUG("%s (@%ld) is not extension", elm->type->name, edx);
1752                         continue;
1753                 }
1754
1755                 /* Fetch the pointer to this member */
1756                 if(elm->flags & ATF_POINTER) {
1757                         memb_ptr2 = (const void * const *)((const char *)sptr + elm->memb_offset);
1758                         present = (*memb_ptr2 != 0);
1759                 } else {
1760                         memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
1761                         memb_ptr2 = &memb_ptr;
1762                         present = 1;
1763                 }
1764
1765                 ASN_DEBUG("checking %s (@%ld) present => %d",
1766                           elm->type->name, edx, present);
1767                 exts_count++;
1768                 exts_present += present;
1769
1770                 /* Encode as presence marker */
1771                 if(po1 && per_put_few_bits(po1, present, 1))
1772                         return -1;
1773                 /* Encode as open type field */
1774                 if(po2 && present && aper_open_type_put(elm->type,
1775                                                         elm->encoding_constraints.per_constraints, *memb_ptr2, po2))
1776                         return -1;
1777
1778         }
1779
1780         return exts_present ? exts_count : 0;
1781 }
1782
1783 asn_enc_rval_t
1784 SEQUENCE_encode_aper(const asn_TYPE_descriptor_t *td,
1785                      const asn_per_constraints_t *constraints,
1786                      const void *sptr, asn_per_outp_t *po) {
1787         const asn_SEQUENCE_specifics_t *specs
1788             = (const asn_SEQUENCE_specifics_t *)td->specifics;
1789         asn_enc_rval_t er = {0,0,0};
1790         int n_extensions;
1791         size_t edx;
1792         size_t i;
1793
1794         (void)constraints;
1795
1796         if(!sptr)
1797                 ASN__ENCODE_FAILED;
1798
1799         er.encoded = 0;
1800
1801         ASN_DEBUG("Encoding %s as SEQUENCE (APER)", td->name);
1802
1803         /*
1804          * X.691#18.1 Whether structure is extensible
1805          * and whether to encode extensions
1806          */
1807         if(specs->first_extension < 0) {
1808                 n_extensions = 0; /* There are no extensions to encode */
1809         } else {
1810                 n_extensions = SEQUENCE_handle_extensions_aper(td, sptr, 0, 0);
1811                 if(n_extensions < 0) ASN__ENCODE_FAILED;
1812                 if(per_put_few_bits(po, n_extensions ? 1 : 0, 1)) {
1813                         ASN__ENCODE_FAILED;
1814                 }
1815         }
1816
1817         /* Encode a presence bitmap */
1818         for(i = 0; i < specs->roms_count; i++) {
1819                 asn_TYPE_member_t *elm;
1820                 const void *memb_ptr;    /* Pointer to the member */
1821                 const void * const *memb_ptr2;       /* Pointer to that pointer */
1822                 int present;
1823
1824                 edx = specs->oms[i];
1825                 elm = &td->elements[edx];
1826
1827                 /* Fetch the pointer to this member */
1828                 if(elm->flags & ATF_POINTER) {
1829                         memb_ptr2 = (const void * const *)((const char *)sptr + elm->memb_offset);
1830                         present = (*memb_ptr2 != 0);
1831                 } else {
1832                         memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
1833                         memb_ptr2 = &memb_ptr;
1834                         present = 1;
1835                 }
1836
1837                 /* Eliminate default values */
1838                 if(present && elm->default_value_cmp
1839                         && elm->default_value_cmp(memb_ptr2) == 1)
1840                         present = 0;
1841
1842                 ASN_DEBUG("Element %s %s %s->%s is %s",
1843                           elm->flags & ATF_POINTER ? "ptr" : "inline",
1844                           elm->default_value_cmp ? "def" : "wtv",
1845                           td->name, elm->name, present ? "present" : "absent");
1846                 if(per_put_few_bits(po, present, 1))
1847                         ASN__ENCODE_FAILED;
1848         }
1849
1850         /*
1851          * Encode the sequence ROOT elements.
1852          */
1853         ASN_DEBUG("first_extension = %d, elements = %d", specs->first_extension,
1854               td->elements_count);
1855         for(edx = 0;
1856                 edx < ((specs->first_extension < 0) ? td->elements_count
1857                                             : (size_t)specs->first_extension);
1858                 edx++) {
1859                 asn_TYPE_member_t *elm = &td->elements[edx];
1860                 const void *memb_ptr;          /* Pointer to the member */
1861                 const void * const *memb_ptr2; /* Pointer to that pointer */
1862
1863                 if(IN_EXTENSION_GROUP(specs, edx))
1864                         continue;
1865
1866                 ASN_DEBUG("About to encode %s", elm->type->name);
1867
1868                 /* Fetch the pointer to this member */
1869                 if(elm->flags & ATF_POINTER) {
1870                         memb_ptr2 = (const void * const *)((const char *)sptr + elm->memb_offset);
1871                         if(!*memb_ptr2) {
1872                                 ASN_DEBUG("Element %s %ld not present",
1873                                           elm->name, edx);
1874                                 if(elm->optional)
1875                                         continue;
1876                                 /* Mandatory element is missing */
1877                                 ASN__ENCODE_FAILED;
1878                         }
1879                 } else {
1880                         memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
1881                         memb_ptr2 = &memb_ptr;
1882                 }
1883
1884                 /* Eliminate default values */
1885                 if(elm->default_value_cmp && elm->default_value_cmp(memb_ptr2) == 1)
1886                         continue;
1887
1888                 ASN_DEBUG("Encoding %s->%s", td->name, elm->name);
1889                 er = elm->type->op->aper_encoder(elm->type, elm->encoding_constraints.per_constraints,
1890                                                  *memb_ptr2, po);
1891                 if(er.encoded == -1)
1892                         return er;
1893         }
1894
1895         /* No extensions to encode */
1896         if(!n_extensions) ASN__ENCODED_OK(er);
1897
1898         ASN_DEBUG("Length of %d bit-map", n_extensions);
1899         /* #18.8. Write down the presence bit-map length. */
1900         if(aper_put_nslength(po, n_extensions))
1901                 ASN__ENCODE_FAILED;
1902
1903         ASN_DEBUG("Bit-map of %d elements", n_extensions);
1904         /* #18.7. Encoding the extensions presence bit-map. */
1905         /* TODO: act upon NOTE in #18.7 for canonical PER */
1906         if(SEQUENCE_handle_extensions_aper(td, sptr, po, 0) != n_extensions)
1907                 ASN__ENCODE_FAILED;
1908
1909         ASN_DEBUG("Writing %d extensions", n_extensions);
1910         /* #18.9. Encode extensions as open type fields. */
1911         if(SEQUENCE_handle_extensions_aper(td, sptr, 0, po) != n_extensions)
1912                 ASN__ENCODE_FAILED;
1913
1914         ASN__ENCODED_OK(er);
1915 }
1916
1917 #endif  /* ASN_DISABLE_PER_SUPPORT */
1918
1919 int
1920 SEQUENCE_compare(const asn_TYPE_descriptor_t *td, const void *aptr,
1921                  const void *bptr) {
1922     size_t edx;
1923
1924         for(edx = 0; edx < td->elements_count; edx++) {
1925                 asn_TYPE_member_t *elm = &td->elements[edx];
1926                 const void *amemb;
1927                 const void *bmemb;
1928         int ret;
1929
1930                 if(elm->flags & ATF_POINTER) {
1931             amemb =
1932                 *(const void *const *)((const char *)aptr + elm->memb_offset);
1933             bmemb =
1934                 *(const void *const *)((const char *)bptr + elm->memb_offset);
1935             if(!amemb) {
1936                 if(!bmemb) continue;
1937                 if(elm->default_value_cmp
1938                    && elm->default_value_cmp(bmemb) == 0) {
1939                     /* A is absent, but B is present and equal to DEFAULT */
1940                     continue;
1941                 }
1942                 return -1;
1943             } else if(!bmemb) {
1944                 if(elm->default_value_cmp
1945                    && elm->default_value_cmp(amemb) == 0) {
1946                     /* B is absent, but A is present and equal to DEFAULT */
1947                     continue;
1948                 }
1949                 return 1;
1950             }
1951                 } else {
1952             amemb = (const void *)((const char *)aptr + elm->memb_offset);
1953             bmemb = (const void *)((const char *)bptr + elm->memb_offset);
1954                 }
1955
1956         ret = elm->type->op->compare_struct(elm->type, amemb, bmemb);
1957         if(ret != 0) return ret;
1958     }
1959
1960     return 0;
1961 }
1962
1963 asn_TYPE_operation_t asn_OP_SEQUENCE = {
1964         SEQUENCE_free,
1965         SEQUENCE_print,
1966         SEQUENCE_compare,
1967         SEQUENCE_decode_ber,
1968         SEQUENCE_encode_der,
1969         SEQUENCE_decode_xer,
1970         SEQUENCE_encode_xer,
1971 #ifdef  ASN_DISABLE_OER_SUPPORT
1972         0,
1973         0,
1974 #else
1975         SEQUENCE_decode_oer,
1976         SEQUENCE_encode_oer,
1977 #endif  /* ASN_DISABLE_OER_SUPPORT */
1978 #ifdef ASN_DISABLE_PER_SUPPORT
1979         0,
1980         0,
1981         0,
1982         0,
1983 #else
1984         SEQUENCE_decode_uper,
1985         SEQUENCE_encode_uper,
1986         SEQUENCE_decode_aper,
1987         SEQUENCE_encode_aper,
1988 #endif /* ASN_DISABLE_PER_SUPPORT */
1989         SEQUENCE_random_fill,
1990         0       /* Use generic outmost tag fetcher */
1991 };
1992
1993
1994 asn_random_fill_result_t
1995 SEQUENCE_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
1996                    const asn_encoding_constraints_t *constr,
1997                    size_t max_length) {
1998     const asn_SEQUENCE_specifics_t *specs =
1999         (const asn_SEQUENCE_specifics_t *)td->specifics;
2000     asn_random_fill_result_t result_ok = {ARFILL_OK, 0};
2001     asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
2002     asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
2003     void *st = *sptr;
2004     size_t edx;
2005
2006     if(max_length == 0) return result_skipped;
2007
2008     (void)constr;
2009
2010     if(st == NULL) {
2011         st = CALLOC(1, specs->struct_size);
2012         if(st == NULL) {
2013             return result_failed;
2014         }
2015     }
2016
2017     for(edx = 0; edx < td->elements_count; edx++) {
2018         const asn_TYPE_member_t *elm = &td->elements[edx];
2019         void *memb_ptr;   /* Pointer to the member */
2020         void **memb_ptr2; /* Pointer to that pointer */
2021         asn_random_fill_result_t tmpres;
2022
2023         if(elm->optional && asn_random_between(0, 4) == 2) {
2024             /* Sometimes decide not to fill the optional value */
2025             continue;
2026         }
2027
2028         if(elm->flags & ATF_POINTER) {
2029             /* Member is a pointer to another structure */
2030             memb_ptr2 = (void **)((char *)st + elm->memb_offset);
2031         } else {
2032             memb_ptr = (char *)st + elm->memb_offset;
2033             memb_ptr2 = &memb_ptr;
2034         }
2035
2036         tmpres = elm->type->op->random_fill(
2037             elm->type, memb_ptr2, &elm->encoding_constraints,
2038             max_length > result_ok.length ? max_length - result_ok.length : 0);
2039         switch(tmpres.code) {
2040         case ARFILL_OK:
2041             result_ok.length += tmpres.length;
2042             continue;
2043         case ARFILL_SKIPPED:
2044             assert(!(elm->flags & ATF_POINTER) || *memb_ptr2 == NULL);
2045             continue;
2046         case ARFILL_FAILED:
2047             if(st == *sptr) {
2048                 ASN_STRUCT_RESET(*td, st);
2049             } else {
2050                 ASN_STRUCT_FREE(*td, st);
2051             }
2052             return tmpres;
2053         }
2054     }
2055
2056     *sptr = st;
2057
2058     return result_ok;
2059 }
2060