3 * Copyright (c) 2017 Lev Walkin <vlm@lionet.info>. All rights reserved.
4 * Redistribution and modifications are permitted subject to BSD license.
6 #include <asn_internal.h>
8 #include <constr_CHOICE.h>
9 #include <per_opentype.h>
12 asn_TYPE_operation_t asn_OP_OPEN_TYPE = {
20 #ifdef ASN_DISABLE_OER_SUPPORT
21 0, 0, /* No OER support, use "-gen-OER" to enable */
26 #ifdef ASN_DISABLE_PER_SUPPORT
29 OPEN_TYPE_decode_uper,
30 OPEN_TYPE_encode_uper,
31 OPEN_TYPE_decode_aper,
32 OPEN_TYPE_encode_aper,
34 0, /* Random fill is not supported for open type */
35 0 /* Use generic outmost tag fetcher */
39 #define ADVANCE(num_bytes) \
41 size_t num = num_bytes; \
42 ptr = ((const char *)ptr) + num; \
44 consumed_myself += num; \
48 OPEN_TYPE_ber_get(const asn_codec_ctx_t *opt_codec_ctx,
49 const asn_TYPE_descriptor_t *td, void *sptr,
50 const asn_TYPE_member_t *elm, const void *ptr, size_t size) {
51 size_t consumed_myself = 0;
52 asn_type_selector_result_t selected;
53 void *memb_ptr; /* Pointer to the member */
54 void **memb_ptr2; /* Pointer to that pointer */
58 if(!(elm->flags & ATF_OPEN_TYPE)) {
62 if(!elm->type_selector) {
63 ASN_DEBUG("Type selector is not defined for Open Type %s->%s->%s",
64 td->name, elm->name, elm->type->name);
68 selected = elm->type_selector(td, sptr);
69 if(!selected.presence_index) {
73 /* Fetch the pointer to this member */
74 if(elm->flags & ATF_POINTER) {
75 memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
77 memb_ptr = (char *)sptr + elm->memb_offset;
78 memb_ptr2 = &memb_ptr;
80 if(*memb_ptr2 != NULL) {
81 /* Make sure we reset the structure first before encoding */
82 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0) != 0) {
89 + elm->type->elements[selected.presence_index - 1].memb_offset;
91 ASN_DEBUG("presence %d\n", selected.presence_index);
93 rv = selected.type_descriptor->op->ber_decoder(
94 opt_codec_ctx, selected.type_descriptor, &inner_value, ptr, size,
100 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
101 selected.presence_index)
104 rv.consumed = consumed_myself;
107 /* Oh, now a full-blown failure failure */
111 rv.consumed = consumed_myself;
118 if(elm->flags & ATF_POINTER) {
119 ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
122 ASN_STRUCT_RESET(*selected.type_descriptor,
130 OPEN_TYPE_xer_get(const asn_codec_ctx_t *opt_codec_ctx,
131 const asn_TYPE_descriptor_t *td, void *sptr,
132 const asn_TYPE_member_t *elm, const void *ptr, size_t size) {
133 size_t consumed_myself = 0;
134 asn_type_selector_result_t selected;
135 void *memb_ptr; /* Pointer to the member */
136 void **memb_ptr2; /* Pointer to that pointer */
142 pxer_chunk_type_e ch_type;
144 if(!(elm->flags & ATF_OPEN_TYPE)) {
148 if(!elm->type_selector) {
149 ASN_DEBUG("Type selector is not defined for Open Type %s->%s->%s",
150 td->name, elm->name, elm->type->name);
154 selected = elm->type_selector(td, sptr);
155 if(!selected.presence_index) {
159 /* Fetch the pointer to this member */
160 assert(elm->flags == ATF_OPEN_TYPE);
161 if(elm->flags & ATF_POINTER) {
162 memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
164 memb_ptr = (char *)sptr + elm->memb_offset;
165 memb_ptr2 = &memb_ptr;
167 if(*memb_ptr2 != NULL) {
168 /* Make sure we reset the structure first before encoding */
169 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0)
179 ch_size = xer_next_token(&xer_context, ptr, size, &ch_type);
198 * Wrapper value confirmed.
200 switch(xer_check_tag(ptr, ch_size, elm->name)) {
211 + elm->type->elements[selected.presence_index - 1].memb_offset;
213 rv = selected.type_descriptor->op->xer_decoder(
214 opt_codec_ctx, selected.type_descriptor, &inner_value, NULL, ptr, size);
215 ADVANCE(rv.consumed);
219 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
220 selected.presence_index)
228 /* Point to a best position where failure occurred */
229 rv.consumed = consumed_myself;
232 /* Wrt. rv.consumed==0:
233 * In case a genuine RC_WMORE, the whole Open Type decoding
234 * will have to be restarted.
237 if(elm->flags & ATF_POINTER) {
238 ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
241 ASN_STRUCT_RESET(*selected.type_descriptor,
252 ch_size = xer_next_token(&xer_context, ptr, size, &ch_type);
271 * Wrapper value confirmed.
273 switch(xer_check_tag(ptr, ch_size, elm->name)) {
282 rv.consumed += consumed_myself;
288 #ifndef ASN_DISABLE_PER_SUPPORT
291 OPEN_TYPE_uper_get(const asn_codec_ctx_t *opt_codec_ctx,
292 const asn_TYPE_descriptor_t *td, void *sptr,
293 const asn_TYPE_member_t *elm, asn_per_data_t *pd) {
294 asn_type_selector_result_t selected;
295 void *memb_ptr; /* Pointer to the member */
296 void **memb_ptr2; /* Pointer to that pointer */
300 if(!(elm->flags & ATF_OPEN_TYPE)) {
304 if(!elm->type_selector) {
305 ASN_DEBUG("Type selector is not defined for Open Type %s->%s->%s",
306 td->name, elm->name, elm->type->name);
310 selected = elm->type_selector(td, sptr);
311 if(!selected.presence_index) {
315 /* Fetch the pointer to this member */
316 assert(elm->flags == ATF_OPEN_TYPE);
317 if(elm->flags & ATF_POINTER) {
318 memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
320 memb_ptr = (char *)sptr + elm->memb_offset;
321 memb_ptr2 = &memb_ptr;
323 if(*memb_ptr2 != NULL) {
324 /* Make sure we reset the structure first before encoding */
325 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0)
333 + elm->type->elements[selected.presence_index - 1].memb_offset;
335 rv = uper_open_type_get(opt_codec_ctx, selected.type_descriptor, NULL,
339 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
340 selected.presence_index)
350 if(elm->flags & ATF_POINTER) {
351 ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
354 ASN_STRUCT_RESET(*selected.type_descriptor,
363 OPEN_TYPE_encode_uper(const asn_TYPE_descriptor_t *td,
364 const asn_per_constraints_t *constraints,
365 const void *sptr, asn_per_outp_t *po) {
366 const void *memb_ptr; /* Pointer to the member */
367 asn_TYPE_member_t *elm; /* CHOICE's element */
368 asn_enc_rval_t er = {0,0,0};
373 present = CHOICE_variant_get_presence(td, sptr);
374 if(present == 0 || present > td->elements_count) {
380 ASN_DEBUG("Encoding %s OPEN TYPE element %d", td->name, present);
382 elm = &td->elements[present];
383 if(elm->flags & ATF_POINTER) {
384 /* Member is a pointer to another structure */
386 *(const void *const *)((const char *)sptr + elm->memb_offset);
387 if(!memb_ptr) ASN__ENCODE_FAILED;
389 memb_ptr = (const char *)sptr + elm->memb_offset;
392 if(uper_open_type_put(elm->type, NULL, memb_ptr, po) < 0) {
401 OPEN_TYPE_aper_get(const asn_codec_ctx_t *opt_codec_ctx,
402 const asn_TYPE_descriptor_t *td, void *sptr,
403 const asn_TYPE_member_t *elm, asn_per_data_t *pd) {
404 asn_type_selector_result_t selected;
405 void *memb_ptr; /* Pointer to the member */
406 void **memb_ptr2; /* Pointer to that pointer */
410 if(!(elm->flags & ATF_OPEN_TYPE)) {
414 if(!elm->type_selector) {
415 ASN_DEBUG("Type selector is not defined for Open Type %s->%s->%s",
416 td->name, elm->name, elm->type->name);
420 selected = elm->type_selector(td, sptr);
421 if(!selected.presence_index) {
425 /* Fetch the pointer to this member */
426 assert(elm->flags == ATF_OPEN_TYPE);
427 if(elm->flags & ATF_POINTER) {
428 memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
430 memb_ptr = (char *)sptr + elm->memb_offset;
431 memb_ptr2 = &memb_ptr;
433 if(*memb_ptr2 != NULL) {
434 /* Make sure we reset the structure first before encoding */
435 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0)
443 + elm->type->elements[selected.presence_index - 1].memb_offset;
445 rv = aper_open_type_get(opt_codec_ctx, selected.type_descriptor, NULL,
449 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
450 selected.presence_index)
460 if(elm->flags & ATF_POINTER) {
461 ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
464 ASN_STRUCT_RESET(*selected.type_descriptor,
473 OPEN_TYPE_encode_aper(const asn_TYPE_descriptor_t *td,
474 const asn_per_constraints_t *constraints,
475 const void *sptr, asn_per_outp_t *po) {
476 const void *memb_ptr; /* Pointer to the member */
477 asn_TYPE_member_t *elm; /* CHOICE's element */
478 asn_enc_rval_t er = {0,0,0};
483 present = CHOICE_variant_get_presence(td, sptr);
484 if(present == 0 || present > td->elements_count) {
490 ASN_DEBUG("Encoding %s OPEN TYPE element %d", td->name, present);
492 elm = &td->elements[present];
493 if(elm->flags & ATF_POINTER) {
494 /* Member is a pointer to another structure */
496 *(const void *const *)((const char *)sptr + elm->memb_offset);
497 if(!memb_ptr) ASN__ENCODE_FAILED;
499 memb_ptr = (const char *)sptr + elm->memb_offset;
502 if(aper_open_type_put(elm->type, NULL, memb_ptr, po) < 0) {
510 #endif /* ASN_DISABLE_PER_SUPPORT */