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