SIM-115: update simulator to use latest E2SM KPM version 3
[sim/e2-interface.git] / e2sim / asn1c / OPEN_TYPE_ber.c
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  */
6 #include <asn_internal.h>
7 #include <OPEN_TYPE.h>
8 #include <constr_CHOICE.h>
9
10 asn_dec_rval_t
11 OPEN_TYPE_ber_get(const asn_codec_ctx_t *opt_codec_ctx,
12                   const asn_TYPE_descriptor_t *td, void *sptr,
13                   const asn_TYPE_member_t *elm, const void *ptr, size_t size) {
14     size_t consumed_myself = 0;
15     asn_type_selector_result_t selected;
16     void *memb_ptr;   /* Pointer to the member */
17     void **memb_ptr2; /* Pointer to that pointer */
18     void *inner_value;
19     asn_dec_rval_t rv;
20
21     if(!(elm->flags & ATF_OPEN_TYPE)) {
22         ASN__DECODE_FAILED;
23     }
24
25     if(!elm->type_selector) {
26         ASN_DEBUG("Type selector is not defined for Open Type %s->%s->%s",
27                   td->name, elm->name, elm->type->name);
28         ASN__DECODE_FAILED;
29     }
30
31     selected = elm->type_selector(td, sptr);
32     if(!selected.presence_index) {
33         ASN__DECODE_FAILED;
34     }
35
36     /* Fetch the pointer to this member */
37     if(elm->flags & ATF_POINTER) {
38         memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
39     } else {
40         memb_ptr = (char *)sptr + elm->memb_offset;
41         memb_ptr2 = &memb_ptr;
42     }
43     if(*memb_ptr2 != NULL) {
44         /* Make sure we reset the structure first before encoding */
45         if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0) != 0) {
46             ASN__DECODE_FAILED;
47         }
48     }
49
50     inner_value =
51         (char *)*memb_ptr2
52         + elm->type->elements[selected.presence_index - 1].memb_offset;
53
54     ASN_DEBUG("presence %d\n", selected.presence_index);
55
56     rv = selected.type_descriptor->op->ber_decoder(
57         opt_codec_ctx, selected.type_descriptor, &inner_value, ptr, size,
58         elm->tag_mode);
59     ADVANCE(rv.consumed);
60     rv.consumed = 0;
61     switch(rv.code) {
62     case RC_OK:
63         if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
64                                        selected.presence_index)
65            == 0) {
66             rv.code = RC_OK;
67             rv.consumed = consumed_myself;
68             return rv;
69         } else {
70             /* Oh, now a full-blown failure failure */
71         }
72         /* Fall through */
73     case RC_FAIL:
74         rv.consumed = consumed_myself;
75         /* Fall through */
76     case RC_WMORE:
77         break;
78     }
79
80     if(*memb_ptr2) {
81         if(elm->flags & ATF_POINTER) {
82             ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
83             *memb_ptr2 = NULL;
84         } else {
85             ASN_STRUCT_RESET(*selected.type_descriptor,
86                                           inner_value);
87         }
88     }
89     return rv;
90 }