2 * Copyright (c) 2017 Lev Walkin <vlm@lionet.info>. All rights reserved.
\r
3 * Redistribution and modifications are permitted subject to BSD license.
\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
11 asn_TYPE_operation_t asn_OP_OPEN_TYPE = {
\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
22 OPEN_TYPE_decode_oer,
\r
23 OPEN_TYPE_encode_oer,
\r
25 #ifdef ASN_DISABLE_PER_SUPPORT
\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
33 0, /* Random fill is not supported for open type */
\r
34 0 /* Use generic outmost tag fetcher */
\r
38 #define ADVANCE(num_bytes) \
\r
40 size_t num = num_bytes; \
\r
41 ptr = ((const char *)ptr) + num; \
\r
43 consumed_myself += num; \
\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
57 if(!(elm->flags & ATF_OPEN_TYPE)) {
\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
67 selected = elm->type_selector(td, sptr);
\r
68 if(!selected.presence_index) {
\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
76 memb_ptr = (char *)sptr + elm->memb_offset;
\r
77 memb_ptr2 = &memb_ptr;
\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
88 + elm->type->elements[selected.presence_index - 1].memb_offset;
\r
90 ASN_DEBUG("presence %d\n", selected.presence_index);
\r
92 rv = selected.type_descriptor->op->ber_decoder(
\r
93 opt_codec_ctx, selected.type_descriptor, &inner_value, ptr, size,
\r
95 ADVANCE(rv.consumed);
\r
99 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
\r
100 selected.presence_index)
\r
103 rv.consumed = consumed_myself;
\r
106 /* Oh, now a full-blown failure failure */
\r
110 rv.consumed = consumed_myself;
\r
117 if(elm->flags & ATF_POINTER) {
\r
118 ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
\r
121 ASN_STRUCT_RESET(*selected.type_descriptor,
\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
139 int xer_context = 0;
\r
141 pxer_chunk_type_e ch_type;
\r
143 if(!(elm->flags & ATF_OPEN_TYPE)) {
\r
144 ASN__DECODE_FAILED;
\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
153 selected = elm->type_selector(td, sptr);
\r
154 if(!selected.presence_index) {
\r
155 ASN__DECODE_FAILED;
\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
163 memb_ptr = (char *)sptr + elm->memb_offset;
\r
164 memb_ptr2 = &memb_ptr;
\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
170 ASN__DECODE_FAILED;
\r
178 ch_size = xer_next_token(&xer_context, ptr, size, &ch_type);
\r
180 ASN__DECODE_FAILED;
\r
184 ASN__DECODE_STARVED;
\r
197 * Wrapper value confirmed.
\r
199 switch(xer_check_tag(ptr, ch_size, elm->name)) {
\r
205 ASN__DECODE_FAILED;
\r
210 + elm->type->elements[selected.presence_index - 1].memb_offset;
\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
218 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
\r
219 selected.presence_index)
\r
227 /* Point to a best position where failure occurred */
\r
228 rv.consumed = consumed_myself;
\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
236 if(elm->flags & ATF_POINTER) {
\r
237 ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
\r
240 ASN_STRUCT_RESET(*selected.type_descriptor,
\r
248 * Finalize wrapper.
\r
251 ch_size = xer_next_token(&xer_context, ptr, size, &ch_type);
\r
253 ASN__DECODE_FAILED;
\r
257 ASN__DECODE_STARVED;
\r
270 * Wrapper value confirmed.
\r
272 switch(xer_check_tag(ptr, ch_size, elm->name)) {
\r
278 ASN__DECODE_FAILED;
\r
281 rv.consumed += consumed_myself;
\r
287 #ifndef ASN_DISABLE_PER_SUPPORT
\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
299 if(!(elm->flags & ATF_OPEN_TYPE)) {
\r
300 ASN__DECODE_FAILED;
\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
309 selected = elm->type_selector(td, sptr);
\r
310 if(!selected.presence_index) {
\r
311 ASN__DECODE_FAILED;
\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
319 memb_ptr = (char *)sptr + elm->memb_offset;
\r
320 memb_ptr2 = &memb_ptr;
\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
326 ASN__DECODE_FAILED;
\r
332 + elm->type->elements[selected.presence_index - 1].memb_offset;
\r
334 rv = uper_open_type_get(opt_codec_ctx, selected.type_descriptor, NULL,
\r
338 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
\r
339 selected.presence_index)
\r
349 if(elm->flags & ATF_POINTER) {
\r
350 ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
\r
353 ASN_STRUCT_RESET(*selected.type_descriptor,
\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
372 present = CHOICE_variant_get_presence(td, sptr);
\r
373 if(present == 0 || present > td->elements_count) {
\r
374 ASN__ENCODE_FAILED;
\r
379 ASN_DEBUG("Encoding %s OPEN TYPE element %d", td->name, present);
\r
381 elm = &td->elements[present];
\r
382 if(elm->flags & ATF_POINTER) {
\r
383 /* Member is a pointer to another structure */
\r
385 *(const void *const *)((const char *)sptr + elm->memb_offset);
\r
386 if(!memb_ptr) ASN__ENCODE_FAILED;
\r
388 memb_ptr = (const char *)sptr + elm->memb_offset;
\r
391 if(uper_open_type_put(elm->type, NULL, memb_ptr, po) < 0) {
\r
392 ASN__ENCODE_FAILED;
\r
396 ASN__ENCODED_OK(er);
\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
409 if(!(elm->flags & ATF_OPEN_TYPE)) {
\r
410 ASN__DECODE_FAILED;
\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
419 selected = elm->type_selector(td, sptr);
\r
420 if(!selected.presence_index) {
\r
421 ASN__DECODE_FAILED;
\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
429 memb_ptr = (char *)sptr + elm->memb_offset;
\r
430 memb_ptr2 = &memb_ptr;
\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
436 ASN__DECODE_FAILED;
\r
442 + elm->type->elements[selected.presence_index - 1].memb_offset;
\r
444 rv = aper_open_type_get(opt_codec_ctx, selected.type_descriptor, NULL,
\r
448 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
\r
449 selected.presence_index)
\r
459 if(elm->flags & ATF_POINTER) {
\r
460 ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
\r
463 ASN_STRUCT_RESET(*selected.type_descriptor,
\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
482 present = CHOICE_variant_get_presence(td, sptr);
\r
483 if(present == 0 || present > td->elements_count) {
\r
484 ASN__ENCODE_FAILED;
\r
489 ASN_DEBUG("Encoding %s OPEN TYPE element %d", td->name, present);
\r
491 elm = &td->elements[present];
\r
492 if(elm->flags & ATF_POINTER) {
\r
493 /* Member is a pointer to another structure */
\r
495 *(const void *const *)((const char *)sptr + elm->memb_offset);
\r
496 if(!memb_ptr) ASN__ENCODE_FAILED;
\r
498 memb_ptr = (const char *)sptr + elm->memb_offset;
\r
501 if(aper_open_type_put(elm->type, NULL, memb_ptr, po) < 0) {
\r
502 ASN__ENCODE_FAILED;
\r
506 ASN__ENCODED_OK(er);
\r
509 #endif /* ASN_DISABLE_PER_SUPPORT */
\r