constr_CHOICE.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2003-2017 Lev Walkin <vlm@lionet.info>. All rights reserved.
3  * Redistribution and modifications are permitted subject to BSD license.
4  */
7 
10 #if !defined(ASN_DISABLE_PRINT_SUPPORT)
12 #else
13  0,
14 #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */
17 #if !defined(ASN_DISABLE_BER_SUPPORT)
20 #else
21  0,
22  0,
23 #endif /* !defined(ASN_DISABLE_BER_SUPPORT) */
24 #if !defined(ASN_DISABLE_XER_SUPPORT)
27 #else
28  0,
29  0,
30 #endif /* !defined(ASN_DISABLE_XER_SUPPORT) */
31 #if !defined(ASN_DISABLE_JER_SUPPORT)
34 #else
35  0,
36  0,
37 #endif /* !defined(ASN_DISABLE_JER_SUPPORT) */
38 #if !defined(ASN_DISABLE_OER_SUPPORT)
41 #else
42  0,
43  0,
44 #endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
45 #if !defined(ASN_DISABLE_UPER_SUPPORT)
48 #else
49  0,
50  0,
51 #endif /* !defined(ASN_DISABLE_UPER_SUPPORT) */
52 #if !defined(ASN_DISABLE_APER_SUPPORT)
55 #else
56  0,
57  0,
58 #endif /* !defined(ASN_DISABLE_APER_SUPPORT) */
59 #if !defined(ASN_DISABLE_RFILL_SUPPORT)
61 #else
62  0,
63 #endif /* !defined(ASN_DISABLE_RFILL_SUPPORT) */
65 };
66 
68 CHOICE_outmost_tag(const asn_TYPE_descriptor_t *td, const void *ptr, int tag_mode, ber_tlv_tag_t tag) {
69  const asn_CHOICE_specifics_t *specs = (const asn_CHOICE_specifics_t *)td->specifics;
70  unsigned present;
71 
72  assert(tag_mode == 0); (void)tag_mode;
73  assert(tag == 0); (void)tag;
74 
75  /*
76  * Figure out which CHOICE element is encoded.
77  */
78  present = _fetch_present_idx(ptr, specs->pres_offset, specs->pres_size);
79 
80  if(present > 0 && present <= td->elements_count) {
81  const asn_TYPE_member_t *elm = &td->elements[present-1];
82  const void *memb_ptr;
83 
84  if(elm->flags & ATF_POINTER) {
85  memb_ptr = *(const void * const *)
86  ((const char *)ptr + elm->memb_offset);
87  } else {
88  memb_ptr = (const void *)
89  ((const char *)ptr + elm->memb_offset);
90  }
91 
92  return asn_TYPE_outmost_tag(elm->type, memb_ptr,
93  elm->tag_mode, elm->tag);
94  } else {
95  return (ber_tlv_tag_t)-1;
96  }
97 }
98 
99 /*
100  * See the definitions.
101  */
102 static const void *_get_member_ptr(const asn_TYPE_descriptor_t *,
103  const void *sptr, asn_TYPE_member_t **elm,
104  unsigned *present);
105 
106 int
107 CHOICE_constraint(const asn_TYPE_descriptor_t *td, const void *sptr,
108  asn_app_constraint_failed_f *ctfailcb, void *app_key) {
109  const asn_CHOICE_specifics_t *specs =
110  (const asn_CHOICE_specifics_t *)td->specifics;
111  unsigned present;
112 
113  if(!sptr) {
114  ASN__CTFAIL(app_key, td, sptr,
115  "%s: value not given (%s:%d)",
116  td->name, __FILE__, __LINE__);
117  return -1;
118  }
119 
120  /*
121  * Figure out which CHOICE element is encoded.
122  */
123  present = _fetch_present_idx(sptr, specs->pres_offset,specs->pres_size);
124  if(present > 0 && present <= td->elements_count) {
125  asn_TYPE_member_t *elm = &td->elements[present-1];
126  const void *memb_ptr;
127 
128  if(elm->flags & ATF_POINTER) {
129  memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset);
130  if(!memb_ptr) {
131  if(elm->optional)
132  return 0;
133  ASN__CTFAIL(app_key, td, sptr,
134  "%s: mandatory CHOICE element %s absent (%s:%d)",
135  td->name, elm->name, __FILE__, __LINE__);
136  return -1;
137  }
138  } else {
139  memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
140  }
141 
143  return elm->encoding_constraints.general_constraints(elm->type, memb_ptr,
144  ctfailcb, app_key);
145  } else {
147  memb_ptr, ctfailcb, app_key);
148  }
149  } else {
150  ASN__CTFAIL(app_key, td, sptr,
151  "%s: no CHOICE element given (%s:%d)",
152  td->name, __FILE__, __LINE__);
153  return -1;
154  }
155 }
156 
157 void
158 CHOICE_free(const asn_TYPE_descriptor_t *td, void *ptr,
159  enum asn_struct_free_method method) {
160  const asn_CHOICE_specifics_t *specs;
161  unsigned present;
162 
163  if(!td || !ptr)
164  return;
165 
166  specs = (const asn_CHOICE_specifics_t *)td->specifics;
167 
168  ASN_DEBUG("Freeing %s as CHOICE", td->name);
169 
170  /*
171  * Figure out which CHOICE element is encoded.
172  */
173  present = _fetch_present_idx(ptr, specs->pres_offset, specs->pres_size);
174 
175  /*
176  * Free that element.
177  */
178  if(present > 0 && present <= td->elements_count) {
179  asn_TYPE_member_t *elm = &td->elements[present-1];
180  void *memb_ptr;
181 
182  if(elm->flags & ATF_POINTER) {
183  memb_ptr = *(void **)((char *)ptr + elm->memb_offset);
184  if(memb_ptr)
185  ASN_STRUCT_FREE(*elm->type, memb_ptr);
186  } else {
187  memb_ptr = (void *)((char *)ptr + elm->memb_offset);
188  ASN_STRUCT_FREE_CONTENTS_ONLY(*elm->type, memb_ptr);
189  }
190  }
191 
192  switch(method) {
194  FREEMEM(ptr);
195  break;
197  break;
199  memset(ptr, 0, specs->struct_size);
200  break;
201  }
202 }
203 
204 
205 /*
206  * The following functions functions offer protection against -fshort-enums,
207  * compatible with little- and big-endian machines.
208  * If assertion is triggered, either disable -fshort-enums, or add an entry
209  * here with the ->pres_size of your target stracture.
210  * Unless the target structure is packed, the ".present" member
211  * is guaranteed to be aligned properly. ASN.1 compiler itself does not
212  * produce packed code.
213  */
214 unsigned
215 _fetch_present_idx(const void *struct_ptr, unsigned pres_offset,
216  unsigned pres_size) {
217  const void *present_ptr;
218  unsigned present;
219 
220  present_ptr = ((const char *)struct_ptr) + pres_offset;
221 
222  switch(pres_size) {
223  case sizeof(int): present = *(const unsigned int *)present_ptr; break;
224  case sizeof(short): present = *(const unsigned short *)present_ptr; break;
225  case sizeof(char): present = *(const unsigned char *)present_ptr; break;
226  default:
227  /* ANSI C mandates enum to be equivalent to integer */
228  assert(pres_size != sizeof(int));
229  return 0; /* If not aborted, pass back safe value */
230  }
231 
232  return present;
233 }
234 
235 void
236 _set_present_idx(void *struct_ptr, unsigned pres_offset, unsigned pres_size,
237  unsigned present) {
238  void *present_ptr;
239  present_ptr = ((char *)struct_ptr) + pres_offset;
240 
241  switch(pres_size) {
242  case sizeof(int): *(unsigned int *)present_ptr = present; break;
243  case sizeof(short): *(unsigned short *)present_ptr = present; break;
244  case sizeof(char): *(unsigned char *)present_ptr = present; break;
245  default:
246  /* ANSI C mandates enum to be equivalent to integer */
247  assert(pres_size != sizeof(int));
248  }
249 }
250 
251 static const void *
252 _get_member_ptr(const asn_TYPE_descriptor_t *td, const void *sptr,
253  asn_TYPE_member_t **elm_ptr, unsigned *present_out) {
254  const asn_CHOICE_specifics_t *specs =
255  (const asn_CHOICE_specifics_t *)td->specifics;
256  unsigned present;
257 
258  if(!sptr) {
259  *elm_ptr = NULL;
260  *present_out = 0;
261  return NULL;
262  }
263 
264  /*
265  * Figure out which CHOICE element is encoded.
266  */
267  present = _fetch_present_idx(sptr, specs->pres_offset, specs->pres_size);
268  *present_out = present;
269 
270  /*
271  * The presence index is intentionally 1-based to avoid
272  * treating zeroed structure as a valid one.
273  */
274  if(present > 0 && present <= td->elements_count) {
275  asn_TYPE_member_t *const elm = &td->elements[present - 1];
276  const void *memb_ptr;
277 
278  if(elm->flags & ATF_POINTER) {
279  memb_ptr =
280  *(const void *const *)((const char *)sptr + elm->memb_offset);
281  } else {
282  memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
283  }
284  *elm_ptr = elm;
285  return memb_ptr;
286  } else {
287  *elm_ptr = NULL;
288  return NULL;
289  }
290 
291 }
292 
293 int
294 CHOICE_compare(const asn_TYPE_descriptor_t *td, const void *aptr, const void *bptr) {
295  asn_TYPE_member_t *aelm;
296  asn_TYPE_member_t *belm;
297  unsigned apresent = 0;
298  unsigned bpresent = 0;
299  const void *amember = _get_member_ptr(td, aptr, &aelm, &apresent);
300  const void *bmember = _get_member_ptr(td, bptr, &belm, &bpresent);
301 
302  if(amember && bmember) {
303  if(apresent == bpresent) {
304  assert(aelm == belm);
305  return aelm->type->op->compare_struct(aelm->type, amember, bmember);
306  } else if(apresent < bpresent) {
307  return -1;
308  } else {
309  return 1;
310  }
311  } else if(!amember) {
312  return -1;
313  } else {
314  return 1;
315  }
316 }
317 
318 int
319 CHOICE_copy(const asn_TYPE_descriptor_t *td, void **aptr, const void *bptr) {
320  if(!td) return -1;
321 
322  void *st = *aptr;
323  const asn_CHOICE_specifics_t *specs =
324  (const asn_CHOICE_specifics_t *)td->specifics;
325  const asn_TYPE_member_t *elm; /* CHOICE's element */
326  int present;
327  int ret;
328  void *amemb;
329  void **amembp;
330  const void *bmemb;
331 
332  if(!bptr) {
333  if(st) {
334  ASN_STRUCT_FREE(*td, st);
335  *aptr = NULL;
336  }
337  return 0;
338  }
339 
340  if(!st) {
341  st = *aptr = CALLOC(1, specs->struct_size);
342  if(!st) return -1;
343  }
344 
345  present = _fetch_present_idx(bptr,
346  specs->pres_offset, specs->pres_size);
347 
348  if(present <= 0 && (unsigned)present > td->elements_count) return -1;
349  --present;
350 
351  elm = &td->elements[present];
352  if(elm->flags & ATF_POINTER) {
353  /* Member is a pointer to another structure */
354  amembp = (void **)((char *)st + elm->memb_offset);
355  bmemb = *(const void* const*)((const char*)bptr + elm->memb_offset);
356  } else {
357  amemb = (char *)st + elm->memb_offset;
358  amembp = &amemb;
359  bmemb = (const void*)((const char*)bptr + elm->memb_offset);
360  }
361  ret = elm->type->op->copy_struct(elm->type, amembp, bmemb);
362  if (ret != 0) return ret;
363 
364  _set_present_idx(st,
365  specs->pres_offset,
366  specs->pres_size, present + 1);
367 
368  return 0;
369 }
370 
371 /*
372  * Return the 1-based choice variant presence index.
373  * Returns 0 in case of error.
374  */
375 unsigned
377  const asn_CHOICE_specifics_t *specs =
378  (const asn_CHOICE_specifics_t *)td->specifics;
379  return _fetch_present_idx(sptr, specs->pres_offset, specs->pres_size);
380 }
381 
382 /*
383  * Sets or resets the 1-based choice variant presence index.
384  * In case a previous index is not zero, the currently selected structure
385  * member is freed and zeroed-out first.
386  * Returns 0 on success and -1 on error.
387  */
388 int
390  unsigned present) {
391  const asn_CHOICE_specifics_t *specs =
392  (const asn_CHOICE_specifics_t *)td->specifics;
393  unsigned old_present;
394 
395  if(!sptr) {
396  return -1;
397  }
398 
399  if(present > td->elements_count)
400  return -1;
401 
402  old_present =
403  _fetch_present_idx(sptr, specs->pres_offset, specs->pres_size);
404  if(present == old_present)
405  return 0;
406 
407  if(old_present != 0) {
408  assert(old_present <= td->elements_count);
409  ASN_STRUCT_RESET(*td, sptr);
410  }
411 
412  _set_present_idx(sptr, specs->pres_offset, specs->pres_size, present);
413 
414  return 0;
415 }
CHOICE_encode_xer
xer_type_encoder_f CHOICE_encode_xer
Definition: constr_CHOICE.h:60
ASN_STRUCT_FREE
#define ASN_STRUCT_FREE(asn_DEF, ptr)
Definition: constr_TYPE.h:102
asn_TYPE_outmost_tag
asn_outmost_tag_f asn_TYPE_outmost_tag
Definition: constr_TYPE.h:166
asn_TYPE_operation_s
Definition: constr_TYPE.h:184
CHOICE_encode_uper
per_type_encoder_f CHOICE_encode_uper
Definition: constr_CHOICE.h:75
ASFM_FREE_UNDERLYING
@ ASFM_FREE_UNDERLYING
Definition: constr_TYPE.h:92
asn_TYPE_member_s::memb_offset
unsigned memb_offset
Definition: constr_TYPE.h:275
CHOICE_variant_set_presence
int CHOICE_variant_set_presence(const asn_TYPE_descriptor_t *td, void *sptr, unsigned present)
Definition: constr_CHOICE.c:389
asn_app_constraint_failed_f
void() asn_app_constraint_failed_f(void *application_specific_key, const struct asn_TYPE_descriptor_s *type_descriptor_which_failed, const void *structure_which_failed_ptr, const char *error_message_format,...) CC_PRINTFLIKE(4
Definition: asn_application.h:167
CHOICE_decode_aper
per_type_decoder_f CHOICE_decode_aper
Definition: constr_CHOICE.h:78
CHOICE_decode_jer
jer_type_decoder_f CHOICE_decode_jer
Definition: constr_CHOICE.h:64
ber_tlv_tag_t
unsigned ber_tlv_tag_t
Definition: ber_tlv_tag.h:18
CHOICE_copy
int CHOICE_copy(const asn_TYPE_descriptor_t *td, void **aptr, const void *bptr)
Definition: constr_CHOICE.c:319
asn_TYPE_descriptor_s::elements_count
unsigned elements_count
Definition: constr_TYPE.h:253
CHOICE_encode_aper
per_type_encoder_f CHOICE_encode_aper
Definition: constr_CHOICE.h:79
asn_TYPE_descriptor_s::name
const char * name
Definition: constr_TYPE.h:225
CHOICE_compare
int CHOICE_compare(const asn_TYPE_descriptor_t *td, const void *aptr, const void *bptr)
Definition: constr_CHOICE.c:294
CHOICE_encode_der
der_type_encoder_f CHOICE_encode_der
Definition: constr_CHOICE.h:55
CHOICE_constraint
int CHOICE_constraint(const asn_TYPE_descriptor_t *td, const void *sptr, asn_app_constraint_failed_f *ctfailcb, void *app_key)
Definition: constr_CHOICE.c:107
CALLOC
#define CALLOC(nmemb, size)
Definition: asn_internal.h:37
ASFM_FREE_UNDERLYING_AND_RESET
@ ASFM_FREE_UNDERLYING_AND_RESET
Definition: constr_TYPE.h:93
asn_CHOICE_specifics_s::struct_size
unsigned struct_size
Definition: constr_CHOICE.h:18
ASFM_FREE_EVERYTHING
@ ASFM_FREE_EVERYTHING
Definition: constr_TYPE.h:91
asn_CHOICE_specifics_s
Definition: constr_CHOICE.h:14
ASN_STRUCT_RESET
#define ASN_STRUCT_RESET(asn_DEF, ptr)
Definition: constr_TYPE.h:112
CHOICE_encode_oer
oer_type_encoder_f CHOICE_encode_oer
Definition: constr_CHOICE.h:70
FREEMEM
#define FREEMEM(ptr)
Definition: asn_internal.h:40
CHOICE_decode_oer
oer_type_decoder_f CHOICE_decode_oer
Definition: constr_CHOICE.h:69
ATF_POINTER
@ ATF_POINTER
Definition: constr_TYPE.h:268
asn_TYPE_descriptor_s
Definition: constr_TYPE.h:224
asn_TYPE_member_s::type
asn_TYPE_descriptor_t * type
Definition: constr_TYPE.h:278
asn_TYPE_descriptor_s::specifics
const void * specifics
Definition: constr_TYPE.h:259
CHOICE_decode_ber
ber_type_decoder_f CHOICE_decode_ber
Definition: constr_CHOICE.h:54
asn_CHOICE_specifics_s::pres_offset
unsigned pres_offset
Definition: constr_CHOICE.h:20
asn_TYPE_member_s::name
const char * name
Definition: constr_TYPE.h:283
asn_TYPE_descriptor_s::op
asn_TYPE_operation_t * op
Definition: constr_TYPE.h:232
asn_struct_free_method
asn_struct_free_method
Definition: constr_TYPE.h:90
CHOICE_print
asn_struct_print_f CHOICE_print
Definition: constr_CHOICE.h:45
CHOICE_outmost_tag
ber_tlv_tag_t CHOICE_outmost_tag(const asn_TYPE_descriptor_t *td, const void *ptr, int tag_mode, ber_tlv_tag_t tag)
Definition: constr_CHOICE.c:68
asn_TYPE_operation_s::compare_struct
asn_struct_compare_f * compare_struct
Definition: constr_TYPE.h:187
asn_internal.h
ASN__CTFAIL
#define ASN__CTFAIL
Definition: constraints.h:57
asn_TYPE_descriptor_s::elements
struct asn_TYPE_member_s * elements
Definition: constr_TYPE.h:252
constr_CHOICE.h
asn_encoding_constraints_s::general_constraints
asn_constr_check_f * general_constraints
Definition: constr_TYPE.h:218
asn_TYPE_member_s::tag_mode
int tag_mode
Definition: constr_TYPE.h:277
_fetch_present_idx
unsigned _fetch_present_idx(const void *struct_ptr, unsigned pres_offset, unsigned pres_size)
Definition: constr_CHOICE.c:215
asn_OP_CHOICE
asn_TYPE_operation_t asn_OP_CHOICE
Definition: constr_CHOICE.c:8
CHOICE_random_fill
asn_random_fill_f CHOICE_random_fill
Definition: constr_CHOICE.h:83
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
CHOICE_decode_xer
xer_type_decoder_f CHOICE_decode_xer
Definition: constr_CHOICE.h:59
asn_TYPE_member_s::flags
enum asn_TYPE_flags_e flags
Definition: constr_TYPE.h:273
CHOICE_variant_get_presence
unsigned CHOICE_variant_get_presence(const asn_TYPE_descriptor_t *td, const void *sptr)
Definition: constr_CHOICE.c:376
_set_present_idx
void _set_present_idx(void *struct_ptr, unsigned pres_offset, unsigned pres_size, unsigned present)
Definition: constr_CHOICE.c:236
ASN_STRUCT_FREE_CONTENTS_ONLY
#define ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF, ptr)
Definition: constr_TYPE.h:123
asn_TYPE_member_s::tag
ber_tlv_tag_t tag
Definition: constr_TYPE.h:276
CHOICE_encode_jer
jer_type_encoder_f CHOICE_encode_jer
Definition: constr_CHOICE.h:65
CHOICE_free
void CHOICE_free(const asn_TYPE_descriptor_t *td, void *ptr, enum asn_struct_free_method method)
Definition: constr_CHOICE.c:158
_get_member_ptr
static const void * _get_member_ptr(const asn_TYPE_descriptor_t *, const void *sptr, asn_TYPE_member_t **elm, unsigned *present)
Definition: constr_CHOICE.c:252
asn_TYPE_member_s::encoding_constraints
asn_encoding_constraints_t encoding_constraints
Definition: constr_TYPE.h:280
asn_TYPE_member_s::optional
unsigned optional
Definition: constr_TYPE.h:274
CHOICE_decode_uper
per_type_decoder_f CHOICE_decode_uper
Definition: constr_CHOICE.h:74
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