X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=asn1c_defs%2Fconstr_CHOICE.c;h=86dcbb030a6f1b76bec8efdc51eb44b536cfa798;hb=28b894594573ab1e7087ed8fb50b208d7b135b07;hp=613e6ea78cdfb1f1381123486afa907c132fc146;hpb=6d677813b02deda27db8039ec0de86a5332caa1f;p=ric-app%2Fhw.git diff --git a/asn1c_defs/constr_CHOICE.c b/asn1c_defs/constr_CHOICE.c index 613e6ea..86dcbb0 100644 --- a/asn1c_defs/constr_CHOICE.c +++ b/asn1c_defs/constr_CHOICE.c @@ -1017,6 +1017,7 @@ CHOICE_decode_aper(const asn_codec_ctx_t *opt_codec_ctx, const asn_CHOICE_specifics_t *specs = (const asn_CHOICE_specifics_t *)td->specifics; asn_dec_rval_t rv; const asn_per_constraint_t *ct; + const asn_per_constraint_t *ext_ct = NULL; asn_TYPE_member_t *elm; /* CHOICE's element */ void *memb_ptr; void **memb_ptr2; @@ -1042,9 +1043,13 @@ CHOICE_decode_aper(const asn_codec_ctx_t *opt_codec_ctx, if(ct && ct->flags & APC_EXTENSIBLE) { value = per_get_few_bits(pd, 1); if(value < 0) ASN__DECODE_STARVED; - if(value) ct = 0; /* Not restricted */ + if(value) { + ext_ct = ct; + 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; @@ -1055,7 +1060,7 @@ CHOICE_decode_aper(const asn_codec_ctx_t *opt_codec_ctx, } else { if(specs->ext_start == -1) ASN__DECODE_FAILED; - value = uper_get_nsnnwn(pd); + value = aper_get_nsnnwn(pd, ext_ct->range_bits); if(value < 0) ASN__DECODE_STARVED; value += specs->ext_start; if((unsigned)value >= td->elements_count) @@ -1083,7 +1088,7 @@ CHOICE_decode_aper(const asn_codec_ctx_t *opt_codec_ctx, rv = elm->type->op->aper_decoder(opt_codec_ctx, elm->type, elm->encoding_constraints.per_constraints, memb_ptr2, pd); } else { - rv = uper_open_type_get(opt_codec_ctx, elm->type, + rv = aper_open_type_get(opt_codec_ctx, elm->type, elm->encoding_constraints.per_constraints, memb_ptr2, pd); } @@ -1099,10 +1104,12 @@ CHOICE_encode_aper(const asn_TYPE_descriptor_t *td, const void *sptr, asn_per_outp_t *po) { const asn_CHOICE_specifics_t *specs = (const asn_CHOICE_specifics_t *)td->specifics; const asn_TYPE_member_t *elm; /* CHOICE's element */ - const asn_per_constraint_t *ct; + const asn_per_constraint_t *ct = NULL; + const asn_per_constraint_t *ext_ct = NULL; const void *memb_ptr; - int present; - + unsigned present; + int present_enc; + if(!sptr) ASN__ENCODE_FAILED; ASN_DEBUG("Encoding %s as CHOICE using ALIGNED PER", td->name); @@ -1110,7 +1117,7 @@ CHOICE_encode_aper(const asn_TYPE_descriptor_t *td, if(constraints) ct = &constraints->value; else if(td->encoding_constraints.per_constraints) ct = &td->encoding_constraints.per_constraints->value; - else ct = 0; + else ct = NULL; present = _fetch_present_idx(sptr, specs->pres_offset, specs->pres_size); @@ -1126,25 +1133,38 @@ CHOICE_encode_aper(const asn_TYPE_descriptor_t *td, /* Adjust if canonical order is different from natural order */ if(specs->to_canonical_order) - present = specs->to_canonical_order[present]; - + present_enc = specs->to_canonical_order[present]; + else + present_enc = present; + ASN_DEBUG("Encoding %s CHOICE element %d", td->name, present); - if(ct && ct->range_bits >= 0) { - if(present < ct->lower_bound - || present > ct->upper_bound) { - if(ct->flags & APC_EXTENSIBLE) { - if(per_put_few_bits(po, 1, 1)) - ASN__ENCODE_FAILED; - } else { - ASN__ENCODE_FAILED; - } - ct = 0; - } + if(ct && (ct->range_bits >= 0)) { + // Value is not within the range of the primary values ? + if(present < ct->lower_bound || present > ct->upper_bound) { + if(ct->flags & APC_EXTENSIBLE) { + ASN_DEBUG("CHOICE member %d (enc %d) is an extension (%ld..%ld)", + present, present_enc, ct->lower_bound, ct->upper_bound); + // X691/23.5 Extension marker = 1 + if(per_put_few_bits(po, 1, 1)) { + ASN__ENCODE_FAILED; + } + } else { + ASN__ENCODE_FAILED; + } + // no more need of constraint. + ext_ct = ct; + ct = NULL; + } } - if(ct && ct->flags & APC_EXTENSIBLE) { - if(per_put_few_bits(po, 0, 1)) - ASN__ENCODE_FAILED; + + if(ct && (ct->flags & APC_EXTENSIBLE)) { + ASN_DEBUG("CHOICE member %d (enc %d) is not an extension (%ld..%ld)", + present, present, ct->lower_bound, ct->upper_bound); + // X691.23.5 Extension marker = 0 + if(per_put_few_bits(po, 0, 1)) { + ASN__ENCODE_FAILED; + } } elm = &td->elements[present]; @@ -1156,8 +1176,10 @@ CHOICE_encode_aper(const asn_TYPE_descriptor_t *td, memb_ptr = (const char *)sptr + elm->memb_offset; } - if(ct && ct->range_bits >= 0) { - if(per_put_few_bits(po, present, ct->range_bits)) + if(ct && (ct->range_bits >= 0)) { + // By construction (ct != 0), the alternative value is a non extended one. + // X691/23.7 X691/23.6 alternative value encoded as a range_bits bits value. + if(per_put_few_bits(po, present_enc, ct->range_bits)) ASN__ENCODE_FAILED; return elm->type->op->aper_encoder(elm->type, elm->encoding_constraints.per_constraints, @@ -1166,10 +1188,10 @@ CHOICE_encode_aper(const asn_TYPE_descriptor_t *td, asn_enc_rval_t rval = {0,0,0}; if(specs->ext_start == -1) ASN__ENCODE_FAILED; - if (ct) { - if(aper_put_nsnnwn(po, ct->range_bits, present - specs->ext_start)) + // X691/23.8 normally encoded as a small non negative whole number + + if(ext_ct && aper_put_nsnnwn(po, ext_ct->range_bits, present_enc - specs->ext_start)) ASN__ENCODE_FAILED; - } if(aper_open_type_put(elm->type, elm->encoding_constraints.per_constraints, memb_ptr, po)) ASN__ENCODE_FAILED;