SIM-115: update simulator to use latest E2SM KPM version 3
[sim/e2-interface.git] / e2sim / asn1c / OPEN_TYPE_xer.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_xer_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     int xer_context = 0;
22     ssize_t ch_size;
23     pxer_chunk_type_e ch_type;
24
25     if(!(elm->flags & ATF_OPEN_TYPE)) {
26         ASN__DECODE_FAILED;
27     }
28
29     if(!elm->type_selector) {
30         ASN_DEBUG("Type selector is not defined for Open Type %s->%s->%s",
31                   td->name, elm->name, elm->type->name);
32         ASN__DECODE_FAILED;
33     }
34
35     selected = elm->type_selector(td, sptr);
36     if(!selected.presence_index) {
37         ASN__DECODE_FAILED;
38     }
39
40     /* Fetch the pointer to this member */
41     assert(elm->flags == ATF_OPEN_TYPE);
42     if(elm->flags & ATF_POINTER) {
43         memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
44     } else {
45         memb_ptr = (char *)sptr + elm->memb_offset;
46         memb_ptr2 = &memb_ptr;
47     }
48     if(*memb_ptr2 != NULL) {
49         /* Make sure we reset the structure first before encoding */
50         if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0)
51            != 0) {
52             ASN__DECODE_FAILED;
53         }
54     }
55
56     /*
57      * Confirm wrapper.
58      */
59     for(;;) {
60         ch_size = xer_next_token(&xer_context, ptr, size, &ch_type);
61         if(ch_size < 0) {
62             ASN__DECODE_FAILED;
63         } else {
64             switch(ch_type) {
65             case PXER_WMORE:
66                 ASN__DECODE_STARVED;
67             case PXER_COMMENT:
68             case PXER_TEXT:
69                 ADVANCE(ch_size);
70                 continue;
71             case PXER_TAG:
72                 break;
73             }
74             break;
75         }
76     }
77
78     /*
79      * Wrapper value confirmed.
80      */
81     switch(xer_check_tag(ptr, ch_size, elm->name)) {
82     case XCT_OPENING:
83         ADVANCE(ch_size);
84         break;
85     case XCT_BROKEN:
86     default:
87         ASN__DECODE_FAILED;
88     }
89
90     inner_value =
91         (char *)*memb_ptr2
92         + elm->type->elements[selected.presence_index - 1].memb_offset;
93
94     rv = selected.type_descriptor->op->xer_decoder(
95         opt_codec_ctx, selected.type_descriptor, &inner_value, NULL, ptr, size);
96     ADVANCE(rv.consumed);
97     rv.consumed = 0;
98     switch(rv.code) {
99     case RC_OK:
100         if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
101                                        selected.presence_index)
102            == 0) {
103             break;
104         } else {
105             rv.code = RC_FAIL;
106         }
107         /* Fall through */
108     case RC_FAIL:
109         /* Point to a best position where failure occurred */
110         rv.consumed = consumed_myself;
111         /* Fall through */
112     case RC_WMORE:
113         /* Wrt. rv.consumed==0:
114          * In case a genuine RC_WMORE, the whole Open Type decoding
115          * will have to be restarted.
116          */
117         if(*memb_ptr2) {
118             if(elm->flags & ATF_POINTER) {
119                 ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
120                 *memb_ptr2 = NULL;
121             } else {
122                 ASN_STRUCT_RESET(*selected.type_descriptor,
123                                               inner_value);
124             }
125         }
126         return rv;
127     }
128
129     /*
130      * Finalize wrapper.
131      */
132     for(;;) {
133         ch_size = xer_next_token(&xer_context, ptr, size, &ch_type);
134         if(ch_size < 0) {
135             ASN__DECODE_FAILED;
136         } else {
137             switch(ch_type) {
138             case PXER_WMORE:
139                 ASN__DECODE_STARVED;
140             case PXER_COMMENT:
141             case PXER_TEXT:
142                 ADVANCE(ch_size);
143                 continue;
144             case PXER_TAG:
145                 break;
146             }
147             break;
148         }
149     }
150
151     /*
152      * Wrapper value confirmed.
153      */
154     switch(xer_check_tag(ptr, ch_size, elm->name)) {
155     case XCT_CLOSING:
156         ADVANCE(ch_size);
157         break;
158     case XCT_BROKEN:
159     default:
160         ASN__DECODE_FAILED;
161     }
162
163     rv.consumed += consumed_myself;
164
165     return rv;
166 }