constr_CHOICE_uper.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
3  * All rights reserved.
4  * Redistribution and modifications are permitted subject to BSD license.
5  */
9 
11 CHOICE_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
12  const asn_TYPE_descriptor_t *td,
13  const asn_per_constraints_t *constraints, void **sptr,
14  asn_per_data_t *pd) {
15  const asn_CHOICE_specifics_t *specs =
16  (const asn_CHOICE_specifics_t *)td->specifics;
17  asn_dec_rval_t rv;
18  const asn_per_constraint_t *ct;
19  asn_TYPE_member_t *elm; /* CHOICE's element */
20  void *memb_ptr;
21  void **memb_ptr2;
22  void *st = *sptr;
23  int value;
24 
25  if(ASN__STACK_OVERFLOW_CHECK(opt_codec_ctx))
27 
28  /*
29  * Create the target structure if it is not present already.
30  */
31  if(!st) {
32  st = *sptr = CALLOC(1, specs->struct_size);
33  if(!st) ASN__DECODE_FAILED;
34  }
35 
36  if(constraints) ct = &constraints->value;
38  else ct = 0;
39 
40  if(ct && ct->flags & APC_EXTENSIBLE) {
41  value = per_get_few_bits(pd, 1);
42  if(value < 0) ASN__DECODE_STARVED;
43  if(value) ct = 0; /* Not restricted */
44  }
45 
46  if(ct && ct->range_bits >= 0) {
47  value = per_get_few_bits(pd, ct->range_bits);
48  if(value < 0) ASN__DECODE_STARVED;
49  ASN_DEBUG("CHOICE %s got index %d in range %d",
50  td->name, value, ct->range_bits);
51  if(value > ct->upper_bound)
53  } else {
54  if(specs->ext_start == -1)
56  value = uper_get_nsnnwn(pd);
57  if(value < 0) ASN__DECODE_STARVED;
58  value += specs->ext_start;
59  if((unsigned)value >= td->elements_count)
61  }
62 
63  /* Adjust if canonical order is different from natural order */
64  if(specs->from_canonical_order) {
65  ASN_DEBUG("CHOICE presence from wire %d", value);
66  value = specs->from_canonical_order[value];
67  ASN_DEBUG("CHOICE presence index effective %d", value);
68  }
69 
70  /* Set presence to be able to free it later */
71  _set_present_idx(st, specs->pres_offset, specs->pres_size, value + 1);
72 
73  elm = &td->elements[value];
74  if(elm->flags & ATF_POINTER) {
75  /* Member is a pointer to another structure */
76  memb_ptr2 = (void **)((char *)st + elm->memb_offset);
77  } else {
78  memb_ptr = (char *)st + elm->memb_offset;
79  memb_ptr2 = &memb_ptr;
80  }
81  ASN_DEBUG("Discovered CHOICE %s encodes %s", td->name, elm->name);
82 
83  if(ct && ct->range_bits >= 0) {
84  rv = elm->type->op->uper_decoder(opt_codec_ctx, elm->type,
85  elm->encoding_constraints.per_constraints,
86  memb_ptr2, pd);
87  } else {
88  rv = uper_open_type_get(opt_codec_ctx, elm->type,
89  elm->encoding_constraints.per_constraints,
90  memb_ptr2, pd);
91  }
92 
93  if(rv.code != RC_OK)
94  ASN_DEBUG("Failed to decode %s in %s (CHOICE) %d",
95  elm->name, td->name, rv.code);
96  return rv;
97 }
98 
101  const asn_per_constraints_t *constraints, const void *sptr,
102  asn_per_outp_t *po) {
103  const asn_CHOICE_specifics_t *specs = (const asn_CHOICE_specifics_t *)td->specifics;
104  asn_TYPE_member_t *elm; /* CHOICE's element */
105  const asn_per_constraint_t *ct;
106  const void *memb_ptr;
107  unsigned present;
108  int present_enc;
109 
110  if(!sptr) ASN__ENCODE_FAILED;
111 
112  ASN_DEBUG("Encoding %s as CHOICE", td->name);
113 
114  if(constraints) ct = &constraints->value;
117  else ct = 0;
118 
119  present = _fetch_present_idx(sptr, specs->pres_offset, specs->pres_size);
120 
121  /*
122  * If the structure was not initialized properly, it cannot be encoded:
123  * can't deduce what to encode in the choice type.
124  */
125  if(present == 0 || present > td->elements_count)
127  else
128  present--;
129 
130  ASN_DEBUG("Encoding %s CHOICE element %d", td->name, present);
131 
132  /* Adjust if canonical order is different from natural order */
133  if(specs->to_canonical_order)
134  present_enc = specs->to_canonical_order[present];
135  else
136  present_enc = present;
137 
138  if(ct && ct->range_bits >= 0) {
139  if(present_enc < ct->lower_bound
140  || present_enc > ct->upper_bound) {
141  if(ct->flags & APC_EXTENSIBLE) {
142  ASN_DEBUG(
143  "CHOICE member %d (enc %d) is an extension (%"ASN_PRIdMAX"..%"ASN_PRIdMAX")",
144  present, present_enc, ct->lower_bound, ct->upper_bound);
145  if(per_put_few_bits(po, 1, 1))
147  } else {
149  }
150  ct = 0;
151  }
152  }
153  if(ct && ct->flags & APC_EXTENSIBLE) {
154  ASN_DEBUG("CHOICE member %d (enc %d) is not an extension (%"ASN_PRIdMAX"..%"ASN_PRIdMAX")",
155  present, present_enc, ct->lower_bound, ct->upper_bound);
156  if(per_put_few_bits(po, 0, 1))
158  }
159 
160 
161  elm = &td->elements[present];
162  ASN_DEBUG("CHOICE member \"%s\" %d (as %d)", elm->name, present,
163  present_enc);
164  if(elm->flags & ATF_POINTER) {
165  /* Member is a pointer to another structure */
166  memb_ptr =
167  *(const void *const *)((const char *)sptr + elm->memb_offset);
168  if(!memb_ptr) ASN__ENCODE_FAILED;
169  } else {
170  memb_ptr = (const char *)sptr + elm->memb_offset;
171  }
172 
173  if(ct && ct->range_bits >= 0) {
174  if(per_put_few_bits(po, present_enc, ct->range_bits))
176 
177  return elm->type->op->uper_encoder(
178  elm->type, elm->encoding_constraints.per_constraints, memb_ptr, po);
179  } else {
180  asn_enc_rval_t rval = {0,0,0};
181  if(specs->ext_start == -1) ASN__ENCODE_FAILED;
182  if(uper_put_nsnnwn(po, present_enc - specs->ext_start))
184  if(uper_open_type_put(elm->type,
185  elm->encoding_constraints.per_constraints,
186  memb_ptr, po))
188  rval.encoded = 0;
189  ASN__ENCODED_OK(rval);
190  }
191 }
asn_bit_outp_s
Definition: asn_bit_data.h:56
asn_TYPE_member_s::memb_offset
unsigned memb_offset
Definition: constr_TYPE.h:275
ASN_PRIdMAX
#define ASN_PRIdMAX
Definition: asn_system.h:181
ASN__ENCODED_OK
#define ASN__ENCODED_OK(rval)
Definition: asn_codecs.h:67
uper_open_type_put
int uper_open_type_put(const asn_TYPE_descriptor_t *td, const asn_per_constraints_t *constraints, const void *sptr, asn_per_outp_t *po)
Definition: uper_opentype.c:25
asn_TYPE_descriptor_s::elements_count
unsigned elements_count
Definition: constr_TYPE.h:253
uper_put_nsnnwn
int uper_put_nsnnwn(asn_per_outp_t *po, int n)
Definition: uper_support.c:101
asn_TYPE_descriptor_s::name
const char * name
Definition: constr_TYPE.h:225
asn_enc_rval_s
Definition: asn_codecs.h:41
CALLOC
#define CALLOC(nmemb, size)
Definition: asn_internal.h:37
per_get_few_bits
#define per_get_few_bits(data, bits)
Definition: per_support.h:39
asn_per_constraints_s::value
asn_per_constraint_t value
Definition: per_support.h:31
asn_CHOICE_specifics_s::struct_size
unsigned struct_size
Definition: constr_CHOICE.h:18
asn_per_constraint_s
Definition: per_support.h:18
asn_CHOICE_specifics_s
Definition: constr_CHOICE.h:14
asn_bit_data_s
Definition: asn_bit_data.h:17
CHOICE_decode_uper
asn_dec_rval_t CHOICE_decode_uper(const asn_codec_ctx_t *opt_codec_ctx, const asn_TYPE_descriptor_t *td, const asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd)
Definition: constr_CHOICE_uper.c:11
CHOICE_encode_uper
asn_enc_rval_t CHOICE_encode_uper(const asn_TYPE_descriptor_t *td, const asn_per_constraints_t *constraints, const void *sptr, asn_per_outp_t *po)
Definition: constr_CHOICE_uper.c:100
ATF_POINTER
@ ATF_POINTER
Definition: constr_TYPE.h:268
ASN__ENCODE_FAILED
#define ASN__ENCODE_FAILED
Definition: asn_codecs.h:59
_set_present_idx
void _set_present_idx(void *sptr, unsigned offset, unsigned size, unsigned present)
Definition: constr_CHOICE.c:236
asn_TYPE_descriptor_s
Definition: constr_TYPE.h:224
asn_TYPE_descriptor_s::specifics
const void * specifics
Definition: constr_TYPE.h:259
asn_CHOICE_specifics_s::pres_offset
unsigned pres_offset
Definition: constr_CHOICE.h:20
asn_CHOICE_specifics_s::ext_start
signed ext_start
Definition: constr_CHOICE.h:36
RC_OK
@ RC_OK
Definition: asn_codecs.h:82
ASN__STACK_OVERFLOW_CHECK
static int CC_NOTUSED ASN__STACK_OVERFLOW_CHECK(const asn_codec_ctx_t *ctx)
Definition: asn_internal.h:165
ASN__DECODE_STARVED
#define ASN__DECODE_STARVED
Definition: asn_codecs.h:97
asn_encoding_constraints_s::per_constraints
const struct asn_per_constraints_s * per_constraints
Definition: constr_TYPE.h:213
asn_internal.h
asn_CHOICE_specifics_s::to_canonical_order
const unsigned * to_canonical_order
Definition: constr_CHOICE.h:30
asn_CHOICE_specifics_s::from_canonical_order
const unsigned * from_canonical_order
Definition: constr_CHOICE.h:31
asn_codec_ctx_s
Definition: asn_codecs.h:23
asn_TYPE_descriptor_s::elements
struct asn_TYPE_member_s * elements
Definition: constr_TYPE.h:252
constr_CHOICE.h
asn_dec_rval_s
Definition: asn_codecs.h:86
ASN__DECODE_FAILED
#define ASN__DECODE_FAILED
Definition: asn_codecs.h:90
_fetch_present_idx
unsigned _fetch_present_idx(const void *struct_ptr, unsigned off, unsigned size)
Definition: constr_CHOICE.c:215
asn_enc_rval_s::encoded
ssize_t encoded
Definition: asn_codecs.h:47
asn_per_constraints_s
Definition: per_support.h:30
asn_TYPE_member_s
Definition: constr_TYPE.h:272
asn_TYPE_descriptor_s::encoding_constraints
asn_encoding_constraints_t encoding_constraints
Definition: constr_TYPE.h:247
uper_opentype.h
uper_get_nsnnwn
ssize_t uper_get_nsnnwn(asn_per_data_t *pd)
Definition: uper_support.c:75
per_put_few_bits
#define per_put_few_bits(out, bits, obits)
Definition: per_support.h:46
uper_open_type_get
asn_dec_rval_t uper_open_type_get(const asn_codec_ctx_t *opt_codec_ctx, const asn_TYPE_descriptor_t *td, const asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd)
Definition: uper_opentype.c:255
asn_CHOICE_specifics_s::pres_size
unsigned pres_size
Definition: constr_CHOICE.h:21


etsi_its_vam_ts_coding
Author(s): Jean-Pierre Busch , Guido Küppers , Lennart Reiher
autogenerated on Sun May 18 2025 02:30:55