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