asn_dec_rval_t NativeEnumerated_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { asn_INTEGER_specifics_t *specs = (asn_INTEGER_specifics_t *)td->specifics; asn_dec_rval_t rval = { RC_OK, 0 }; long *native = (long *)*sptr; asn_per_constraint_t *ct; long value; (void)opt_codec_ctx; if(constraints) ct = &constraints->value; else if(td->per_constraints) ct = &td->per_constraints->value; else _ASN_DECODE_FAILED; /* Mandatory! */ if(!specs) _ASN_DECODE_FAILED; if(!native) { native = (long *)(*sptr = CALLOC(1, sizeof(*native))); if(!native) _ASN_DECODE_FAILED; } ASN_DEBUG("Decoding %s as NativeEnumerated", td->name); if(ct->flags & APC_EXTENSIBLE) { int inext = per_get_few_bits(pd, 1); if(inext < 0) _ASN_DECODE_STARVED; if(inext) ct = 0; } if(ct && ct->range_bits >= 0) { value = per_get_few_bits(pd, ct->range_bits); if(value < 0) _ASN_DECODE_STARVED; if(value >= (specs->extension ? specs->extension - 1 : specs->map_count)) _ASN_DECODE_FAILED; } else { if(!specs->extension) _ASN_DECODE_FAILED; /* * X.691, #10.6: normally small non-negative whole number; */ value = uper_get_nsnnwn(pd); if(value < 0) _ASN_DECODE_STARVED; value += specs->extension - 1; if(value >= specs->map_count) _ASN_DECODE_FAILED; } *native = specs->value2enum[value].nat_value; ASN_DEBUG("Decoded %s = %ld", td->name, *native); return rval; }
asn_dec_rval_t CHOICE_decode_uper(Allocator * allocator, asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics; asn_dec_rval_t rv; asn_per_constraint_t *ct; asn_TYPE_member_t *elm; /* CHOICE's element */ void *memb_ptr; void **memb_ptr2; void *st = *sptr; int value; if(_ASN_STACK_OVERFLOW_CHECK(opt_codec_ctx)) _ASN_DECODE_FAILED; /* * Create the target structure if it is not present already. */ if(!st) { st = *sptr = CXX_ALLOC_WRAP CALLOC(1, specs->struct_size); if(!st) _ASN_DECODE_FAILED; } if(constraints) ct = &constraints->value; else if(td->per_constraints) ct = &td->per_constraints->value; else ct = 0; if(ct && ct->flags & asn_per_constraint_s::APC_EXTENSIBLE) { value = per_get_few_bits(pd, 1); if(value < 0) _ASN_DECODE_STARVED; if(value) ct = 0; /* Not restricted */ } if(ct && ct->range_bits >= 0) { value = per_get_few_bits(pd, ct->range_bits); if(value < 0) _ASN_DECODE_STARVED; ASN_DEBUG("CHOICE %s got index %d in range %d", td->name, value, ct->range_bits); if(value > ct->upper_bound) _ASN_DECODE_FAILED; } else { if(specs->ext_start == -1) _ASN_DECODE_FAILED; value = uper_get_nsnnwn(pd); if(value < 0) _ASN_DECODE_STARVED; value += specs->ext_start; if(value >= td->elements_count) _ASN_DECODE_FAILED; } /* Adjust if canonical order is different from natural order */ if(specs->canonical_order) value = specs->canonical_order[value]; /* Set presence to be able to free it later */ _set_present_idx(st, specs->pres_offset, specs->pres_size, value + 1); elm = &td->elements[value]; if(elm->flags & ATF_POINTER) { /* Member is a pointer to another structure */ memb_ptr2 = (void **)((char *)st + elm->memb_offset); } else { memb_ptr = (char *)st + elm->memb_offset; memb_ptr2 = &memb_ptr; } ASN_DEBUG("Discovered CHOICE %s encodes %s", td->name, elm->name); if(ct && ct->range_bits >= 0) { rv = elm->type->uper_decoder(allocator, opt_codec_ctx, elm->type, elm->per_constraints, memb_ptr2, pd); } else { rv = uper_open_type_get(allocator, opt_codec_ctx, elm->type, elm->per_constraints, memb_ptr2, pd); } if(rv.code != RC_OK) ASN_DEBUG("Failed to decode %s in %s (CHOICE) %d", elm->name, td->name, rv.code); return rv; }