blob: 9c4c8e63db8262923890f59ec8b033ae4d2ff313 [file] [log] [blame]
Lev Walkinf6853ce2017-08-11 00:50:27 -07001/*
2 * Copyright (c) 2017 Lev Walkin <vlm@lionet.info>. All rights reserved.
3 * Redistribution and modifications are permitted subject to BSD license.
4 */
5#include <asn_internal.h>
6#include <OPEN_TYPE.h>
7#include <constr_CHOICE.h>
8#include <per_opentype.h>
9#include <errno.h>
10
Bi-Ruei, Chiu1f87ac02017-08-20 01:25:45 +080011asn_TYPE_operation_t asn_OP_OPEN_TYPE = {
12 OPEN_TYPE_free,
13 OPEN_TYPE_print,
14 OPEN_TYPE_compare,
15 OPEN_TYPE_constraint,
16 OPEN_TYPE_decode_ber,
17 OPEN_TYPE_encode_der,
18 OPEN_TYPE_decode_xer,
19 OPEN_TYPE_encode_xer,
20 0, 0, /* No OER support, use "-gen-OER" to enable */
21 OPEN_TYPE_decode_uper,
22 OPEN_TYPE_encode_uper,
23 0, /* Use generic outmost tag fetcher */
24};
Lev Walkinf6853ce2017-08-11 00:50:27 -070025
26asn_dec_rval_t
27OPEN_TYPE_uper_get(asn_codec_ctx_t *opt_codec_ctx,
28 asn_TYPE_descriptor_t *td, void *sptr,
29 asn_TYPE_member_t *elm, asn_per_data_t *pd) {
30 asn_type_selector_result_t selected;
31 void *memb_ptr; /* Pointer to the member */
32 void **memb_ptr2; /* Pointer to that pointer */
33 asn_dec_rval_t rv;
34
35 if(!(elm->flags & ATF_OPEN_TYPE) || !elm->type_selector) {
36 ASN__DECODE_FAILED;
37 }
38
39 selected = elm->type_selector(td, sptr);
40 if(!selected.presence_index) {
41 ASN__DECODE_FAILED;
42 }
43
44 /* Fetch the pointer to this member */
45 assert(elm->flags == ATF_OPEN_TYPE);
46 if(elm->flags & ATF_POINTER) {
47 memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
48 } else {
49 memb_ptr = (char *)sptr + elm->memb_offset;
50 memb_ptr2 = &memb_ptr;
51 }
52 if(*memb_ptr2 != NULL) {
53 /* Make sure we reset the structure first before encoding */
54 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0)
55 != 0) {
56 ASN__DECODE_FAILED;
57 }
58 }
59
60 void *inner_value =
61 (char *)*memb_ptr2
62 + elm->type->elements[selected.presence_index - 1].memb_offset;
63
64 rv = uper_open_type_get(opt_codec_ctx, selected.type_descriptor, NULL,
65 &inner_value, pd);
66 switch(rv.code) {
67 case RC_OK:
68 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
69 selected.presence_index)
70 == 0) {
71 break;
72 } else {
73 rv.code = RC_FAIL;
74 }
75 /* Fall through */
76 case RC_WMORE:
77 case RC_FAIL:
78 if(*memb_ptr2) {
79 asn_CHOICE_specifics_t *specs = selected.type_descriptor->specifics;
80 if(elm->flags & ATF_POINTER) {
81 ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
82 *memb_ptr2 = NULL;
83 } else {
84 ASN_STRUCT_FREE_CONTENTS_ONLY(*selected.type_descriptor,
85 inner_value);
86 memset(*memb_ptr2, 0, specs->struct_size);
87 }
88 }
89 }
90 return rv;
91}
92
93asn_dec_rval_t
94OPEN_TYPE_oer_get(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
95 void *sptr, asn_TYPE_member_t *elm, const void *ptr,
96 size_t size) {
97 asn_type_selector_result_t selected;
98 void *memb_ptr; /* Pointer to the member */
99 void **memb_ptr2; /* Pointer to that pointer */
100 asn_dec_rval_t rv;
101 size_t ot_ret;
102
103 if(!(elm->flags & ATF_OPEN_TYPE) || !elm->type_selector) {
104 ASN__DECODE_FAILED;
105 }
106
107 selected = elm->type_selector(td, sptr);
108 if(!selected.presence_index) {
109 ASN__DECODE_FAILED;
110 }
111
112 /* Fetch the pointer to this member */
113 if(elm->flags & ATF_POINTER) {
114 memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
115 } else {
116 memb_ptr = (char *)sptr + elm->memb_offset;
117 memb_ptr2 = &memb_ptr;
118 }
119 if(*memb_ptr2 != NULL) {
120 /* Make sure we reset the structure first before encoding */
121 if(CHOICE_variant_set_presence(selected.type_descriptor, *memb_ptr2, 0)
122 != 0) {
123 ASN__DECODE_FAILED;
124 }
125 }
126
127 ot_ret = oer_open_type_get(opt_codec_ctx, selected.type_descriptor, NULL,
128 memb_ptr2, ptr, size);
129 switch(ot_ret) {
130 default:
131 if(CHOICE_variant_set_presence(selected.type_descriptor, *memb_ptr2,
132 selected.presence_index)
133 == 0) {
134 rv.code = RC_OK;
135 rv.consumed = ot_ret;
136 return rv;
137 } else {
138 /* Oh, now a full-blown failure failure */
139 }
140 /* Fall through */
141 case -1:
142 rv.code = RC_FAIL;
143 rv.consumed = 0;
144 break;
145 case 0:
146 rv.code = RC_WMORE;
147 rv.consumed = 0;
148 break;
149 }
150
151 if(*memb_ptr2) {
152 asn_CHOICE_specifics_t *specs = selected.type_descriptor->specifics;
153 if(elm->flags & ATF_POINTER) {
154 ASN_STRUCT_FREE(*selected.type_descriptor, *memb_ptr2);
155 *memb_ptr2 = NULL;
156 } else {
157 ASN_STRUCT_FREE_CONTENTS_ONLY(*selected.type_descriptor,
158 *memb_ptr2);
159 memset(*memb_ptr2, 0, specs->struct_size);
160 }
161 }
162 return rv;
163}