1 /*****************************************************************************
3 # Copyright 2019 AT&T Intellectual Property *
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 *
9 # http://www.apache.org/licenses/LICENSE-2.0 *
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. *
17 ******************************************************************************/
20 * Copyright (c) 2003-2017 Lev Walkin <vlm@lionet.info>.
21 * All rights reserved.
22 * Redistribution and modifications are permitted subject to BSD license.
24 #include <asn_internal.h>
25 #include <constr_SEQUENCE.h>
26 #include <OPEN_TYPE.h>
27 #include <per_opentype.h>
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.
34 #define LEFT ((size<(size_t)ctx->left)?size:(size_t)ctx->left)
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
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.
47 #define SIZE_VIOLATION (ctx->left >= 0 && (size_t)ctx->left <= size)
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.
54 #define ADVANCE(num_bytes) do { \
55 size_t num = num_bytes; \
56 ptr = ((const char *)ptr) + num; \
60 consumed_myself += num; \
64 * Switch to the next phase of parsing.
68 #define NEXT_PHASE(ctx) do { \
72 #define PHASE_OUT(ctx) do { ctx->phase = 10; } while(0)
75 * Return a standardized complex structure.
78 #define RETURN(_code) do { \
80 rval.consumed = consumed_myself;\
85 * Check whether we are inside the extensions group.
87 #define IN_EXTENSION_GROUP(specs, memb_idx) \
88 ((specs)->first_extension >= 0 \
89 && (unsigned)(specs)->first_extension <= (memb_idx))
92 * Tags are canonically sorted in the tag2element map.
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;
99 int a_class = BER_TAG_CLASS(a->el_tag);
100 int b_class = BER_TAG_CLASS(b->el_tag);
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);
106 if(a_value == b_value) {
107 if(a->el_no > b->el_no)
110 * Important: we do not check
111 * for a->el_no <= b->el_no!
114 } else if(a_value < b_value)
118 } else if(a_class < b_class) {
127 * The decoder of the SEQUENCE type.
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) {
134 * Bring closer parts of structure description.
136 const asn_SEQUENCE_specifics_t *specs = (const asn_SEQUENCE_specifics_t *)td->specifics;
137 const asn_TYPE_member_t *elements = td->elements;
140 * Parts of the structure being constructed.
142 void *st = *struct_ptr; /* Target structure. */
143 asn_struct_ctx_t *ctx; /* Decoder context */
145 ber_tlv_tag_t tlv_tag; /* T from TLV */
146 asn_dec_rval_t rval; /* Return code from subparsers */
148 ssize_t consumed_myself = 0; /* Consumed bytes from ptr */
149 size_t edx; /* SEQUENCE element's index */
151 ASN_DEBUG("Decoding %s as SEQUENCE", td->name);
154 * Create the target structure if it is not present already.
157 st = *struct_ptr = CALLOC(1, specs->struct_size);
164 * Restore parsing context.
166 ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
169 * Start to parse where left previously
175 * Check that the set of tags associated with given structure
176 * perfectly fits our expectations.
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);
188 ctx->left += rval.consumed; /* ?Substracted below! */
189 ADVANCE(rval.consumed);
193 ASN_DEBUG("Structure consumes %ld bytes, buffer %ld",
194 (long)ctx->left, (long)size);
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
206 * step = (<member_number> * 2 + <microphase>).
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 */
221 * MICROPHASE 1: Synchronize decoding.
223 ASN_DEBUG("In %s SEQUENCE left %d, edx=%" ASN_PRI_SIZE " flags=%d"
225 td->name, (int)ctx->left, edx,
226 elements[edx].flags, elements[edx].optional,
229 if(ctx->left == 0 /* No more stuff is expected */
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);
237 * Found the legitimate end of the structure.
244 * Fetch the T from TLV.
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);
252 case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
254 case -1: RETURN(RC_FAIL);
257 if(ctx->left < 0 && ((const uint8_t *)ptr)[0] == 0) {
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)) {
270 * Yeah, baby! Found the terminator
271 * of the indefinite length structure.
274 * Proceed to the canonical
275 * finalization function.
276 * No advancing is necessary.
284 * Find the next available type with this tag.
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;
294 /* ... and resort to bsearch() */
296 for(n = edx; n < opt_edx_end; n++) {
297 if(BER_TAGS_EQUAL(tlv_tag, elements[n].tag)) {
299 * Found element corresponding to the tag
301 * Reposition over the right element.
304 ctx->step = 1 + 2 * edx; /* Remember! */
306 } else if(elements[n].flags & ATF_ANY_TYPE) {
308 * This is the ANY type, which may bear
309 * any flag whatsoever.
312 ctx->step = 1 + 2 * edx; /* Remember! */
314 } else if(elements[n].tag == (ber_tlv_tag_t)-1) {
321 * Resort to a binary search over
322 * sorted array of tags.
324 const asn_TYPE_tag2member_t *t2m;
325 asn_TYPE_tag2member_t key = {0, 0, 0, 0};
326 key.el_tag = tlv_tag;
328 t2m = (const asn_TYPE_tag2member_t *)bsearch(&key,
329 specs->tag2el, specs->tag2el_count,
330 sizeof(specs->tag2el[0]), _t2e_cmp);
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;
336 * Rewind to the first element with that tag,
337 * `cause bsearch() does not guarantee order.
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;
348 ctx->step = 1 + 2 * edx;
354 if(n == opt_edx_end) {
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.
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),
368 elements[edx].optional
369 ?" or alternatives":"");
374 edx += elements[edx].optional;
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,
382 ASN_DEBUG("Skip length %d in %s",
383 (int)skip, td->name);
385 case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
387 case -1: RETURN(RC_FAIL);
390 ADVANCE(skip + tag_len);
393 continue; /* Try again with the next tag */
398 * MICROPHASE 2: Invoke the member-specific decoder.
400 ctx->step |= 1; /* Confirm entering next microphase */
402 ASN_DEBUG("Inside SEQUENCE %s MF2", td->name);
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).
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);
414 * A pointer to a pointer
415 * holding the start of the structure
417 memb_ptr = (char *)st + elements[edx].memb_offset;
418 memb_ptr2 = &memb_ptr;
421 * Invoke the member fetch routine according to member's type
423 if(elements[edx].flags & ATF_OPEN_TYPE) {
424 rval = OPEN_TYPE_ber_get(opt_codec_ctx, td, st, &elements[edx], ptr, LEFT);
426 rval = elements[edx].type->op->ber_decoder(opt_codec_ctx,
428 memb_ptr2, ptr, LEFT,
429 elements[edx].tag_mode);
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);
438 case RC_WMORE: /* More data expected */
439 if(!SIZE_VIOLATION) {
440 ADVANCE(rval.consumed);
443 ASN_DEBUG("Size violation (c->l=%ld <= s=%ld)",
444 (long)ctx->left, (long)size);
446 case RC_FAIL: /* Fatal error */
450 ADVANCE(rval.consumed);
451 } /* for(all structure members) */
456 case 3: /* 00 and other tags expected */
457 case 4: /* only 00's expected */
459 ASN_DEBUG("SEQUENCE %s Leftover: %ld, size = %ld",
460 td->name, (long)ctx->left, (long)size);
463 * Skip everything until the end of the SEQUENCE.
468 tl = ber_fetch_tag(ptr, LEFT, &tlv_tag);
470 case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
472 case -1: RETURN(RC_FAIL);
476 * If expected <0><0>...
479 && ((const uint8_t *)ptr)[0] == 0) {
485 } else if(((const uint8_t *)ptr)[1] == 0) {
487 * Correctly finished with <0><0>.
496 if(!IN_EXTENSION_GROUP(specs, td->elements_count)
497 || ctx->phase == 4) {
498 ASN_DEBUG("Unexpected continuation "
499 "of a non-extensible type "
502 ber_tlv_tag_string(tlv_tag));
506 ll = ber_skip_length(opt_codec_ctx,
507 BER_TLV_CONSTRUCTED(ptr),
508 (const char *)ptr + tl, LEFT - tl);
510 case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
512 case -1: RETURN(RC_FAIL);
526 * The DER encoder of the SEQUENCE type.
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};
537 ASN_DEBUG("%s %s as SEQUENCE",
538 cb?"Encoding":"Estimating", td->name);
541 * Gather the length of the underlying members sequence.
543 for(edx = 0; edx < td->elements_count; edx++) {
544 asn_TYPE_member_t *elm = &td->elements[edx];
546 const void *memb_ptr; /* Pointer to the member */
547 const void *const *memb_ptr2; /* Pointer to that pointer */
549 if(elm->flags & ATF_POINTER) {
551 (const void *const *)((const char *)sptr + elm->memb_offset);
553 ASN_DEBUG("Element %s %" ASN_PRI_SIZE " not present",
557 /* Mandatory element is missing */
561 memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
562 memb_ptr2 = &memb_ptr;
565 /* Eliminate default values */
566 if(elm->default_value_cmp && elm->default_value_cmp(*memb_ptr2) == 0)
569 erval = elm->type->op->der_encoder(elm->type, *memb_ptr2,
570 elm->tag_mode, elm->tag,
572 if(erval.encoded == -1)
574 computed_size += erval.encoded;
575 ASN_DEBUG("Member %" ASN_PRI_SIZE " %s estimated %ld bytes",
576 edx, elm->name, (long)erval.encoded);
580 * Encode the TLV for the sequence itself.
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);
586 erval.encoded = computed_size + ret;
588 if(!cb) ASN__ENCODED_OK(erval);
591 * Encode all members.
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 */
599 if(elm->flags & ATF_POINTER) {
601 (const void *const *)((const char *)sptr + elm->memb_offset);
602 if(!*memb_ptr2) continue;
604 memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
605 memb_ptr2 = &memb_ptr;
608 /* Eliminate default values */
609 if(elm->default_value_cmp && elm->default_value_cmp(*memb_ptr2) == 0)
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)
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);
621 if(computed_size != 0)
623 * Encoded size is not equal to the computed size.
627 ASN__ENCODED_OK(erval);
632 #define XER_ADVANCE(num_bytes) \
634 size_t num = (num_bytes); \
635 ptr = ((const char *)ptr) + num; \
637 consumed_myself += num; \
641 * Decode the XER (XML) data.
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) {
648 * Bring closer parts of structure description.
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;
656 * ... and parts of the structure being constructed.
658 void *st = *struct_ptr; /* Target structure. */
659 asn_struct_ctx_t *ctx; /* Decoder context */
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 */
666 * Create the target structure if it is not present already.
669 st = *struct_ptr = CALLOC(1, specs->struct_size);
670 if(st == 0) RETURN(RC_FAIL);
674 * Restore parsing context.
676 ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
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
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;
694 * Go inside the inner member of a sequence.
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 */
701 elm = &td->elements[edx];
703 if(elm->flags & ATF_POINTER) {
704 /* Member is a pointer to another structure */
705 memb_ptr2 = (void **)((char *)st + elm->memb_offset);
707 memb_ptr_dontuse = (char *)st + elm->memb_offset;
708 memb_ptr2 = &memb_ptr_dontuse; /* Only use of memb_ptr_dontuse */
711 if(elm->flags & ATF_OPEN_TYPE) {
712 tmprval = OPEN_TYPE_xer_get(opt_codec_ctx, td, st, elm, ptr, size);
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,
719 XER_ADVANCE(tmprval.consumed);
720 if(tmprval.code != RC_OK)
721 RETURN(tmprval.code);
722 ctx->phase = 1; /* Back to body processing */
724 ASN_DEBUG("XER/SEQUENCE phase => %d, step => %d",
725 ctx->phase, ctx->step);
730 * Get the next part of the XML stream.
732 ch_size = xer_next_token(&ctx->context, ptr, size,
740 case PXER_COMMENT: /* Got XML comment */
741 case PXER_TEXT: /* Ignore free-standing text */
742 XER_ADVANCE(ch_size); /* Skip silently */
745 break; /* Check the rest down there */
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);
753 /* Skip the extensions section */
754 if(ctx->phase == 3) {
755 switch(xer_skip_unknown(tcv, &ctx->left)) {
760 XER_ADVANCE(ch_size);
763 XER_ADVANCE(ch_size);
774 if(ctx->phase == 0) break;
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 */
788 ASN_DEBUG("Premature end of XER SEQUENCE");
794 if(ctx->phase == 0) {
795 XER_ADVANCE(ch_size);
796 ctx->phase = 1; /* Processing body phase */
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 */
809 if(edx < td->elements_count) {
811 * Search which member corresponds to this tag.
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);
824 * Process this member.
834 break; /* Phase out */
841 ASN_DEBUG("Out of defined members: %" ASN_PRI_SIZE "/%u",
842 edx, td->elements_count);
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 "",
852 * Check for (XCT_BOTH or XCT_UNKNOWN_BO)
853 * By using a mask. Only record a pure
856 if(tcv & XCT_CLOSING) {
857 /* Found </extension> without body */
860 ctx->phase = 3; /* Skip ...'s */
862 XER_ADVANCE(ch_size);
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]:'.');
881 ctx->phase = 4; /* "Phase out" on hard failure */
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;
895 if(!sptr) ASN__ENCODE_FAILED;
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);
906 if(elm->flags & ATF_POINTER) {
908 *(const void *const *)((const char *)sptr + elm->memb_offset);
910 assert(tmp_def_val == 0);
911 if(elm->default_value_set) {
912 if(elm->default_value_set(&tmp_def_val)) {
915 memb_ptr = tmp_def_val;
916 tmp_def_val_td = elm->type;
918 } else if(elm->optional) {
921 /* Mandatory element is missing */
926 memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
929 if(!xcan) ASN__TEXT_INDENT(1, ilevel);
930 ASN__CALLBACK3("<", 1, mname, mlen, ">", 1);
932 /* Print the member itself */
933 tmper = elm->type->op->xer_encoder(elm->type, memb_ptr, ilevel + 1,
936 ASN_STRUCT_FREE(*tmp_def_val_td, tmp_def_val);
939 if(tmper.encoded == -1) return tmper;
940 er.encoded += tmper.encoded;
942 ASN__CALLBACK3("</", 2, mname, mlen, ">", 1);
945 if(!xcan) ASN__TEXT_INDENT(1, ilevel - 1);
949 if(tmp_def_val) ASN_STRUCT_FREE(*tmp_def_val_td, tmp_def_val);
954 SEQUENCE_print(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
955 asn_app_consume_bytes_f *cb, void *app_key) {
959 if(!sptr) return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
962 if(cb(td->name, strlen(td->name), app_key) < 0
963 || cb(" ::= {", 6, app_key) < 0)
966 for(edx = 0; edx < td->elements_count; edx++) {
967 asn_TYPE_member_t *elm = &td->elements[edx];
968 const void *memb_ptr;
970 if(elm->flags & ATF_POINTER) {
971 memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset);
973 if(elm->optional) continue;
974 /* Print <absent> line */
978 memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
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)
989 /* Print the member itself */
990 ret = elm->type->op->print_struct(elm->type, memb_ptr, ilevel + 1,
998 return (cb("}", 1, app_key) < 0) ? -1 : 0;
1002 SEQUENCE_free(const asn_TYPE_descriptor_t *td, void *sptr,
1003 enum asn_struct_free_method method) {
1005 const asn_SEQUENCE_specifics_t *specs =
1006 (const asn_SEQUENCE_specifics_t *)td->specifics;
1007 asn_struct_ctx_t *ctx; /* Decoder context */
1012 ASN_DEBUG("Freeing %s as SEQUENCE", td->name);
1014 for(edx = 0; edx < td->elements_count; edx++) {
1015 asn_TYPE_member_t *elm = &td->elements[edx];
1017 if(elm->flags & ATF_POINTER) {
1018 memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
1020 ASN_STRUCT_FREE(*elm->type, memb_ptr);
1022 memb_ptr = (void *)((char *)sptr + elm->memb_offset);
1023 ASN_STRUCT_FREE_CONTENTS_ONLY(*elm->type, memb_ptr);
1027 /* Clean parsing context */
1028 ctx = (asn_struct_ctx_t *)((char *)sptr + specs->ctx_offset);
1032 case ASFM_FREE_EVERYTHING:
1035 case ASFM_FREE_UNDERLYING:
1037 case ASFM_FREE_UNDERLYING_AND_RESET:
1040 ((const asn_SEQUENCE_specifics_t *)(td->specifics))->struct_size);
1046 SEQUENCE_constraint(const asn_TYPE_descriptor_t *td, const void *sptr,
1047 asn_app_constraint_failed_f *ctfailcb, void *app_key) {
1051 ASN__CTFAIL(app_key, td, sptr,
1052 "%s: value not given (%s:%d)",
1053 td->name, __FILE__, __LINE__);
1058 * Iterate over structure members and check their validity.
1060 for(edx = 0; edx < td->elements_count; edx++) {
1061 asn_TYPE_member_t *elm = &td->elements[edx];
1062 const void *memb_ptr;
1064 if(elm->flags & ATF_POINTER) {
1065 memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset);
1069 ASN__CTFAIL(app_key, td, sptr,
1070 "%s: mandatory element %s absent (%s:%d)",
1071 td->name, elm->name, __FILE__, __LINE__);
1075 memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
1078 if(elm->encoding_constraints.general_constraints) {
1079 int ret = elm->encoding_constraints.general_constraints(elm->type, memb_ptr,
1083 return elm->type->encoding_constraints.general_constraints(elm->type,
1084 memb_ptr, ctfailcb, app_key);
1091 #ifndef ASN_DISABLE_PER_SUPPORT
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;
1108 if(ASN__STACK_OVERFLOW_CHECK(opt_codec_ctx))
1112 st = *sptr = CALLOC(1, specs->struct_size);
1113 if(!st) ASN__DECODE_FAILED;
1116 ASN_DEBUG("Decoding %s as SEQUENCE (UPER)", td->name);
1118 /* Handle extensions */
1119 if(specs->first_extension < 0) {
1122 extpresent = per_get_few_bits(pd, 1);
1123 if(extpresent < 0) ASN__DECODE_STARVED;
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)) {
1134 ASN__DECODE_STARVED;
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);
1145 * Get the sequence ROOT elements.
1148 edx < (specs->first_extension < 0 ? td->elements_count
1149 : (size_t)specs->first_extension);
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 */
1155 assert(!IN_EXTENSION_GROUP(specs, edx));
1157 /* Fetch the pointer to this member */
1158 if(elm->flags & ATF_POINTER) {
1159 memb_ptr2 = (void **)((char *)st + elm->memb_offset);
1161 memb_ptr = (char *)st + elm->memb_offset;
1162 memb_ptr2 = &memb_ptr;
1165 /* Deal with optionality */
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);
1172 /* This element is not present */
1173 if(elm->default_value_set) {
1174 /* Fill-in DEFAULT */
1175 if(elm->default_value_set(memb_ptr2)) {
1179 ASN_DEBUG("Filled-in default");
1181 /* The member is just not present */
1187 /* Fetch the member from the stream */
1188 ASN_DEBUG("Decoding member \"%s\" in %s", elm->name, td->name);
1190 if(elm->flags & ATF_OPEN_TYPE) {
1191 rv = OPEN_TYPE_uper_get(opt_codec_ctx, td, st, elm, pd);
1193 rv = elm->type->op->uper_decoder(opt_codec_ctx, elm->type,
1194 elm->encoding_constraints.per_constraints, memb_ptr2, pd);
1196 if(rv.code != RC_OK) {
1197 ASN_DEBUG("Failed decode %s in %s",
1198 elm->name, td->name);
1204 /* Optionality map is not needed anymore */
1208 * Deal with extensions.
1212 uint8_t *epres; /* Presence of extension members */
1213 asn_per_data_t epmd;
1215 bmlength = uper_get_nslength(pd);
1216 if(bmlength < 0) ASN__DECODE_STARVED;
1218 ASN_DEBUG("Extensions %" ASN_PRI_SSIZE " present in %s", bmlength, td->name);
1220 epres = (uint8_t *)MALLOC((bmlength + 15) >> 3);
1221 if(!epres) ASN__DECODE_STARVED;
1223 /* Get the extensions map */
1224 if(per_get_many_bits(pd, epres, 0, bmlength)) {
1226 ASN__DECODE_STARVED;
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);
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 */
1242 /* Fetch the pointer to this member */
1243 if(elm->flags & ATF_POINTER) {
1244 memb_ptr2 = (void **)((char *)st + elm->memb_offset);
1246 memb_ptr = (void *)((char *)st + elm->memb_offset);
1247 memb_ptr2 = &memb_ptr;
1250 present = per_get_few_bits(&epmd, 1);
1252 if(present < 0) break; /* No more extensions */
1256 ASN_DEBUG("Decoding member %s in %s %p", elm->name, td->name,
1258 rv = uper_open_type_get(opt_codec_ctx, elm->type,
1259 elm->encoding_constraints.per_constraints,
1261 if(rv.code != RC_OK) {
1267 /* Skip over overflow extensions which aren't present
1268 * in this system's version of the protocol */
1270 ASN_DEBUG("Getting overflow extensions");
1271 switch(per_get_few_bits(&epmd, 1)) {
1275 if(uper_open_type_skip(opt_codec_ctx, pd)) {
1277 ASN__DECODE_STARVED;
1279 ASN_DEBUG("Skipped overflow extension");
1288 if(specs->first_extension >= 0) {
1290 /* Fill DEFAULT members in extensions */
1291 for(i = specs->roms_count; i < specs->roms_count + specs->aoms_count;
1293 asn_TYPE_member_t *elm;
1294 void **memb_ptr2; /* Pointer to member pointer */
1296 edx = specs->oms[i];
1297 elm = &td->elements[edx];
1299 if(!elm->default_value_set) continue;
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;
1306 continue; /* Extensions are all optionals */
1309 /* Set default value */
1310 if(elm->default_value_set(memb_ptr2)) {
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;
1330 if(specs->first_extension < 0) {
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 */
1341 /* Fetch the pointer to this member */
1342 if(elm->flags & ATF_POINTER) {
1344 (const void *const *)((const char *)sptr + elm->memb_offset);
1345 present = (*memb_ptr2 != 0);
1347 memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
1348 memb_ptr2 = &memb_ptr;
1352 ASN_DEBUG("checking %s:%s (@%" ASN_PRI_SIZE ") present => %d", elm->name,
1353 elm->type->name, edx, present);
1355 exts_present += present;
1357 /* Encode as presence marker */
1358 if(po1 && per_put_few_bits(po1, present, 1)) {
1361 /* Encode as open type field */
1363 && uper_open_type_put(elm->type,
1364 elm->encoding_constraints.per_constraints,
1369 return exts_present ? exts_count : 0;
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};
1390 ASN_DEBUG("Encoding %s as SEQUENCE (UPER)", td->name);
1393 * X.691#18.1 Whether structure is extensible
1394 * and whether to encode extensions
1396 if(specs->first_extension < 0) {
1397 n_extensions = 0; /* There are no extensions to encode */
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)) {
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 */
1413 edx = specs->oms[i];
1414 elm = &td->elements[edx];
1416 /* Fetch the pointer to this member */
1417 if(elm->flags & ATF_POINTER) {
1419 (const void *const *)((const char *)sptr + elm->memb_offset);
1420 present = (*memb_ptr2 != 0);
1422 memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
1423 memb_ptr2 = &memb_ptr;
1427 /* Eliminate default values */
1428 if(present && elm->default_value_cmp
1429 && elm->default_value_cmp(*memb_ptr2) == 0)
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))
1441 * Encode the sequence ROOT elements.
1443 ASN_DEBUG("first_extension = %d, elements = %d", specs->first_extension,
1444 td->elements_count);
1446 edx < ((specs->first_extension < 0) ? td->elements_count
1447 : (size_t)specs->first_extension);
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 */
1453 ASN_DEBUG("About to encode %s", elm->type->name);
1455 /* Fetch the pointer to this member */
1456 if(elm->flags & ATF_POINTER) {
1458 (const void *const *)((const char *)sptr + elm->memb_offset);
1460 ASN_DEBUG("Element %s %" ASN_PRI_SIZE " not present",
1464 /* Mandatory element is missing */
1468 memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
1469 memb_ptr2 = &memb_ptr;
1472 /* Eliminate default values */
1473 if(elm->default_value_cmp && elm->default_value_cmp(*memb_ptr2) == 0)
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,
1480 if(er.encoded == -1) return er;
1483 /* No extensions to encode */
1484 if(!n_extensions) ASN__ENCODED_OK(er);
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))
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)
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)
1502 ASN__ENCODED_OK(er);
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;
1519 if(ASN__STACK_OVERFLOW_CHECK(opt_codec_ctx))
1523 st = *sptr = CALLOC(1, specs->struct_size);
1524 if(!st) ASN__DECODE_FAILED;
1527 ASN_DEBUG("Decoding %s as SEQUENCE (APER)", td->name);
1529 /* Handle extensions */
1530 if(specs->first_extension < 0) {
1533 extpresent = per_get_few_bits(pd, 1);
1534 if(extpresent < 0) ASN__DECODE_STARVED;
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)) {
1545 ASN__DECODE_STARVED;
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);
1556 * Get the sequence ROOT elements.
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 */
1566 if(IN_EXTENSION_GROUP(specs, edx))
1569 /* Fetch the pointer to this member */
1570 if(elm->flags & ATF_POINTER) {
1571 memb_ptr2 = (void **)((char *)st + elm->memb_offset);
1573 memb_ptr = (char *)st + elm->memb_offset;
1574 memb_ptr2 = &memb_ptr;
1578 padding = (8 - (pd->moved % 8)) % 8;
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);
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);
1590 per_get_few_bits(pd, padding);
1592 #endif /* dealing with padding */
1594 /* Deal with optionality */
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);
1601 /* This element is not present */
1602 if(elm->default_value_set) {
1603 /* Fill-in DEFAULT */
1604 if(elm->default_value_set(memb_ptr2)) {
1608 ASN_DEBUG("Filled-in default");
1610 /* The member is just not present */
1616 /* Fetch the member from the stream */
1617 ASN_DEBUG("Decoding member \"%s\" in %s", elm->name, td->name);
1619 if(elm->flags & ATF_OPEN_TYPE) {
1620 rv = OPEN_TYPE_aper_get(opt_codec_ctx, td, st, elm, pd);
1622 rv = elm->type->op->aper_decoder(opt_codec_ctx, elm->type,
1623 elm->encoding_constraints.per_constraints, memb_ptr2, pd);
1625 if(rv.code != RC_OK) {
1626 ASN_DEBUG("Failed decode %s in %s",
1627 elm->name, td->name);
1633 /* Optionality map is not needed anymore */
1637 * Deal with extensions.
1641 uint8_t *epres; /* Presence of extension members */
1642 asn_per_data_t epmd;
1644 bmlength = aper_get_nslength(pd);
1645 if(bmlength < 0) ASN__DECODE_STARVED;
1647 ASN_DEBUG("Extensions %" ASN_PRI_SSIZE " present in %s", bmlength, td->name);
1649 epres = (uint8_t *)MALLOC((bmlength + 15) >> 3);
1650 if(!epres) ASN__DECODE_STARVED;
1652 /* Get the extensions map */
1653 if(per_get_many_bits(pd, epres, 0, bmlength))
1654 ASN__DECODE_STARVED;
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);
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 */
1669 if(!IN_EXTENSION_GROUP(specs, edx)) {
1670 ASN_DEBUG("%ld is not extension", edx);
1674 /* Fetch the pointer to this member */
1675 if(elm->flags & ATF_POINTER) {
1676 memb_ptr2 = (void **)((char *)st + elm->memb_offset);
1678 memb_ptr = (void *)((char *)st + elm->memb_offset);
1679 memb_ptr2 = &memb_ptr;
1682 present = per_get_few_bits(&epmd, 1);
1684 if(present < 0) break; /* No more extensions */
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) {
1697 /* Skip over overflow extensions which aren't present
1698 * in this system's version of the protocol */
1700 ASN_DEBUG("Getting overflow extensions");
1701 switch(per_get_few_bits(&epmd, 1)) {
1707 if(aper_open_type_skip(opt_codec_ctx, pd)) {
1709 ASN__DECODE_STARVED;
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 */
1724 if(!elm->default_value_set) continue;
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;
1732 continue; /* Extensions are all optionals */
1735 /* Set default value */
1736 if(elm->default_value_set(memb_ptr2)) {
1747 SEQUENCE_handle_extensions_aper(const asn_TYPE_descriptor_t *td,
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;
1756 if(specs->first_extension < 0) {
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 */
1767 if(!IN_EXTENSION_GROUP(specs, edx)) {
1768 ASN_DEBUG("%s (@%ld) is not extension", elm->type->name, edx);
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);
1777 memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
1778 memb_ptr2 = &memb_ptr;
1782 ASN_DEBUG("checking %s (@%ld) present => %d",
1783 elm->type->name, edx, present);
1785 exts_present += present;
1787 /* Encode as presence marker */
1788 if(po1 && per_put_few_bits(po1, present, 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))
1797 return exts_present ? exts_count : 0;
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};
1818 ASN_DEBUG("Encoding %s as SEQUENCE (APER)", td->name);
1821 * X.691#18.1 Whether structure is extensible
1822 * and whether to encode extensions
1824 if(specs->first_extension < 0) {
1825 n_extensions = 0; /* There are no extensions to encode */
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)) {
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 */
1841 edx = specs->oms[i];
1842 elm = &td->elements[edx];
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);
1849 memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
1850 memb_ptr2 = &memb_ptr;
1854 /* Eliminate default values */
1855 if(present && elm->default_value_cmp
1856 && elm->default_value_cmp(memb_ptr2) == 1)
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))
1868 * Encode the sequence ROOT elements.
1870 ASN_DEBUG("first_extension = %d, elements = %d", specs->first_extension,
1871 td->elements_count);
1873 edx < ((specs->first_extension < 0) ? td->elements_count
1874 : (size_t)specs->first_extension);
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 */
1880 if(IN_EXTENSION_GROUP(specs, edx))
1883 ASN_DEBUG("About to encode %s", elm->type->name);
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);
1889 ASN_DEBUG("Element %s %ld not present",
1893 /* Mandatory element is missing */
1897 memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
1898 memb_ptr2 = &memb_ptr;
1901 /* Eliminate default values */
1902 if(elm->default_value_cmp && elm->default_value_cmp(memb_ptr2) == 1)
1905 ASN_DEBUG("Encoding %s->%s", td->name, elm->name);
1906 er = elm->type->op->aper_encoder(elm->type, elm->encoding_constraints.per_constraints,
1908 if(er.encoded == -1)
1912 /* No extensions to encode */
1913 if(!n_extensions) ASN__ENCODED_OK(er);
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))
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)
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)
1931 ASN__ENCODED_OK(er);
1934 #endif /* ASN_DISABLE_PER_SUPPORT */
1937 SEQUENCE_compare(const asn_TYPE_descriptor_t *td, const void *aptr,
1941 for(edx = 0; edx < td->elements_count; edx++) {
1942 asn_TYPE_member_t *elm = &td->elements[edx];
1947 if(elm->flags & ATF_POINTER) {
1949 *(const void *const *)((const char *)aptr + elm->memb_offset);
1951 *(const void *const *)((const char *)bptr + elm->memb_offset);
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 */
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 */
1969 amemb = (const void *)((const char *)aptr + elm->memb_offset);
1970 bmemb = (const void *)((const char *)bptr + elm->memb_offset);
1973 ret = elm->type->op->compare_struct(elm->type, amemb, bmemb);
1974 if(ret != 0) return ret;
1980 asn_TYPE_operation_t asn_OP_SEQUENCE = {
1984 SEQUENCE_decode_ber,
1985 SEQUENCE_encode_der,
1986 SEQUENCE_decode_xer,
1987 SEQUENCE_encode_xer,
1988 #ifdef ASN_DISABLE_OER_SUPPORT
1992 SEQUENCE_decode_oer,
1993 SEQUENCE_encode_oer,
1994 #endif /* ASN_DISABLE_OER_SUPPORT */
1995 #ifdef ASN_DISABLE_PER_SUPPORT
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 */
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};
2023 if(max_length == 0) return result_skipped;
2028 st = CALLOC(1, specs->struct_size);
2030 return result_failed;
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;
2040 if(elm->optional && asn_random_between(0, 4) == 2) {
2041 /* Sometimes decide not to fill the optional value */
2045 if(elm->flags & ATF_POINTER) {
2046 /* Member is a pointer to another structure */
2047 memb_ptr2 = (void **)((char *)st + elm->memb_offset);
2049 memb_ptr = (char *)st + elm->memb_offset;
2050 memb_ptr2 = &memb_ptr;
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) {
2058 result_ok.length += tmpres.length;
2060 case ARFILL_SKIPPED:
2061 assert(!(elm->flags & ATF_POINTER) || *memb_ptr2 == NULL);
2065 ASN_STRUCT_RESET(*td, st);
2067 ASN_STRUCT_FREE(*td, st);