blob: e490504fbb04f49016a263c860d80d71a6329dd2 [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,
Bi-Ruei, Chiu1f87ac02017-08-20 01:25:45 +080015 OPEN_TYPE_decode_ber,
16 OPEN_TYPE_encode_der,
17 OPEN_TYPE_decode_xer,
18 OPEN_TYPE_encode_xer,
19 0, 0, /* No OER support, use "-gen-OER" to enable */
Lev Walkina4db2af2017-08-27 01:27:07 -070020#ifdef ASN_DISABLE_PER_SUPPORT
21 0, 0,
22#else
Bi-Ruei, Chiu1f87ac02017-08-20 01:25:45 +080023 OPEN_TYPE_decode_uper,
24 OPEN_TYPE_encode_uper,
Lev Walkina4db2af2017-08-27 01:27:07 -070025#endif
Lev Walkina5972be2017-09-29 23:15:58 -070026 0, /* Random fill is not supported for open type */
Bi-Ruei, Chiu1f87ac02017-08-20 01:25:45 +080027 0, /* Use generic outmost tag fetcher */
28};
Lev Walkinf6853ce2017-08-11 00:50:27 -070029
Lev Walkinc10d30a2017-08-27 00:38:21 -070030#undef ADVANCE
31#define ADVANCE(num_bytes) \
Lev Walkinf59dac92017-08-26 21:26:51 -070032 do { \
33 size_t num = num_bytes; \
34 ptr = ((const char *)ptr) + num; \
35 size -= num; \
36 consumed_myself += num; \
37 } while(0)
38
39asn_dec_rval_t
Lev Walkinafbf2a92017-09-12 23:30:27 -070040OPEN_TYPE_ber_get(const asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
Lev Walkinc10d30a2017-08-27 00:38:21 -070041 void *sptr, asn_TYPE_member_t *elm, const void *ptr,
42 size_t size) {
43 size_t consumed_myself = 0;
44 asn_type_selector_result_t selected;
45 void *memb_ptr; /* Pointer to the member */
46 void **memb_ptr2; /* Pointer to that pointer */
47 void *inner_value;
48 asn_dec_rval_t rv;
49
Lev Walkin75b6fe42017-08-27 01:03:22 -070050 if(!(elm->flags & ATF_OPEN_TYPE)) {
51 ASN__DECODE_FAILED;
52 }
53
54 if(!elm->type_selector) {
55 ASN_DEBUG("Type selector is not defined for Open Type %s->%s->%s",
56 td->name, elm->name, elm->type->name);
Lev Walkinc10d30a2017-08-27 00:38:21 -070057 ASN__DECODE_FAILED;
58 }
59
60 selected = elm->type_selector(td, sptr);
61 if(!selected.presence_index) {
62 ASN__DECODE_FAILED;
63 }
64
65 /* Fetch the pointer to this member */
66 if(elm->flags & ATF_POINTER) {
67 memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
68 } else {
69 memb_ptr = (char *)sptr + elm->memb_offset;
70 memb_ptr2 = &memb_ptr;
71 }
72 if(*memb_ptr2 != NULL) {
73 /* Make sure we reset the structure first before encoding */
74 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0) != 0) {
75 ASN__DECODE_FAILED;
76 }
77 }
78
79 inner_value =
80 (char *)*memb_ptr2
81 + elm->type->elements[selected.presence_index - 1].memb_offset;
82
83 ASN_DEBUG("presence %d\n", selected.presence_index);
84
85 rv = selected.type_descriptor->op->ber_decoder(
86 opt_codec_ctx, selected.type_descriptor, &inner_value, ptr, size,
87 elm->tag_mode);
88 ADVANCE(rv.consumed);
89 rv.consumed = 0;
90 switch(rv.code) {
91 case RC_OK:
92 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
93 selected.presence_index)
94 == 0) {
95 rv.code = RC_OK;
96 rv.consumed = consumed_myself;
97 return rv;
98 } else {
99 /* Oh, now a full-blown failure failure */
100 }
101 /* Fall through */
102 case RC_FAIL:
103 rv.consumed = consumed_myself;
104 /* Fall through */
105 case RC_WMORE:
106 break;
107 }
108
109 if(*memb_ptr2) {
110 asn_CHOICE_specifics_t *specs = selected.type_descriptor->specifics;
111 if(elm->flags & ATF_POINTER) {
112 ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
113 *memb_ptr2 = NULL;
114 } else {
115 ASN_STRUCT_FREE_CONTENTS_ONLY(*selected.type_descriptor,
116 inner_value);
117 memset(*memb_ptr2, 0, specs->struct_size);
118 }
119 }
120 return rv;
121}
122
123asn_dec_rval_t
Lev Walkinafbf2a92017-09-12 23:30:27 -0700124OPEN_TYPE_xer_get(const asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
Lev Walkinf59dac92017-08-26 21:26:51 -0700125 void *sptr, asn_TYPE_member_t *elm, const void *ptr,
126 size_t size) {
127 size_t consumed_myself = 0;
128 asn_type_selector_result_t selected;
129 void *memb_ptr; /* Pointer to the member */
130 void **memb_ptr2; /* Pointer to that pointer */
131 void *inner_value;
Lev Walkinf59dac92017-08-26 21:26:51 -0700132 asn_dec_rval_t rv;
133
134 int xer_context = 0;
135 ssize_t ch_size;
136 pxer_chunk_type_e ch_type;
137
Lev Walkin75b6fe42017-08-27 01:03:22 -0700138 if(!(elm->flags & ATF_OPEN_TYPE)) {
139 ASN__DECODE_FAILED;
140 }
141
142 if(!elm->type_selector) {
143 ASN_DEBUG("Type selector is not defined for Open Type %s->%s->%s",
144 td->name, elm->name, elm->type->name);
Lev Walkinf59dac92017-08-26 21:26:51 -0700145 ASN__DECODE_FAILED;
146 }
147
148 selected = elm->type_selector(td, sptr);
149 if(!selected.presence_index) {
150 ASN__DECODE_FAILED;
151 }
152
153 /* Fetch the pointer to this member */
154 assert(elm->flags == ATF_OPEN_TYPE);
155 if(elm->flags & ATF_POINTER) {
156 memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
157 } else {
158 memb_ptr = (char *)sptr + elm->memb_offset;
159 memb_ptr2 = &memb_ptr;
160 }
161 if(*memb_ptr2 != NULL) {
162 /* Make sure we reset the structure first before encoding */
163 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0)
164 != 0) {
165 ASN__DECODE_FAILED;
166 }
167 }
168
169 /*
170 * Confirm wrapper.
171 */
172 for(;;) {
173 ch_size = xer_next_token(&xer_context, ptr, size, &ch_type);
Lev Walkin4ccce3d2017-08-27 00:41:58 -0700174 if(ch_size < 0) {
Lev Walkinf59dac92017-08-26 21:26:51 -0700175 ASN__DECODE_FAILED;
176 } else {
177 switch(ch_type) {
178 case PXER_WMORE:
179 ASN__DECODE_STARVED;
180 case PXER_COMMENT:
181 case PXER_TEXT:
Lev Walkinc10d30a2017-08-27 00:38:21 -0700182 ADVANCE(ch_size);
Lev Walkinf59dac92017-08-26 21:26:51 -0700183 continue;
184 case PXER_TAG:
185 break;
186 }
187 break;
188 }
189 }
190
191 /*
192 * Wrapper value confirmed.
193 */
194 switch(xer_check_tag(ptr, ch_size, elm->name)) {
195 case XCT_OPENING:
Lev Walkinc10d30a2017-08-27 00:38:21 -0700196 ADVANCE(ch_size);
Lev Walkinf59dac92017-08-26 21:26:51 -0700197 break;
198 case XCT_BROKEN:
199 default:
200 ASN__DECODE_FAILED;
201 }
202
203 inner_value =
204 (char *)*memb_ptr2
205 + elm->type->elements[selected.presence_index - 1].memb_offset;
206
207 rv = selected.type_descriptor->op->xer_decoder(
208 opt_codec_ctx, selected.type_descriptor, &inner_value, NULL, ptr, size);
Lev Walkinc10d30a2017-08-27 00:38:21 -0700209 ADVANCE(rv.consumed);
Lev Walkinf59dac92017-08-26 21:26:51 -0700210 rv.consumed = 0;
211 switch(rv.code) {
212 case RC_OK:
213 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
214 selected.presence_index)
215 == 0) {
216 break;
217 } else {
218 rv.code = RC_FAIL;
219 }
220 /* Fall through */
221 case RC_FAIL:
222 /* Point to a best position where failure occurred */
223 rv.consumed = consumed_myself;
224 /* Fall through */
225 case RC_WMORE:
226 /* Wrt. rv.consumed==0:
227 * In case a genuine RC_WMORE, the whole Open Type decoding
228 * will have to be restarted.
229 */
230 if(*memb_ptr2) {
231 asn_CHOICE_specifics_t *specs = selected.type_descriptor->specifics;
232 if(elm->flags & ATF_POINTER) {
233 ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
234 *memb_ptr2 = NULL;
235 } else {
236 ASN_STRUCT_FREE_CONTENTS_ONLY(*selected.type_descriptor,
237 inner_value);
238 memset(*memb_ptr2, 0, specs->struct_size);
239 }
240 }
241 return rv;
242 }
243
244 /*
245 * Finalize wrapper.
246 */
247 for(;;) {
248 ch_size = xer_next_token(&xer_context, ptr, size, &ch_type);
Lev Walkin4ccce3d2017-08-27 00:41:58 -0700249 if(ch_size < 0) {
Lev Walkinf59dac92017-08-26 21:26:51 -0700250 ASN__DECODE_FAILED;
251 } else {
252 switch(ch_type) {
253 case PXER_WMORE:
254 ASN__DECODE_STARVED;
255 case PXER_COMMENT:
256 case PXER_TEXT:
Lev Walkinc10d30a2017-08-27 00:38:21 -0700257 ADVANCE(ch_size);
Lev Walkinf59dac92017-08-26 21:26:51 -0700258 continue;
259 case PXER_TAG:
260 break;
261 }
262 break;
263 }
264 }
265
266 /*
267 * Wrapper value confirmed.
268 */
269 switch(xer_check_tag(ptr, ch_size, elm->name)) {
270 case XCT_CLOSING:
Lev Walkinc10d30a2017-08-27 00:38:21 -0700271 ADVANCE(ch_size);
Lev Walkinf59dac92017-08-26 21:26:51 -0700272 break;
273 case XCT_BROKEN:
274 default:
275 ASN__DECODE_FAILED;
276 }
277
278 rv.consumed += consumed_myself;
279
280 return rv;
281}
282
283
Lev Walkin69033802017-08-25 12:15:58 -0700284#ifndef ASN_DISABLE_PER_SUPPORT
285
Lev Walkinf6853ce2017-08-11 00:50:27 -0700286asn_dec_rval_t
Lev Walkinafbf2a92017-09-12 23:30:27 -0700287OPEN_TYPE_uper_get(const asn_codec_ctx_t *opt_codec_ctx,
Lev Walkinf6853ce2017-08-11 00:50:27 -0700288 asn_TYPE_descriptor_t *td, void *sptr,
289 asn_TYPE_member_t *elm, asn_per_data_t *pd) {
290 asn_type_selector_result_t selected;
291 void *memb_ptr; /* Pointer to the member */
292 void **memb_ptr2; /* Pointer to that pointer */
Lev Walkinf59dac92017-08-26 21:26:51 -0700293 void *inner_value;
Lev Walkinf6853ce2017-08-11 00:50:27 -0700294 asn_dec_rval_t rv;
295
Lev Walkin75b6fe42017-08-27 01:03:22 -0700296 if(!(elm->flags & ATF_OPEN_TYPE)) {
297 ASN__DECODE_FAILED;
298 }
299
300 if(!elm->type_selector) {
301 ASN_DEBUG("Type selector is not defined for Open Type %s->%s->%s",
302 td->name, elm->name, elm->type->name);
Lev Walkinf6853ce2017-08-11 00:50:27 -0700303 ASN__DECODE_FAILED;
304 }
305
306 selected = elm->type_selector(td, sptr);
307 if(!selected.presence_index) {
308 ASN__DECODE_FAILED;
309 }
310
311 /* Fetch the pointer to this member */
312 assert(elm->flags == ATF_OPEN_TYPE);
313 if(elm->flags & ATF_POINTER) {
314 memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
315 } else {
316 memb_ptr = (char *)sptr + elm->memb_offset;
317 memb_ptr2 = &memb_ptr;
318 }
319 if(*memb_ptr2 != NULL) {
320 /* Make sure we reset the structure first before encoding */
321 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0)
322 != 0) {
323 ASN__DECODE_FAILED;
324 }
325 }
326
Lev Walkinf59dac92017-08-26 21:26:51 -0700327 inner_value =
Lev Walkinf6853ce2017-08-11 00:50:27 -0700328 (char *)*memb_ptr2
329 + elm->type->elements[selected.presence_index - 1].memb_offset;
330
331 rv = uper_open_type_get(opt_codec_ctx, selected.type_descriptor, NULL,
332 &inner_value, pd);
333 switch(rv.code) {
334 case RC_OK:
335 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
336 selected.presence_index)
337 == 0) {
338 break;
339 } else {
340 rv.code = RC_FAIL;
341 }
342 /* Fall through */
343 case RC_WMORE:
344 case RC_FAIL:
345 if(*memb_ptr2) {
346 asn_CHOICE_specifics_t *specs = selected.type_descriptor->specifics;
347 if(elm->flags & ATF_POINTER) {
348 ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
349 *memb_ptr2 = NULL;
350 } else {
351 ASN_STRUCT_FREE_CONTENTS_ONLY(*selected.type_descriptor,
352 inner_value);
353 memset(*memb_ptr2, 0, specs->struct_size);
354 }
355 }
356 }
357 return rv;
358}
359
Lev Walkin35ace192017-08-26 23:33:14 -0700360asn_enc_rval_t
361OPEN_TYPE_encode_uper(asn_TYPE_descriptor_t *td,
362 const asn_per_constraints_t *constraints, void *sptr,
363 asn_per_outp_t *po) {
Lev Walkin35ace192017-08-26 23:33:14 -0700364 void *memb_ptr; /* Pointer to the member */
365 asn_TYPE_member_t *elm; /* CHOICE's element */
366 asn_enc_rval_t er;
367 unsigned present;
368
369 (void)constraints;
370
371 present = CHOICE_variant_get_presence(td, sptr);
372 if(present == 0 || present > td->elements_count) {
373 ASN__ENCODE_FAILED;
374 } else {
375 present--;
376 }
377
378 ASN_DEBUG("Encoding %s OPEN TYPE element %d", td->name, present);
379
380 elm = &td->elements[present];
381 if(elm->flags & ATF_POINTER) {
382 /* Member is a pointer to another structure */
383 memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
384 if(!memb_ptr) ASN__ENCODE_FAILED;
385 } else {
386 memb_ptr = (char *)sptr + elm->memb_offset;
387 }
388
389 if(uper_open_type_put(elm->type, NULL, memb_ptr, po) < 0) {
390 ASN__ENCODE_FAILED;
391 }
392
393 er.encoded = 0;
394 ASN__ENCODED_OK(er);
395}
396
397
Lev Walkin69033802017-08-25 12:15:58 -0700398#endif /* ASN_DISABLE_PER_SUPPORT */