2  * Copyright (c) 2003-2017 Lev Walkin <vlm@lionet.info>.
 
   4  * Redistribution and modifications are permitted subject to BSD license.
 
   6 #include <asn_internal.h>
 
   7 #include <constr_SEQUENCE.h>
 
   9 #include <per_opentype.h>
 
  12  * Number of bytes left for this structure.
 
  13  * (ctx->left) indicates the number of bytes _transferred_ for the structure.
 
  14  * (size) contains the number of bytes in the buffer passed.
 
  16 #define LEFT    ((size<(size_t)ctx->left)?size:(size_t)ctx->left)
 
  19  * If the subprocessor function returns with an indication that it wants
 
  20  * more data, it may well be a fatal decoding problem, because the
 
  21  * size is constrained by the <TLV>'s L, even if the buffer size allows
 
  23  * For example, consider the buffer containing the following TLVs:
 
  24  * <T:5><L:1><V> <T:6>...
 
  25  * The TLV length clearly indicates that one byte is expected in V, but
 
  26  * if the V processor returns with "want more data" even if the buffer
 
  27  * contains way more data than the V processor have seen.
 
  29 #define SIZE_VIOLATION  (ctx->left >= 0 && (size_t)ctx->left <= size)
 
  32  * This macro "eats" the part of the buffer which is definitely "consumed",
 
  33  * i.e. was correctly converted into local representation or rightfully skipped.
 
  36 #define ADVANCE(num_bytes)      do {            \
 
  37                 size_t num = num_bytes;         \
 
  38                 ptr = ((const char *)ptr) + num; \
 
  42                 consumed_myself += num;         \
 
  46  * Switch to the next phase of parsing.
 
  50 #define NEXT_PHASE(ctx) do {                    \
 
  54 #define PHASE_OUT(ctx)  do { ctx->phase = 10; } while(0)
 
  57  * Return a standardized complex structure.
 
  60 #define RETURN(_code)   do {                    \
 
  62                 rval.consumed = consumed_myself;\
 
  67  * Check whether we are inside the extensions group.
 
  69 #define IN_EXTENSION_GROUP(specs, memb_idx) \
 
  70     ((specs)->first_extension >= 0          \
 
  71      && (unsigned)(specs)->first_extension <= (memb_idx))
 
  74  * Tags are canonically sorted in the tag2element map.
 
  77 _t2e_cmp(const void *ap, const void *bp) {
 
  78         const asn_TYPE_tag2member_t *a = (const asn_TYPE_tag2member_t *)ap;
 
  79         const asn_TYPE_tag2member_t *b = (const asn_TYPE_tag2member_t *)bp;
 
  81         int a_class = BER_TAG_CLASS(a->el_tag);
 
  82         int b_class = BER_TAG_CLASS(b->el_tag);
 
  84         if(a_class == b_class) {
 
  85                 ber_tlv_tag_t a_value = BER_TAG_VALUE(a->el_tag);
 
  86                 ber_tlv_tag_t b_value = BER_TAG_VALUE(b->el_tag);
 
  88                 if(a_value == b_value) {
 
  89                         if(a->el_no > b->el_no)
 
  92                          * Important: we do not check
 
  93                          * for a->el_no <= b->el_no!
 
  96                 } else if(a_value < b_value)
 
 100         } else if(a_class < b_class) {
 
 109  * The decoder of the SEQUENCE type.
 
 112 SEQUENCE_decode_ber(const asn_codec_ctx_t *opt_codec_ctx,
 
 113                     const asn_TYPE_descriptor_t *td, void **struct_ptr,
 
 114                     const void *ptr, size_t size, int tag_mode) {
 
 116          * Bring closer parts of structure description.
 
 118         const asn_SEQUENCE_specifics_t *specs = (const asn_SEQUENCE_specifics_t *)td->specifics;
 
 119     const asn_TYPE_member_t *elements = td->elements;
 
 122          * Parts of the structure being constructed.
 
 124         void *st = *struct_ptr; /* Target structure. */
 
 125         asn_struct_ctx_t *ctx;  /* Decoder context */
 
 127         ber_tlv_tag_t tlv_tag;  /* T from TLV */
 
 128         asn_dec_rval_t rval;    /* Return code from subparsers */
 
 130         ssize_t consumed_myself = 0;    /* Consumed bytes from ptr */
 
 131         size_t edx;                     /* SEQUENCE element's index */
 
 133         ASN_DEBUG("Decoding %s as SEQUENCE", td->name);
 
 136          * Create the target structure if it is not present already.
 
 139                 st = *struct_ptr = CALLOC(1, specs->struct_size);
 
 146          * Restore parsing context.
 
 148         ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
 
 151          * Start to parse where left previously
 
 157                  * Check that the set of tags associated with given structure
 
 158                  * perfectly fits our expectations.
 
 161                 rval = ber_check_tags(opt_codec_ctx, td, ctx, ptr, size,
 
 162                         tag_mode, 1, &ctx->left, 0);
 
 163                 if(rval.code != RC_OK) {
 
 164                         ASN_DEBUG("%s tagging check failed: %d",
 
 165                                 td->name, rval.code);
 
 170                         ctx->left += rval.consumed; /* ?Substracted below! */
 
 171                 ADVANCE(rval.consumed);
 
 175                 ASN_DEBUG("Structure consumes %ld bytes, buffer %ld",
 
 176                         (long)ctx->left, (long)size);
 
 182                  * From the place where we've left it previously,
 
 183                  * try to decode the next member from the list of
 
 184                  * this structure's elements.
 
 185                  * (ctx->step) stores the member being processed
 
 186                  * between invocations and the microphase {0,1} of parsing
 
 188                  *      step = (<member_number> * 2 + <microphase>).
 
 190           for(edx = ((size_t)ctx->step >> 1); edx < td->elements_count;
 
 191                         edx++, ctx->step = (ctx->step & ~1) + 2) {
 
 192                 void *memb_ptr;         /* Pointer to the member */
 
 193                 void **memb_ptr2;       /* Pointer to that pointer */
 
 194                 ssize_t tag_len;        /* Length of TLV's T */
 
 195                 size_t opt_edx_end;     /* Next non-optional element */
 
 203                  * MICROPHASE 1: Synchronize decoding.
 
 205                 ASN_DEBUG("In %s SEQUENCE left %d, edx=%" ASN_PRI_SIZE " flags=%d"
 
 207                         td->name, (int)ctx->left, edx,
 
 208                         elements[edx].flags, elements[edx].optional,
 
 211         if(ctx->left == 0 /* No more stuff is expected */
 
 213                   /* Explicit OPTIONAL specification reaches the end */
 
 214                   (edx + elements[edx].optional == td->elements_count) ||
 
 215                   /* All extensions are optional */
 
 216                   IN_EXTENSION_GROUP(specs, edx))) {
 
 217             ASN_DEBUG("End of SEQUENCE %s", td->name);
 
 219              * Found the legitimate end of the structure.
 
 226                  * Fetch the T from TLV.
 
 228                 tag_len = ber_fetch_tag(ptr, LEFT, &tlv_tag);
 
 229                 ASN_DEBUG("Current tag in %s SEQUENCE for element %" ASN_PRI_SIZE " "
 
 230                         "(%s) is %s encoded in %d bytes, of frame %ld",
 
 231                         td->name, edx, elements[edx].name,
 
 232                         ber_tlv_tag_string(tlv_tag), (int)tag_len, (long)LEFT);
 
 234                 case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
 
 236                 case -1: RETURN(RC_FAIL);
 
 239         if(ctx->left < 0 && ((const uint8_t *)ptr)[0] == 0) {
 
 246             } else if(((const uint8_t *)ptr)[1] == 0) {
 
 247                 ASN_DEBUG("edx = %" ASN_PRI_SIZE ", opt = %d, ec=%d", edx,
 
 248                           elements[edx].optional, td->elements_count);
 
 249                 if((edx + elements[edx].optional == td->elements_count)
 
 250                    || IN_EXTENSION_GROUP(specs, edx)) {
 
 252                      * Yeah, baby! Found the terminator
 
 253                      * of the indefinite length structure.
 
 256                      * Proceed to the canonical
 
 257                      * finalization function.
 
 258                      * No advancing is necessary.
 
 266                  * Find the next available type with this tag.
 
 269                 opt_edx_end = edx + elements[edx].optional + 1;
 
 270                 if(opt_edx_end > td->elements_count)
 
 271                         opt_edx_end = td->elements_count;       /* Cap */
 
 272                 else if(opt_edx_end - edx > 8) {
 
 273                         /* Limit the scope of linear search... */
 
 274                         opt_edx_end = edx + 8;
 
 276                         /* ... and resort to bsearch() */
 
 278                 for(n = edx; n < opt_edx_end; n++) {
 
 279                         if(BER_TAGS_EQUAL(tlv_tag, elements[n].tag)) {
 
 281                                  * Found element corresponding to the tag
 
 283                                  * Reposition over the right element.
 
 286                                 ctx->step = 1 + 2 * edx;        /* Remember! */
 
 288                         } else if(elements[n].flags & ATF_ANY_TYPE) {
 
 290                                  * This is the ANY type, which may bear
 
 291                                  * any flag whatsoever.
 
 294                                 ctx->step = 1 + 2 * edx;        /* Remember! */
 
 296                         } else if(elements[n].tag == (ber_tlv_tag_t)-1) {
 
 303                          * Resort to a binary search over
 
 304                          * sorted array of tags.
 
 306                         const asn_TYPE_tag2member_t *t2m;
 
 307                         asn_TYPE_tag2member_t key = {0, 0, 0, 0};
 
 308                         key.el_tag = tlv_tag;
 
 310                         t2m = (const asn_TYPE_tag2member_t *)bsearch(&key,
 
 311                                 specs->tag2el, specs->tag2el_count,
 
 312                                 sizeof(specs->tag2el[0]), _t2e_cmp);
 
 314                                 const asn_TYPE_tag2member_t *best = 0;
 
 315                                 const asn_TYPE_tag2member_t *t2m_f, *t2m_l;
 
 316                                 size_t edx_max = edx + elements[edx].optional;
 
 318                                  * Rewind to the first element with that tag,
 
 319                                  * `cause bsearch() does not guarantee order.
 
 321                                 t2m_f = t2m + t2m->toff_first;
 
 322                                 t2m_l = t2m + t2m->toff_last;
 
 323                                 for(t2m = t2m_f; t2m <= t2m_l; t2m++) {
 
 324                                         if(t2m->el_no > edx_max) break;
 
 325                                         if(t2m->el_no < edx) continue;
 
 330                                         ctx->step = 1 + 2 * edx;
 
 336                 if(n == opt_edx_end) {
 
 338                          * If tag is unknown, it may be either
 
 339                          * an unknown (thus, incorrect) tag,
 
 340                          * or an extension (...),
 
 341                          * or an end of the indefinite-length structure.
 
 343                         if(!IN_EXTENSION_GROUP(specs,
 
 344                                 edx + elements[edx].optional)) {
 
 345                                 ASN_DEBUG("Unexpected tag %s (at %" ASN_PRI_SIZE ")",
 
 346                                         ber_tlv_tag_string(tlv_tag), edx);
 
 347                                 ASN_DEBUG("Expected tag %s (%s)%s",
 
 348                                         ber_tlv_tag_string(elements[edx].tag),
 
 350                                         elements[edx].optional
 
 351                                                 ?" or alternatives":"");
 
 356                                 edx += elements[edx].optional;
 
 358                                 ASN_DEBUG("Skipping unexpected %s (at %" ASN_PRI_SIZE ")",
 
 359                                         ber_tlv_tag_string(tlv_tag), edx);
 
 360                                 skip = ber_skip_length(opt_codec_ctx,
 
 361                                         BER_TLV_CONSTRUCTED(ptr),
 
 362                                         (const char *)ptr + tag_len,
 
 364                                 ASN_DEBUG("Skip length %d in %s",
 
 365                                         (int)skip, td->name);
 
 367                                 case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
 
 369                                 case -1: RETURN(RC_FAIL);
 
 372                                 ADVANCE(skip + tag_len);
 
 375                                 continue;  /* Try again with the next tag */
 
 380                  * MICROPHASE 2: Invoke the member-specific decoder.
 
 382                 ctx->step |= 1;         /* Confirm entering next microphase */
 
 384                 ASN_DEBUG("Inside SEQUENCE %s MF2", td->name);
 
 387                  * Compute the position of the member inside a structure,
 
 388                  * and also a type of containment (it may be contained
 
 389                  * as pointer or using inline inclusion).
 
 391                 if(elements[edx].flags & ATF_POINTER) {
 
 392                         /* Member is a pointer to another structure */
 
 393                         memb_ptr2 = (void **)((char *)st + elements[edx].memb_offset);
 
 396                          * A pointer to a pointer
 
 397                          * holding the start of the structure
 
 399                         memb_ptr = (char *)st + elements[edx].memb_offset;
 
 400                         memb_ptr2 = &memb_ptr;
 
 403                  * Invoke the member fetch routine according to member's type
 
 405                 if(elements[edx].flags & ATF_OPEN_TYPE) {
 
 406                         rval = OPEN_TYPE_ber_get(opt_codec_ctx, td, st, &elements[edx], ptr, LEFT);
 
 408                         rval = elements[edx].type->op->ber_decoder(opt_codec_ctx,
 
 410                                         memb_ptr2, ptr, LEFT,
 
 411                                         elements[edx].tag_mode);
 
 413                 ASN_DEBUG("In %s SEQUENCE decoded %" ASN_PRI_SIZE " %s of %d "
 
 414                         "in %d bytes rval.code %d, size=%d",
 
 415                         td->name, edx, elements[edx].type->name,
 
 416                         (int)LEFT, (int)rval.consumed, rval.code, (int)size);
 
 420                 case RC_WMORE: /* More data expected */
 
 421                         if(!SIZE_VIOLATION) {
 
 422                                 ADVANCE(rval.consumed);
 
 425                         ASN_DEBUG("Size violation (c->l=%ld <= s=%ld)",
 
 426                                 (long)ctx->left, (long)size);
 
 428                 case RC_FAIL: /* Fatal error */
 
 432                 ADVANCE(rval.consumed);
 
 433           }     /* for(all structure members) */
 
 438         case 3: /* 00 and other tags expected */
 
 439         case 4: /* only 00's expected */
 
 441                 ASN_DEBUG("SEQUENCE %s Leftover: %ld, size = %ld",
 
 442                         td->name, (long)ctx->left, (long)size);
 
 445                  * Skip everything until the end of the SEQUENCE.
 
 450                         tl = ber_fetch_tag(ptr, LEFT, &tlv_tag);
 
 452                         case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
 
 454                         case -1: RETURN(RC_FAIL);
 
 458                          * If expected <0><0>...
 
 461                                 && ((const uint8_t *)ptr)[0] == 0) {
 
 467                                 } else if(((const uint8_t *)ptr)[1] == 0) {
 
 469                                          * Correctly finished with <0><0>.
 
 478                         if(!IN_EXTENSION_GROUP(specs, td->elements_count)
 
 479                         || ctx->phase == 4) {
 
 480                                 ASN_DEBUG("Unexpected continuation "
 
 481                                         "of a non-extensible type "
 
 484                                         ber_tlv_tag_string(tlv_tag));
 
 488                         ll = ber_skip_length(opt_codec_ctx,
 
 489                                 BER_TLV_CONSTRUCTED(ptr),
 
 490                                 (const char *)ptr + tl, LEFT - tl);
 
 492                         case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
 
 494                         case -1: RETURN(RC_FAIL);
 
 508  * The DER encoder of the SEQUENCE type.
 
 511 SEQUENCE_encode_der(const asn_TYPE_descriptor_t *td, const void *sptr,
 
 512                     int tag_mode, ber_tlv_tag_t tag,
 
 513                     asn_app_consume_bytes_f *cb, void *app_key) {
 
 514     size_t computed_size = 0;
 
 515         asn_enc_rval_t erval;
 
 519         ASN_DEBUG("%s %s as SEQUENCE",
 
 520                 cb?"Encoding":"Estimating", td->name);
 
 523          * Gather the length of the underlying members sequence.
 
 525         for(edx = 0; edx < td->elements_count; edx++) {
 
 526                 asn_TYPE_member_t *elm = &td->elements[edx];
 
 528                 const void *memb_ptr;           /* Pointer to the member */
 
 529         const void *const *memb_ptr2; /* Pointer to that pointer */
 
 531         if(elm->flags & ATF_POINTER) {
 
 533                 (const void *const *)((const char *)sptr + elm->memb_offset);
 
 535                                 ASN_DEBUG("Element %s %" ASN_PRI_SIZE " not present",
 
 539                                 /* Mandatory element is missing */
 
 543             memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
 
 544             memb_ptr2 = &memb_ptr;
 
 547                 /* Eliminate default values */
 
 548                 if(elm->default_value_cmp && elm->default_value_cmp(*memb_ptr2) == 0)
 
 551                 erval = elm->type->op->der_encoder(elm->type, *memb_ptr2,
 
 552                         elm->tag_mode, elm->tag,
 
 554                 if(erval.encoded == -1)
 
 556                 computed_size += erval.encoded;
 
 557                 ASN_DEBUG("Member %" ASN_PRI_SIZE " %s estimated %ld bytes",
 
 558                         edx, elm->name, (long)erval.encoded);
 
 562          * Encode the TLV for the sequence itself.
 
 564         ret = der_write_tags(td, computed_size, tag_mode, 1, tag, cb, app_key);
 
 565         ASN_DEBUG("Wrote tags: %ld (+%ld)", (long)ret, (long)computed_size);
 
 568         erval.encoded = computed_size + ret;
 
 570         if(!cb) ASN__ENCODED_OK(erval);
 
 573          * Encode all members.
 
 575         for(edx = 0; edx < td->elements_count; edx++) {
 
 576                 asn_TYPE_member_t *elm = &td->elements[edx];
 
 577                 asn_enc_rval_t tmperval;
 
 578         const void *memb_ptr;           /* Pointer to the member */
 
 579         const void *const *memb_ptr2;   /* Pointer to that pointer */
 
 581         if(elm->flags & ATF_POINTER) {
 
 583                 (const void *const *)((const char *)sptr + elm->memb_offset);
 
 584             if(!*memb_ptr2) continue;
 
 586             memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
 
 587             memb_ptr2 = &memb_ptr;
 
 590                 /* Eliminate default values */
 
 591         if(elm->default_value_cmp && elm->default_value_cmp(*memb_ptr2) == 0)
 
 594                 tmperval = elm->type->op->der_encoder(elm->type, *memb_ptr2,
 
 595                         elm->tag_mode, elm->tag, cb, app_key);
 
 596                 if(tmperval.encoded == -1)
 
 598                 computed_size -= tmperval.encoded;
 
 599                 ASN_DEBUG("Member %" ASN_PRI_SIZE " %s of SEQUENCE %s encoded in %ld bytes",
 
 600                         edx, elm->name, td->name, (long)tmperval.encoded);
 
 603         if(computed_size != 0)
 
 605                  * Encoded size is not equal to the computed size.
 
 609         ASN__ENCODED_OK(erval);
 
 614 #define XER_ADVANCE(num_bytes)           \
 
 616         size_t num = (num_bytes);        \
 
 617         ptr = ((const char *)ptr) + num; \
 
 619         consumed_myself += num;          \
 
 623  * Decode the XER (XML) data.
 
 626 SEQUENCE_decode_xer(const asn_codec_ctx_t *opt_codec_ctx,
 
 627                     const asn_TYPE_descriptor_t *td, void **struct_ptr,
 
 628                     const char *opt_mname, const void *ptr, size_t size) {
 
 630          * Bring closer parts of structure description.
 
 632         const asn_SEQUENCE_specifics_t *specs
 
 633                 = (const asn_SEQUENCE_specifics_t *)td->specifics;
 
 634         asn_TYPE_member_t *elements = td->elements;
 
 635         const char *xml_tag = opt_mname ? opt_mname : td->xml_tag;
 
 638          * ... and parts of the structure being constructed.
 
 640         void *st = *struct_ptr; /* Target structure. */
 
 641         asn_struct_ctx_t *ctx;  /* Decoder context */
 
 643         asn_dec_rval_t rval;            /* Return value from a decoder */
 
 644         ssize_t consumed_myself = 0;    /* Consumed bytes from ptr */
 
 645         size_t edx;                     /* Element index */
 
 648          * Create the target structure if it is not present already.
 
 651                 st = *struct_ptr = CALLOC(1, specs->struct_size);
 
 652                 if(st == 0) RETURN(RC_FAIL);
 
 656          * Restore parsing context.
 
 658         ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
 
 662          * Phases of XER/XML processing:
 
 663          * Phase 0: Check that the opening tag matches our expectations.
 
 664          * Phase 1: Processing body and reacting on closing tag.
 
 665          * Phase 2: Processing inner type.
 
 666          * Phase 3: Skipping unknown extensions.
 
 667          * Phase 4: PHASED OUT
 
 669         for(edx = ctx->step; ctx->phase <= 3;) {
 
 670                 pxer_chunk_type_e ch_type;      /* XER chunk type */
 
 671                 ssize_t ch_size;                /* Chunk size */
 
 672                 xer_check_tag_e tcv;            /* Tag check value */
 
 673                 asn_TYPE_member_t *elm;
 
 676                  * Go inside the inner member of a sequence.
 
 678                 if(ctx->phase == 2) {
 
 679                         asn_dec_rval_t tmprval;
 
 680                         void *memb_ptr_dontuse;         /* Pointer to the member */
 
 681                         void **memb_ptr2;       /* Pointer to that pointer */
 
 683                         elm = &td->elements[edx];
 
 685                         if(elm->flags & ATF_POINTER) {
 
 686                                 /* Member is a pointer to another structure */
 
 687                                 memb_ptr2 = (void **)((char *)st + elm->memb_offset);
 
 689                                 memb_ptr_dontuse = (char *)st + elm->memb_offset;
 
 690                                 memb_ptr2 = &memb_ptr_dontuse;  /* Only use of memb_ptr_dontuse */
 
 693                         if(elm->flags & ATF_OPEN_TYPE) {
 
 694                                 tmprval = OPEN_TYPE_xer_get(opt_codec_ctx, td, st, elm, ptr, size);
 
 696                                 /* Invoke the inner type decoder, m.b. multiple times */
 
 697                                 tmprval = elm->type->op->xer_decoder(opt_codec_ctx,
 
 698                                                 elm->type, memb_ptr2, elm->name,
 
 701                         XER_ADVANCE(tmprval.consumed);
 
 702                         if(tmprval.code != RC_OK)
 
 703                                 RETURN(tmprval.code);
 
 704                         ctx->phase = 1; /* Back to body processing */
 
 706                         ASN_DEBUG("XER/SEQUENCE phase => %d, step => %d",
 
 707                                 ctx->phase, ctx->step);
 
 712                  * Get the next part of the XML stream.
 
 714                 ch_size = xer_next_token(&ctx->context, ptr, size,
 
 722                         case PXER_COMMENT:      /* Got XML comment */
 
 723                         case PXER_TEXT:         /* Ignore free-standing text */
 
 724                                 XER_ADVANCE(ch_size);   /* Skip silently */
 
 727                                 break;  /* Check the rest down there */
 
 731                 tcv = xer_check_tag(ptr, ch_size, xml_tag);
 
 732                 ASN_DEBUG("XER/SEQUENCE: tcv = %d, ph=%d [%s]",
 
 733                         tcv, ctx->phase, xml_tag);
 
 735                 /* Skip the extensions section */
 
 736                 if(ctx->phase == 3) {
 
 737                         switch(xer_skip_unknown(tcv, &ctx->left)) {
 
 742                                 XER_ADVANCE(ch_size);
 
 745                                 XER_ADVANCE(ch_size);
 
 756                         if(ctx->phase == 0) break;
 
 760             if(ctx->phase == 0) {
 
 761                 if(edx >= td->elements_count ||
 
 762                    /* Explicit OPTIONAL specs reaches the end */
 
 763                    (edx + elements[edx].optional == td->elements_count) ||
 
 764                    /* All extensions are optional */
 
 765                    IN_EXTENSION_GROUP(specs, edx)) {
 
 766                     XER_ADVANCE(ch_size);
 
 767                                         ctx->phase = 4; /* Phase out */
 
 770                                         ASN_DEBUG("Premature end of XER SEQUENCE");
 
 776                         if(ctx->phase == 0) {
 
 777                                 XER_ADVANCE(ch_size);
 
 778                                 ctx->phase = 1; /* Processing body phase */
 
 785                         ASN_DEBUG("XER/SEQUENCE: tcv=%d, ph=%d, edx=%" ASN_PRI_SIZE "",
 
 786                                 tcv, ctx->phase, edx);
 
 787                         if(ctx->phase != 1) {
 
 788                                 break;  /* Really unexpected */
 
 791                         if(edx < td->elements_count) {
 
 793                                  * Search which member corresponds to this tag.
 
 796                                 size_t edx_end = edx + elements[edx].optional + 1;
 
 797                                 if(edx_end > td->elements_count)
 
 798                                         edx_end = td->elements_count;
 
 799                                 for(n = edx; n < edx_end; n++) {
 
 800                                         elm = &td->elements[n];
 
 801                                         tcv = xer_check_tag(ptr, ch_size, elm->name);
 
 806                                                  * Process this member.
 
 816                                                 break;  /* Phase out */
 
 823                                 ASN_DEBUG("Out of defined members: %" ASN_PRI_SIZE "/%u",
 
 824                                         edx, td->elements_count);
 
 827                         /* It is expected extension */
 
 828                         if(IN_EXTENSION_GROUP(specs,
 
 829                                 edx + (edx < td->elements_count
 
 830                                         ? elements[edx].optional : 0))) {
 
 831                                 ASN_DEBUG("Got anticipated extension at %" ASN_PRI_SIZE "",
 
 834                                  * Check for (XCT_BOTH or XCT_UNKNOWN_BO)
 
 835                                  * By using a mask. Only record a pure
 
 838                                 if(tcv & XCT_CLOSING) {
 
 839                                         /* Found </extension> without body */
 
 842                                         ctx->phase = 3; /* Skip ...'s */
 
 844                                 XER_ADVANCE(ch_size);
 
 853                 ASN_DEBUG("Unexpected XML tag in SEQUENCE [%c%c%c%c%c%c]",
 
 854                         size>0?((const char *)ptr)[0]:'.',
 
 855                         size>1?((const char *)ptr)[1]:'.',
 
 856                         size>2?((const char *)ptr)[2]:'.',
 
 857                         size>3?((const char *)ptr)[3]:'.',
 
 858                         size>4?((const char *)ptr)[4]:'.',
 
 859                         size>5?((const char *)ptr)[5]:'.');
 
 863         ctx->phase = 4; /* "Phase out" on hard failure */
 
 868 SEQUENCE_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr,
 
 869                     int ilevel, enum xer_encoder_flags_e flags,
 
 870                     asn_app_consume_bytes_f *cb, void *app_key) {
 
 872     int xcan = (flags & XER_F_CANONICAL);
 
 873     asn_TYPE_descriptor_t *tmp_def_val_td = 0;
 
 874     void *tmp_def_val = 0;
 
 877     if(!sptr) ASN__ENCODE_FAILED;
 
 881     for(edx = 0; edx < td->elements_count; edx++) {
 
 882         asn_enc_rval_t tmper;
 
 883         asn_TYPE_member_t *elm = &td->elements[edx];
 
 884         const void *memb_ptr;
 
 885         const char *mname = elm->name;
 
 886         unsigned int mlen = strlen(mname);
 
 888         if(elm->flags & ATF_POINTER) {
 
 890                 *(const void *const *)((const char *)sptr + elm->memb_offset);
 
 892                 assert(tmp_def_val == 0);
 
 893                 if(elm->default_value_set) {
 
 894                     if(elm->default_value_set(&tmp_def_val)) {
 
 897                         memb_ptr = tmp_def_val;
 
 898                         tmp_def_val_td = elm->type;
 
 900                 } else if(elm->optional) {
 
 903                     /* Mandatory element is missing */
 
 908             memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
 
 911         if(!xcan) ASN__TEXT_INDENT(1, ilevel);
 
 912         ASN__CALLBACK3("<", 1, mname, mlen, ">", 1);
 
 914         /* Print the member itself */
 
 915         tmper = elm->type->op->xer_encoder(elm->type, memb_ptr, ilevel + 1,
 
 918             ASN_STRUCT_FREE(*tmp_def_val_td, tmp_def_val);
 
 921         if(tmper.encoded == -1) return tmper;
 
 922         er.encoded += tmper.encoded;
 
 924         ASN__CALLBACK3("</", 2, mname, mlen, ">", 1);
 
 927     if(!xcan) ASN__TEXT_INDENT(1, ilevel - 1);
 
 931     if(tmp_def_val) ASN_STRUCT_FREE(*tmp_def_val_td, tmp_def_val);
 
 936 SEQUENCE_print(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
 
 937                asn_app_consume_bytes_f *cb, void *app_key) {
 
 941         if(!sptr) return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
 
 944         if(cb(td->name, strlen(td->name), app_key) < 0
 
 945         || cb(" ::= {", 6, app_key) < 0)
 
 948         for(edx = 0; edx < td->elements_count; edx++) {
 
 949                 asn_TYPE_member_t *elm = &td->elements[edx];
 
 950                 const void *memb_ptr;
 
 952                 if(elm->flags & ATF_POINTER) {
 
 953                         memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset);
 
 955                                 if(elm->optional) continue;
 
 956                                 /* Print <absent> line */
 
 960                         memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
 
 966                 /* Print the member's name and stuff */
 
 967                 if(cb(elm->name, strlen(elm->name), app_key) < 0
 
 968                 || cb(": ", 2, app_key) < 0)
 
 971                 /* Print the member itself */
 
 972                 ret = elm->type->op->print_struct(elm->type, memb_ptr, ilevel + 1,
 
 980         return (cb("}", 1, app_key) < 0) ? -1 : 0;
 
 984 SEQUENCE_free(const asn_TYPE_descriptor_t *td, void *sptr,
 
 985               enum asn_struct_free_method method) {
 
 987     const asn_SEQUENCE_specifics_t *specs =
 
 988         (const asn_SEQUENCE_specifics_t *)td->specifics;
 
 989     asn_struct_ctx_t *ctx; /* Decoder context */
 
 994         ASN_DEBUG("Freeing %s as SEQUENCE", td->name);
 
 996         for(edx = 0; edx < td->elements_count; edx++) {
 
 997                 asn_TYPE_member_t *elm = &td->elements[edx];
 
 999                 if(elm->flags & ATF_POINTER) {
 
1000                         memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
 
1002                                 ASN_STRUCT_FREE(*elm->type, memb_ptr);
 
1004                         memb_ptr = (void *)((char *)sptr + elm->memb_offset);
 
1005                         ASN_STRUCT_FREE_CONTENTS_ONLY(*elm->type, memb_ptr);
 
1009         /* Clean parsing context */
 
1010         ctx = (asn_struct_ctx_t *)((char *)sptr + specs->ctx_offset);
 
1014     case ASFM_FREE_EVERYTHING:
 
1017     case ASFM_FREE_UNDERLYING:
 
1019     case ASFM_FREE_UNDERLYING_AND_RESET:
 
1022             ((const asn_SEQUENCE_specifics_t *)(td->specifics))->struct_size);
 
1028 SEQUENCE_constraint(const asn_TYPE_descriptor_t *td, const void *sptr,
 
1029                     asn_app_constraint_failed_f *ctfailcb, void *app_key) {
 
1033                 ASN__CTFAIL(app_key, td, sptr,
 
1034                         "%s: value not given (%s:%d)",
 
1035                         td->name, __FILE__, __LINE__);
 
1040          * Iterate over structure members and check their validity.
 
1042         for(edx = 0; edx < td->elements_count; edx++) {
 
1043                 asn_TYPE_member_t *elm = &td->elements[edx];
 
1044                 const void *memb_ptr;
 
1046                 if(elm->flags & ATF_POINTER) {
 
1047                         memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset);
 
1051                                 ASN__CTFAIL(app_key, td, sptr,
 
1052                                 "%s: mandatory element %s absent (%s:%d)",
 
1053                                 td->name, elm->name, __FILE__, __LINE__);
 
1057                         memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
 
1060                 if(elm->encoding_constraints.general_constraints) {
 
1061                         int ret = elm->encoding_constraints.general_constraints(elm->type, memb_ptr,
 
1065                         return elm->type->encoding_constraints.general_constraints(elm->type,
 
1066                                 memb_ptr, ctfailcb, app_key);
 
1073 #ifndef ASN_DISABLE_PER_SUPPORT
 
1076 SEQUENCE_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
 
1077                      const asn_TYPE_descriptor_t *td,
 
1078                      const asn_per_constraints_t *constraints, void **sptr,
 
1079                      asn_per_data_t *pd) {
 
1080     const asn_SEQUENCE_specifics_t *specs = (const asn_SEQUENCE_specifics_t *)td->specifics;
 
1081         void *st = *sptr;       /* Target structure. */
 
1082         int extpresent;         /* Extension additions are present */
 
1083         uint8_t *opres;         /* Presence of optional root members */
 
1084         asn_per_data_t opmd;
 
1090         if(ASN__STACK_OVERFLOW_CHECK(opt_codec_ctx))
 
1094                 st = *sptr = CALLOC(1, specs->struct_size);
 
1095                 if(!st) ASN__DECODE_FAILED;
 
1098         ASN_DEBUG("Decoding %s as SEQUENCE (UPER)", td->name);
 
1100         /* Handle extensions */
 
1101         if(specs->first_extension < 0) {
 
1104                 extpresent = per_get_few_bits(pd, 1);
 
1105                 if(extpresent < 0) ASN__DECODE_STARVED;
 
1108         /* Prepare a place and read-in the presence bitmap */
 
1109         memset(&opmd, 0, sizeof(opmd));
 
1110         if(specs->roms_count) {
 
1111                 opres = (uint8_t *)MALLOC(((specs->roms_count + 7) >> 3) + 1);
 
1112                 if(!opres) ASN__DECODE_FAILED;
 
1113                 /* Get the presence map */
 
1114                 if(per_get_many_bits(pd, opres, 0, specs->roms_count)) {
 
1116                         ASN__DECODE_STARVED;
 
1118                 opmd.buffer = opres;
 
1119                 opmd.nbits = specs->roms_count;
 
1120                 ASN_DEBUG("Read in presence bitmap for %s of %d bits (%x..)",
 
1121                         td->name, specs->roms_count, *opres);
 
1127          * Get the sequence ROOT elements.
 
1130         edx < (specs->first_extension < 0 ? td->elements_count
 
1131                                           : (size_t)specs->first_extension);
 
1133         asn_TYPE_member_t *elm = &td->elements[edx];
 
1134                 void *memb_ptr;         /* Pointer to the member */
 
1135                 void **memb_ptr2;       /* Pointer to that pointer */
 
1137                 assert(!IN_EXTENSION_GROUP(specs, edx));
 
1139                 /* Fetch the pointer to this member */
 
1140                 if(elm->flags & ATF_POINTER) {
 
1141                         memb_ptr2 = (void **)((char *)st + elm->memb_offset);
 
1143                         memb_ptr = (char *)st + elm->memb_offset;
 
1144                         memb_ptr2 = &memb_ptr;
 
1147                 /* Deal with optionality */
 
1149                         int present = per_get_few_bits(&opmd, 1);
 
1150                         ASN_DEBUG("Member %s->%s is optional, p=%d (%d->%d)",
 
1151                                 td->name, elm->name, present,
 
1152                                 (int)opmd.nboff, (int)opmd.nbits);
 
1154                                 /* This element is not present */
 
1155                                 if(elm->default_value_set) {
 
1156                                         /* Fill-in DEFAULT */
 
1157                                         if(elm->default_value_set(memb_ptr2)) {
 
1161                                         ASN_DEBUG("Filled-in default");
 
1163                                 /* The member is just not present */
 
1169                 /* Fetch the member from the stream */
 
1170                 ASN_DEBUG("Decoding member \"%s\" in %s", elm->name, td->name);
 
1172                 if(elm->flags & ATF_OPEN_TYPE) {
 
1173                         rv = OPEN_TYPE_uper_get(opt_codec_ctx, td, st, elm, pd);
 
1175                         rv = elm->type->op->uper_decoder(opt_codec_ctx, elm->type,
 
1176                                         elm->encoding_constraints.per_constraints, memb_ptr2, pd);
 
1178                 if(rv.code != RC_OK) {
 
1179                         ASN_DEBUG("Failed decode %s in %s",
 
1180                                 elm->name, td->name);
 
1186         /* Optionality map is not needed anymore */
 
1190          * Deal with extensions.
 
1194                 uint8_t *epres;         /* Presence of extension members */
 
1195                 asn_per_data_t epmd;
 
1197                 bmlength = uper_get_nslength(pd);
 
1198                 if(bmlength < 0) ASN__DECODE_STARVED;
 
1200                 ASN_DEBUG("Extensions %" ASN_PRI_SSIZE " present in %s", bmlength, td->name);
 
1202                 epres = (uint8_t *)MALLOC((bmlength + 15) >> 3);
 
1203                 if(!epres) ASN__DECODE_STARVED;
 
1205                 /* Get the extensions map */
 
1206                 if(per_get_many_bits(pd, epres, 0, bmlength)) {
 
1208                         ASN__DECODE_STARVED;
 
1211                 memset(&epmd, 0, sizeof(epmd));
 
1212                 epmd.buffer = epres;
 
1213                 epmd.nbits = bmlength;
 
1214                 ASN_DEBUG("Read in extensions bitmap for %s of %ld bits (%x..)",
 
1215                         td->name, (long)bmlength, *epres);
 
1217             /* Go over extensions and read them in */
 
1218         for(edx = specs->first_extension; edx < td->elements_count; edx++) {
 
1219             asn_TYPE_member_t *elm = &td->elements[edx];
 
1220             void *memb_ptr;   /* Pointer to the member */
 
1221             void **memb_ptr2; /* Pointer to that pointer */
 
1224             /* Fetch the pointer to this member */
 
1225             if(elm->flags & ATF_POINTER) {
 
1226                 memb_ptr2 = (void **)((char *)st + elm->memb_offset);
 
1228                 memb_ptr = (void *)((char *)st + elm->memb_offset);
 
1229                 memb_ptr2 = &memb_ptr;
 
1232             present = per_get_few_bits(&epmd, 1);
 
1234                 if(present < 0) break; /* No more extensions */
 
1238             ASN_DEBUG("Decoding member %s in %s %p", elm->name, td->name,
 
1240             rv = uper_open_type_get(opt_codec_ctx, elm->type,
 
1241                                     elm->encoding_constraints.per_constraints,
 
1243             if(rv.code != RC_OK) {
 
1249                 /* Skip over overflow extensions which aren't present
 
1250                  * in this system's version of the protocol */
 
1252                         ASN_DEBUG("Getting overflow extensions");
 
1253                         switch(per_get_few_bits(&epmd, 1)) {
 
1257                                 if(uper_open_type_skip(opt_codec_ctx, pd)) {
 
1259                                         ASN__DECODE_STARVED;
 
1261                 ASN_DEBUG("Skipped overflow extension");
 
1270     if(specs->first_extension >= 0) {
 
1272         /* Fill DEFAULT members in extensions */
 
1273         for(i = specs->roms_count; i < specs->roms_count + specs->aoms_count;
 
1275             asn_TYPE_member_t *elm;
 
1276             void **memb_ptr2; /* Pointer to member pointer */
 
1278             edx = specs->oms[i];
 
1279             elm = &td->elements[edx];
 
1281             if(!elm->default_value_set) continue;
 
1283             /* Fetch the pointer to this member */
 
1284             if(elm->flags & ATF_POINTER) {
 
1285                 memb_ptr2 = (void **)((char *)st + elm->memb_offset);
 
1286                 if(*memb_ptr2) continue;
 
1288                 continue; /* Extensions are all optionals */
 
1291             /* Set default value */
 
1292             if(elm->default_value_set(memb_ptr2)) {
 
1304 SEQUENCE__handle_extensions(const asn_TYPE_descriptor_t *td, const void *sptr,
 
1305                             asn_per_outp_t *po1, asn_per_outp_t *po2) {
 
1306     const asn_SEQUENCE_specifics_t *specs =
 
1307         (const asn_SEQUENCE_specifics_t *)td->specifics;
 
1308     int exts_present = 0;
 
1312     if(specs->first_extension < 0) {
 
1316     /* Find out which extensions are present */
 
1317     for(edx = specs->first_extension; edx < td->elements_count; edx++) {
 
1318         asn_TYPE_member_t *elm = &td->elements[edx];
 
1319         const void *memb_ptr;         /* Pointer to the member */
 
1320         const void *const *memb_ptr2; /* Pointer to that pointer */
 
1323         /* Fetch the pointer to this member */
 
1324         if(elm->flags & ATF_POINTER) {
 
1326                 (const void *const *)((const char *)sptr + elm->memb_offset);
 
1327             present = (*memb_ptr2 != 0);
 
1329             memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
 
1330             memb_ptr2 = &memb_ptr;
 
1334         ASN_DEBUG("checking %s:%s (@%" ASN_PRI_SIZE ") present => %d", elm->name,
 
1335                   elm->type->name, edx, present);
 
1337         exts_present += present;
 
1339         /* Encode as presence marker */
 
1340         if(po1 && per_put_few_bits(po1, present, 1)) {
 
1343         /* Encode as open type field */
 
1345            && uper_open_type_put(elm->type,
 
1346                                  elm->encoding_constraints.per_constraints,
 
1351     return exts_present ? exts_count : 0;
 
1355 SEQUENCE_encode_uper(const asn_TYPE_descriptor_t *td,
 
1356                      const asn_per_constraints_t *constraints, const void *sptr,
 
1357                      asn_per_outp_t *po) {
 
1358     const asn_SEQUENCE_specifics_t *specs
 
1359                 = (const asn_SEQUENCE_specifics_t *)td->specifics;
 
1372         ASN_DEBUG("Encoding %s as SEQUENCE (UPER)", td->name);
 
1375          * X.691#18.1 Whether structure is extensible
 
1376          * and whether to encode extensions
 
1378     if(specs->first_extension < 0) {
 
1379         n_extensions = 0; /* There are no extensions to encode */
 
1381         n_extensions = SEQUENCE__handle_extensions(td, sptr, 0, 0);
 
1382         if(n_extensions < 0) ASN__ENCODE_FAILED;
 
1383         if(per_put_few_bits(po, n_extensions ? 1 : 0, 1)) {
 
1388         /* Encode a presence bitmap */
 
1389         for(i = 0; i < specs->roms_count; i++) {
 
1390                 asn_TYPE_member_t *elm;
 
1391                 const void *memb_ptr;           /* Pointer to the member */
 
1392         const void *const *memb_ptr2; /* Pointer to that pointer */
 
1395                 edx = specs->oms[i];
 
1396                 elm = &td->elements[edx];
 
1398                 /* Fetch the pointer to this member */
 
1399                 if(elm->flags & ATF_POINTER) {
 
1401                 (const void *const *)((const char *)sptr + elm->memb_offset);
 
1402             present = (*memb_ptr2 != 0);
 
1404             memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
 
1405             memb_ptr2 = &memb_ptr;
 
1409                 /* Eliminate default values */
 
1410         if(present && elm->default_value_cmp
 
1411            && elm->default_value_cmp(*memb_ptr2) == 0)
 
1414                 ASN_DEBUG("Element %s %s %s->%s is %s",
 
1415                         elm->flags & ATF_POINTER ? "ptr" : "inline",
 
1416                         elm->default_value_cmp ? "def" : "wtv",
 
1417                         td->name, elm->name, present ? "present" : "absent");
 
1418                 if(per_put_few_bits(po, present, 1))
 
1423          * Encode the sequence ROOT elements.
 
1425     ASN_DEBUG("first_extension = %d, elements = %d", specs->first_extension,
 
1426               td->elements_count);
 
1428                 edx < ((specs->first_extension < 0) ? td->elements_count
 
1429                                             : (size_t)specs->first_extension);
 
1431                 asn_TYPE_member_t *elm = &td->elements[edx];
 
1432                 const void *memb_ptr;         /* Pointer to the member */
 
1433                 const void *const *memb_ptr2; /* Pointer to that pointer */
 
1435                 ASN_DEBUG("About to encode %s", elm->type->name);
 
1437                 /* Fetch the pointer to this member */
 
1438                 if(elm->flags & ATF_POINTER) {
 
1440                 (const void *const *)((const char *)sptr + elm->memb_offset);
 
1442                                 ASN_DEBUG("Element %s %" ASN_PRI_SIZE " not present",
 
1446                                 /* Mandatory element is missing */
 
1450             memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
 
1451             memb_ptr2 = &memb_ptr;
 
1454                 /* Eliminate default values */
 
1455                 if(elm->default_value_cmp && elm->default_value_cmp(*memb_ptr2) == 0)
 
1458         ASN_DEBUG("Encoding %s->%s:%s", td->name, elm->name, elm->type->name);
 
1459         er = elm->type->op->uper_encoder(
 
1460             elm->type, elm->encoding_constraints.per_constraints, *memb_ptr2,
 
1462         if(er.encoded == -1) return er;
 
1465         /* No extensions to encode */
 
1466         if(!n_extensions) ASN__ENCODED_OK(er);
 
1468         ASN_DEBUG("Length of extensions %d bit-map", n_extensions);
 
1469         /* #18.8. Write down the presence bit-map length. */
 
1470         if(uper_put_nslength(po, n_extensions))
 
1473         ASN_DEBUG("Bit-map of %d elements", n_extensions);
 
1474         /* #18.7. Encoding the extensions presence bit-map. */
 
1475         /* TODO: act upon NOTE in #18.7 for canonical PER */
 
1476         if(SEQUENCE__handle_extensions(td, sptr, po, 0) != n_extensions)
 
1479         ASN_DEBUG("Writing %d extensions", n_extensions);
 
1480         /* #18.9. Encode extensions as open type fields. */
 
1481         if(SEQUENCE__handle_extensions(td, sptr, 0, po) != n_extensions)
 
1484         ASN__ENCODED_OK(er);
 
1487 #endif  /* ASN_DISABLE_PER_SUPPORT */
 
1490 SEQUENCE_compare(const asn_TYPE_descriptor_t *td, const void *aptr,
 
1494         for(edx = 0; edx < td->elements_count; edx++) {
 
1495                 asn_TYPE_member_t *elm = &td->elements[edx];
 
1500                 if(elm->flags & ATF_POINTER) {
 
1502                 *(const void *const *)((const char *)aptr + elm->memb_offset);
 
1504                 *(const void *const *)((const char *)bptr + elm->memb_offset);
 
1506                 if(!bmemb) continue;
 
1507                 if(elm->default_value_cmp
 
1508                    && elm->default_value_cmp(bmemb) == 0) {
 
1509                     /* A is absent, but B is present and equal to DEFAULT */
 
1514                 if(elm->default_value_cmp
 
1515                    && elm->default_value_cmp(amemb) == 0) {
 
1516                     /* B is absent, but A is present and equal to DEFAULT */
 
1522             amemb = (const void *)((const char *)aptr + elm->memb_offset);
 
1523             bmemb = (const void *)((const char *)bptr + elm->memb_offset);
 
1526         ret = elm->type->op->compare_struct(elm->type, amemb, bmemb);
 
1527         if(ret != 0) return ret;
 
1533 asn_TYPE_operation_t asn_OP_SEQUENCE = {
 
1537         SEQUENCE_decode_ber,
 
1538         SEQUENCE_encode_der,
 
1539         SEQUENCE_decode_xer,
 
1540         SEQUENCE_encode_xer,
 
1541 #ifdef  ASN_DISABLE_OER_SUPPORT
 
1545         SEQUENCE_decode_oer,
 
1546         SEQUENCE_encode_oer,
 
1547 #endif  /* ASN_DISABLE_OER_SUPPORT */
 
1548 #ifdef ASN_DISABLE_PER_SUPPORT
 
1552         SEQUENCE_decode_uper,
 
1553         SEQUENCE_encode_uper,
 
1554 #endif /* ASN_DISABLE_PER_SUPPORT */
 
1555         SEQUENCE_random_fill,
 
1556         0       /* Use generic outmost tag fetcher */
 
1560 asn_random_fill_result_t
 
1561 SEQUENCE_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
 
1562                    const asn_encoding_constraints_t *constr,
 
1563                    size_t max_length) {
 
1564     const asn_SEQUENCE_specifics_t *specs =
 
1565         (const asn_SEQUENCE_specifics_t *)td->specifics;
 
1566     asn_random_fill_result_t result_ok = {ARFILL_OK, 0};
 
1567     asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
 
1568     asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
 
1572     if(max_length == 0) return result_skipped;
 
1577         st = CALLOC(1, specs->struct_size);
 
1579             return result_failed;
 
1583     for(edx = 0; edx < td->elements_count; edx++) {
 
1584         const asn_TYPE_member_t *elm = &td->elements[edx];
 
1585         void *memb_ptr;   /* Pointer to the member */
 
1586         void **memb_ptr2; /* Pointer to that pointer */
 
1587         asn_random_fill_result_t tmpres;
 
1589         if(elm->optional && asn_random_between(0, 4) == 2) {
 
1590             /* Sometimes decide not to fill the optional value */
 
1594         if(elm->flags & ATF_POINTER) {
 
1595             /* Member is a pointer to another structure */
 
1596             memb_ptr2 = (void **)((char *)st + elm->memb_offset);
 
1598             memb_ptr = (char *)st + elm->memb_offset;
 
1599             memb_ptr2 = &memb_ptr;
 
1602         tmpres = elm->type->op->random_fill(
 
1603             elm->type, memb_ptr2, &elm->encoding_constraints,
 
1604             max_length > result_ok.length ? max_length - result_ok.length : 0);
 
1605         switch(tmpres.code) {
 
1607             result_ok.length += tmpres.length;
 
1609         case ARFILL_SKIPPED:
 
1610             assert(!(elm->flags & ATF_POINTER) || *memb_ptr2 == NULL);
 
1614                 ASN_STRUCT_RESET(*td, st);
 
1616                 ASN_STRUCT_FREE(*td, st);