Moving in e2sim originally from it/test/simulators
[sim/e2-interface.git] / e2sim / ASN1c / OPEN_TYPE.c
1 /*****************************************************************************
2 #                                                                            *
3 # Copyright 2019 AT&T Intellectual Property                                  *
4 #                                                                            *
5 # Licensed under the Apache License, Version 2.0 (the "License");            *
6 # you may not use this file except in compliance with the License.           *
7 # You may obtain a copy of the License at                                    *
8 #                                                                            *
9 #      http://www.apache.org/licenses/LICENSE-2.0                            *
10 #                                                                            *
11 # Unless required by applicable law or agreed to in writing, software        *
12 # distributed under the License is distributed on an "AS IS" BASIS,          *
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
14 # See the License for the specific language governing permissions and        *
15 # limitations under the License.                                             *
16 #                                                                            *
17 ******************************************************************************/
18
19 /*
20  * Copyright (c) 2017 Lev Walkin <vlm@lionet.info>. All rights reserved.
21  * Redistribution and modifications are permitted subject to BSD license.
22  */
23 #include <asn_internal.h>
24 #include <OPEN_TYPE.h>
25 #include <constr_CHOICE.h>
26 #include <per_opentype.h>
27 #include <errno.h>
28
29 asn_TYPE_operation_t asn_OP_OPEN_TYPE = {
30         OPEN_TYPE_free,
31         OPEN_TYPE_print,
32         OPEN_TYPE_compare,
33         OPEN_TYPE_decode_ber,
34         OPEN_TYPE_encode_der,
35         OPEN_TYPE_decode_xer,
36         OPEN_TYPE_encode_xer,
37 #ifdef ASN_DISABLE_OER_SUPPORT
38         0, 0,   /* No OER support, use "-gen-OER" to enable */
39 #else
40         OPEN_TYPE_decode_oer,
41         OPEN_TYPE_encode_oer,
42 #endif
43 #ifdef ASN_DISABLE_PER_SUPPORT
44         0, 0, 0, 0,
45 #else
46         OPEN_TYPE_decode_uper,
47         OPEN_TYPE_encode_uper,
48         OPEN_TYPE_decode_aper,
49         OPEN_TYPE_encode_aper,
50 #endif
51         0,  /* Random fill is not supported for open type */
52         0       /* Use generic outmost tag fetcher */
53 };
54
55 #undef  ADVANCE
56 #define ADVANCE(num_bytes)               \
57     do {                                 \
58         size_t num = num_bytes;          \
59         ptr = ((const char *)ptr) + num; \
60         size -= num;                     \
61         consumed_myself += num;          \
62     } while(0)
63
64 asn_dec_rval_t
65 OPEN_TYPE_ber_get(const asn_codec_ctx_t *opt_codec_ctx,
66                   const asn_TYPE_descriptor_t *td, void *sptr,
67                   const asn_TYPE_member_t *elm, const void *ptr, size_t size) {
68     size_t consumed_myself = 0;
69     asn_type_selector_result_t selected;
70     void *memb_ptr;   /* Pointer to the member */
71     void **memb_ptr2; /* Pointer to that pointer */
72     void *inner_value;
73     asn_dec_rval_t rv;
74
75     if(!(elm->flags & ATF_OPEN_TYPE)) {
76         ASN__DECODE_FAILED;
77     }
78
79     if(!elm->type_selector) {
80         ASN_DEBUG("Type selector is not defined for Open Type %s->%s->%s",
81                   td->name, elm->name, elm->type->name);
82         ASN__DECODE_FAILED;
83     }
84
85     selected = elm->type_selector(td, sptr);
86     if(!selected.presence_index) {
87         ASN__DECODE_FAILED;
88     }
89
90     /* Fetch the pointer to this member */
91     if(elm->flags & ATF_POINTER) {
92         memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
93     } else {
94         memb_ptr = (char *)sptr + elm->memb_offset;
95         memb_ptr2 = &memb_ptr;
96     }
97     if(*memb_ptr2 != NULL) {
98         /* Make sure we reset the structure first before encoding */
99         if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0) != 0) {
100             ASN__DECODE_FAILED;
101         }
102     }
103
104     inner_value =
105         (char *)*memb_ptr2
106         + elm->type->elements[selected.presence_index - 1].memb_offset;
107
108     ASN_DEBUG("presence %d\n", selected.presence_index);
109
110     rv = selected.type_descriptor->op->ber_decoder(
111         opt_codec_ctx, selected.type_descriptor, &inner_value, ptr, size,
112         elm->tag_mode);
113     ADVANCE(rv.consumed);
114     rv.consumed = 0;
115     switch(rv.code) {
116     case RC_OK:
117         if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
118                                        selected.presence_index)
119            == 0) {
120             rv.code = RC_OK;
121             rv.consumed = consumed_myself;
122             return rv;
123         } else {
124             /* Oh, now a full-blown failure failure */
125         }
126         /* Fall through */
127     case RC_FAIL:
128         rv.consumed = consumed_myself;
129         /* Fall through */
130     case RC_WMORE:
131         break;
132     }
133
134     if(*memb_ptr2) {
135         if(elm->flags & ATF_POINTER) {
136             ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
137             *memb_ptr2 = NULL;
138         } else {
139             ASN_STRUCT_RESET(*selected.type_descriptor,
140                                           inner_value);
141         }
142     }
143     return rv;
144 }
145
146 asn_dec_rval_t
147 OPEN_TYPE_xer_get(const asn_codec_ctx_t *opt_codec_ctx,
148                   const asn_TYPE_descriptor_t *td, void *sptr,
149                   const asn_TYPE_member_t *elm, const void *ptr, size_t size) {
150     size_t consumed_myself = 0;
151     asn_type_selector_result_t selected;
152     void *memb_ptr;   /* Pointer to the member */
153     void **memb_ptr2; /* Pointer to that pointer */
154     void *inner_value;
155     asn_dec_rval_t rv;
156
157     int xer_context = 0;
158     ssize_t ch_size;
159     pxer_chunk_type_e ch_type;
160
161     if(!(elm->flags & ATF_OPEN_TYPE)) {
162         ASN__DECODE_FAILED;
163     }
164
165     if(!elm->type_selector) {
166         ASN_DEBUG("Type selector is not defined for Open Type %s->%s->%s",
167                   td->name, elm->name, elm->type->name);
168         ASN__DECODE_FAILED;
169     }
170
171     selected = elm->type_selector(td, sptr);
172     if(!selected.presence_index) {
173         ASN__DECODE_FAILED;
174     }
175
176     /* Fetch the pointer to this member */
177     assert(elm->flags == ATF_OPEN_TYPE);
178     if(elm->flags & ATF_POINTER) {
179         memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
180     } else {
181         memb_ptr = (char *)sptr + elm->memb_offset;
182         memb_ptr2 = &memb_ptr;
183     }
184     if(*memb_ptr2 != NULL) {
185         /* Make sure we reset the structure first before encoding */
186         if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0)
187            != 0) {
188             ASN__DECODE_FAILED;
189         }
190     }
191
192     /*
193      * Confirm wrapper.
194      */
195     for(;;) {
196         ch_size = xer_next_token(&xer_context, ptr, size, &ch_type);
197         if(ch_size < 0) {
198             ASN__DECODE_FAILED;
199         } else {
200             switch(ch_type) {
201             case PXER_WMORE:
202                 ASN__DECODE_STARVED;
203             case PXER_COMMENT:
204             case PXER_TEXT:
205                 ADVANCE(ch_size);
206                 continue;
207             case PXER_TAG:
208                 break;
209             }
210             break;
211         }
212     }
213
214     /*
215      * Wrapper value confirmed.
216      */
217     switch(xer_check_tag(ptr, ch_size, elm->name)) {
218     case XCT_OPENING:
219         ADVANCE(ch_size);
220         break;
221     case XCT_BROKEN:
222     default:
223         ASN__DECODE_FAILED;
224     }
225
226     inner_value =
227         (char *)*memb_ptr2
228         + elm->type->elements[selected.presence_index - 1].memb_offset;
229
230     rv = selected.type_descriptor->op->xer_decoder(
231         opt_codec_ctx, selected.type_descriptor, &inner_value, NULL, ptr, size);
232     ADVANCE(rv.consumed);
233     rv.consumed = 0;
234     switch(rv.code) {
235     case RC_OK:
236         if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
237                                        selected.presence_index)
238            == 0) {
239             break;
240         } else {
241             rv.code = RC_FAIL;
242         }
243         /* Fall through */
244     case RC_FAIL:
245         /* Point to a best position where failure occurred */
246         rv.consumed = consumed_myself;
247         /* Fall through */
248     case RC_WMORE:
249         /* Wrt. rv.consumed==0:
250          * In case a genuine RC_WMORE, the whole Open Type decoding
251          * will have to be restarted.
252          */
253         if(*memb_ptr2) {
254             if(elm->flags & ATF_POINTER) {
255                 ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
256                 *memb_ptr2 = NULL;
257             } else {
258                 ASN_STRUCT_RESET(*selected.type_descriptor,
259                                               inner_value);
260             }
261         }
262         return rv;
263     }
264
265     /*
266      * Finalize wrapper.
267      */
268     for(;;) {
269         ch_size = xer_next_token(&xer_context, ptr, size, &ch_type);
270         if(ch_size < 0) {
271             ASN__DECODE_FAILED;
272         } else {
273             switch(ch_type) {
274             case PXER_WMORE:
275                 ASN__DECODE_STARVED;
276             case PXER_COMMENT:
277             case PXER_TEXT:
278                 ADVANCE(ch_size);
279                 continue;
280             case PXER_TAG:
281                 break;
282             }
283             break;
284         }
285     }
286
287     /*
288      * Wrapper value confirmed.
289      */
290     switch(xer_check_tag(ptr, ch_size, elm->name)) {
291     case XCT_CLOSING:
292         ADVANCE(ch_size);
293         break;
294     case XCT_BROKEN:
295     default:
296         ASN__DECODE_FAILED;
297     }
298
299     rv.consumed += consumed_myself;
300
301     return rv;
302 }
303
304
305 #ifndef  ASN_DISABLE_PER_SUPPORT
306
307 asn_dec_rval_t
308 OPEN_TYPE_uper_get(const asn_codec_ctx_t *opt_codec_ctx,
309                    const asn_TYPE_descriptor_t *td, void *sptr,
310                    const asn_TYPE_member_t *elm, asn_per_data_t *pd) {
311     asn_type_selector_result_t selected;
312     void *memb_ptr;   /* Pointer to the member */
313     void **memb_ptr2; /* Pointer to that pointer */
314     void *inner_value;
315     asn_dec_rval_t rv;
316
317     if(!(elm->flags & ATF_OPEN_TYPE)) {
318         ASN__DECODE_FAILED;
319     }
320
321     if(!elm->type_selector) {
322         ASN_DEBUG("Type selector is not defined for Open Type %s->%s->%s",
323                   td->name, elm->name, elm->type->name);
324         ASN__DECODE_FAILED;
325     }
326
327     selected = elm->type_selector(td, sptr);
328     if(!selected.presence_index) {
329         ASN__DECODE_FAILED;
330     }
331
332     /* Fetch the pointer to this member */
333     assert(elm->flags == ATF_OPEN_TYPE);
334     if(elm->flags & ATF_POINTER) {
335         memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
336     } else {
337         memb_ptr = (char *)sptr + elm->memb_offset;
338         memb_ptr2 = &memb_ptr;
339     }
340     if(*memb_ptr2 != NULL) {
341         /* Make sure we reset the structure first before encoding */
342         if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0)
343            != 0) {
344             ASN__DECODE_FAILED;
345         }
346     }
347
348     inner_value =
349         (char *)*memb_ptr2
350         + elm->type->elements[selected.presence_index - 1].memb_offset;
351
352     rv = uper_open_type_get(opt_codec_ctx, selected.type_descriptor, NULL,
353                             &inner_value, pd);
354     switch(rv.code) {
355     case RC_OK:
356         if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
357                                        selected.presence_index)
358            == 0) {
359             break;
360         } else {
361             rv.code = RC_FAIL;
362         }
363         /* Fall through */
364     case RC_WMORE:
365     case RC_FAIL:
366         if(*memb_ptr2) {
367             if(elm->flags & ATF_POINTER) {
368                 ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
369                 *memb_ptr2 = NULL;
370             } else {
371                 ASN_STRUCT_RESET(*selected.type_descriptor,
372                                               inner_value);
373             }
374         }
375     }
376     return rv;
377 }
378
379 asn_enc_rval_t
380 OPEN_TYPE_encode_uper(const asn_TYPE_descriptor_t *td,
381                       const asn_per_constraints_t *constraints,
382                       const void *sptr, asn_per_outp_t *po) {
383     const void *memb_ptr;   /* Pointer to the member */
384     asn_TYPE_member_t *elm; /* CHOICE's element */
385     asn_enc_rval_t er = {0,0,0};
386     unsigned present;
387
388     (void)constraints;
389
390     present = CHOICE_variant_get_presence(td, sptr);
391     if(present == 0 || present > td->elements_count) {
392         ASN__ENCODE_FAILED;
393     } else {
394         present--;
395     }
396
397     ASN_DEBUG("Encoding %s OPEN TYPE element %d", td->name, present);
398
399     elm = &td->elements[present];
400     if(elm->flags & ATF_POINTER) {
401         /* Member is a pointer to another structure */
402         memb_ptr =
403             *(const void *const *)((const char *)sptr + elm->memb_offset);
404         if(!memb_ptr) ASN__ENCODE_FAILED;
405     } else {
406         memb_ptr = (const char *)sptr + elm->memb_offset;
407     }
408
409     if(uper_open_type_put(elm->type, NULL, memb_ptr, po) < 0) {
410         ASN__ENCODE_FAILED;
411     }
412
413     er.encoded = 0;
414     ASN__ENCODED_OK(er);
415 }
416
417 asn_dec_rval_t
418 OPEN_TYPE_aper_get(const asn_codec_ctx_t *opt_codec_ctx,
419                    const asn_TYPE_descriptor_t *td, void *sptr,
420                    const asn_TYPE_member_t *elm, asn_per_data_t *pd) {
421     asn_type_selector_result_t selected;
422     void *memb_ptr;   /* Pointer to the member */
423     void **memb_ptr2; /* Pointer to that pointer */
424     void *inner_value;
425     asn_dec_rval_t rv;
426
427     if(!(elm->flags & ATF_OPEN_TYPE)) {
428         ASN__DECODE_FAILED;
429     }
430
431     if(!elm->type_selector) {
432         ASN_DEBUG("Type selector is not defined for Open Type %s->%s->%s",
433                   td->name, elm->name, elm->type->name);
434         ASN__DECODE_FAILED;
435     }
436
437     selected = elm->type_selector(td, sptr);
438     if(!selected.presence_index) {
439         ASN__DECODE_FAILED;
440     }
441
442     /* Fetch the pointer to this member */
443     assert(elm->flags == ATF_OPEN_TYPE);
444     if(elm->flags & ATF_POINTER) {
445         memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
446     } else {
447         memb_ptr = (char *)sptr + elm->memb_offset;
448         memb_ptr2 = &memb_ptr;
449     }
450     if(*memb_ptr2 != NULL) {
451         /* Make sure we reset the structure first before encoding */
452         if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0)
453            != 0) {
454             ASN__DECODE_FAILED;
455         }
456     }
457
458     inner_value =
459         (char *)*memb_ptr2
460         + elm->type->elements[selected.presence_index - 1].memb_offset;
461
462     rv = aper_open_type_get(opt_codec_ctx, selected.type_descriptor, NULL,
463                             &inner_value, pd);
464     switch(rv.code) {
465     case RC_OK:
466         if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
467                                        selected.presence_index)
468            == 0) {
469             break;
470         } else {
471             rv.code = RC_FAIL;
472         }
473         /* Fall through */
474     case RC_WMORE:
475     case RC_FAIL:
476         if(*memb_ptr2) {
477             if(elm->flags & ATF_POINTER) {
478                 ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
479                 *memb_ptr2 = NULL;
480             } else {
481                 ASN_STRUCT_RESET(*selected.type_descriptor,
482                                               inner_value);
483             }
484         }
485     }
486     return rv;
487 }
488
489 asn_enc_rval_t
490 OPEN_TYPE_encode_aper(const asn_TYPE_descriptor_t *td,
491                       const asn_per_constraints_t *constraints,
492                       const void *sptr, asn_per_outp_t *po) {
493     const void *memb_ptr;   /* Pointer to the member */
494     asn_TYPE_member_t *elm; /* CHOICE's element */
495     asn_enc_rval_t er = {0,0,0};
496     unsigned present;
497
498     (void)constraints;
499
500     present = CHOICE_variant_get_presence(td, sptr);
501     if(present == 0 || present > td->elements_count) {
502         ASN__ENCODE_FAILED;
503     } else {
504         present--;
505     }
506
507     ASN_DEBUG("Encoding %s OPEN TYPE element %d", td->name, present);
508
509     elm = &td->elements[present];
510     if(elm->flags & ATF_POINTER) {
511         /* Member is a pointer to another structure */
512         memb_ptr =
513             *(const void *const *)((const char *)sptr + elm->memb_offset);
514         if(!memb_ptr) ASN__ENCODE_FAILED;
515     } else {
516         memb_ptr = (const char *)sptr + elm->memb_offset;
517     }
518
519     if(aper_open_type_put(elm->type, NULL, memb_ptr, po) < 0) {
520         ASN__ENCODE_FAILED;
521     }
522
523     er.encoded = 0;
524     ASN__ENCODED_OK(er);
525 }
526
527 #endif  /* ASN_DISABLE_PER_SUPPORT */