2 * Copyright (c) 2017 Lev Walkin <vlm@lionet.info>. All rights reserved.
3 * Redistribution and modifications are permitted subject to BSD license.
5 #include <asn_internal.h>
7 #include <constr_CHOICE.h>
8 #include <per_opentype.h>
11 asn_TYPE_operation_t asn_OP_OPEN_TYPE = {
19 #ifdef ASN_DISABLE_OER_SUPPORT
20 0, 0, /* No OER support, use "-gen-OER" to enable */
25 #ifdef ASN_DISABLE_PER_SUPPORT
28 OPEN_TYPE_decode_uper,
29 OPEN_TYPE_encode_uper,
30 OPEN_TYPE_decode_aper,
31 OPEN_TYPE_encode_aper,
33 0, /* Random fill is not supported for open type */
34 0 /* Use generic outmost tag fetcher */
38 #define ADVANCE(num_bytes) \
40 size_t num = num_bytes; \
41 ptr = ((const char *)ptr) + num; \
43 consumed_myself += num; \
47 OPEN_TYPE_ber_get(const asn_codec_ctx_t *opt_codec_ctx,
48 const asn_TYPE_descriptor_t *td, void *sptr,
49 const asn_TYPE_member_t *elm, const void *ptr, size_t size) {
50 size_t consumed_myself = 0;
51 asn_type_selector_result_t selected;
52 void *memb_ptr; /* Pointer to the member */
53 void **memb_ptr2; /* Pointer to that pointer */
57 if(!(elm->flags & ATF_OPEN_TYPE)) {
61 if(!elm->type_selector) {
62 ASN_DEBUG("Type selector is not defined for Open Type %s->%s->%s",
63 td->name, elm->name, elm->type->name);
67 selected = elm->type_selector(td, sptr);
68 if(!selected.presence_index) {
72 /* Fetch the pointer to this member */
73 if(elm->flags & ATF_POINTER) {
74 memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
76 memb_ptr = (char *)sptr + elm->memb_offset;
77 memb_ptr2 = &memb_ptr;
79 if(*memb_ptr2 != NULL) {
80 /* Make sure we reset the structure first before encoding */
81 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0) != 0) {
88 + elm->type->elements[selected.presence_index - 1].memb_offset;
90 ASN_DEBUG("presence %d\n", selected.presence_index);
92 rv = selected.type_descriptor->op->ber_decoder(
93 opt_codec_ctx, selected.type_descriptor, &inner_value, ptr, size,
99 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
100 selected.presence_index)
103 rv.consumed = consumed_myself;
106 /* Oh, now a full-blown failure failure */
110 rv.consumed = consumed_myself;
117 if(elm->flags & ATF_POINTER) {
118 ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
121 ASN_STRUCT_RESET(*selected.type_descriptor,
129 OPEN_TYPE_xer_get(const asn_codec_ctx_t *opt_codec_ctx,
130 const asn_TYPE_descriptor_t *td, void *sptr,
131 const asn_TYPE_member_t *elm, const void *ptr, size_t size) {
132 size_t consumed_myself = 0;
133 asn_type_selector_result_t selected;
134 void *memb_ptr; /* Pointer to the member */
135 void **memb_ptr2; /* Pointer to that pointer */
141 pxer_chunk_type_e ch_type;
143 if(!(elm->flags & ATF_OPEN_TYPE)) {
147 if(!elm->type_selector) {
148 ASN_DEBUG("Type selector is not defined for Open Type %s->%s->%s",
149 td->name, elm->name, elm->type->name);
153 selected = elm->type_selector(td, sptr);
154 if(!selected.presence_index) {
158 /* Fetch the pointer to this member */
159 assert(elm->flags == ATF_OPEN_TYPE);
160 if(elm->flags & ATF_POINTER) {
161 memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
163 memb_ptr = (char *)sptr + elm->memb_offset;
164 memb_ptr2 = &memb_ptr;
166 if(*memb_ptr2 != NULL) {
167 /* Make sure we reset the structure first before encoding */
168 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0)
178 ch_size = xer_next_token(&xer_context, ptr, size, &ch_type);
197 * Wrapper value confirmed.
199 switch(xer_check_tag(ptr, ch_size, elm->name)) {
210 + elm->type->elements[selected.presence_index - 1].memb_offset;
212 rv = selected.type_descriptor->op->xer_decoder(
213 opt_codec_ctx, selected.type_descriptor, &inner_value, NULL, ptr, size);
214 ADVANCE(rv.consumed);
218 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
219 selected.presence_index)
227 /* Point to a best position where failure occurred */
228 rv.consumed = consumed_myself;
231 /* Wrt. rv.consumed==0:
232 * In case a genuine RC_WMORE, the whole Open Type decoding
233 * will have to be restarted.
236 if(elm->flags & ATF_POINTER) {
237 ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
240 ASN_STRUCT_RESET(*selected.type_descriptor,
251 ch_size = xer_next_token(&xer_context, ptr, size, &ch_type);
270 * Wrapper value confirmed.
272 switch(xer_check_tag(ptr, ch_size, elm->name)) {
281 rv.consumed += consumed_myself;
287 #ifndef ASN_DISABLE_PER_SUPPORT
290 OPEN_TYPE_uper_get(const asn_codec_ctx_t *opt_codec_ctx,
291 const asn_TYPE_descriptor_t *td, void *sptr,
292 const asn_TYPE_member_t *elm, asn_per_data_t *pd) {
293 asn_type_selector_result_t selected;
294 void *memb_ptr; /* Pointer to the member */
295 void **memb_ptr2; /* Pointer to that pointer */
299 if(!(elm->flags & ATF_OPEN_TYPE)) {
303 if(!elm->type_selector) {
304 ASN_DEBUG("Type selector is not defined for Open Type %s->%s->%s",
305 td->name, elm->name, elm->type->name);
309 selected = elm->type_selector(td, sptr);
310 if(!selected.presence_index) {
314 /* Fetch the pointer to this member */
315 assert(elm->flags == ATF_OPEN_TYPE);
316 if(elm->flags & ATF_POINTER) {
317 memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
319 memb_ptr = (char *)sptr + elm->memb_offset;
320 memb_ptr2 = &memb_ptr;
322 if(*memb_ptr2 != NULL) {
323 /* Make sure we reset the structure first before encoding */
324 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0)
332 + elm->type->elements[selected.presence_index - 1].memb_offset;
334 rv = uper_open_type_get(opt_codec_ctx, selected.type_descriptor, NULL,
338 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
339 selected.presence_index)
349 if(elm->flags & ATF_POINTER) {
350 ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
353 ASN_STRUCT_RESET(*selected.type_descriptor,
362 OPEN_TYPE_encode_uper(const asn_TYPE_descriptor_t *td,
363 const asn_per_constraints_t *constraints,
364 const void *sptr, asn_per_outp_t *po) {
365 const void *memb_ptr; /* Pointer to the member */
366 asn_TYPE_member_t *elm; /* CHOICE's element */
367 asn_enc_rval_t er = {0,0,0};
372 present = CHOICE_variant_get_presence(td, sptr);
373 if(present == 0 || present > td->elements_count) {
379 ASN_DEBUG("Encoding %s OPEN TYPE element %d", td->name, present);
381 elm = &td->elements[present];
382 if(elm->flags & ATF_POINTER) {
383 /* Member is a pointer to another structure */
385 *(const void *const *)((const char *)sptr + elm->memb_offset);
386 if(!memb_ptr) ASN__ENCODE_FAILED;
388 memb_ptr = (const char *)sptr + elm->memb_offset;
391 if(uper_open_type_put(elm->type, NULL, memb_ptr, po) < 0) {
400 OPEN_TYPE_aper_get(const asn_codec_ctx_t *opt_codec_ctx,
401 const asn_TYPE_descriptor_t *td, void *sptr,
402 const asn_TYPE_member_t *elm, asn_per_data_t *pd) {
403 asn_type_selector_result_t selected;
404 void *memb_ptr; /* Pointer to the member */
405 void **memb_ptr2; /* Pointer to that pointer */
409 if(!(elm->flags & ATF_OPEN_TYPE)) {
413 if(!elm->type_selector) {
414 ASN_DEBUG("Type selector is not defined for Open Type %s->%s->%s",
415 td->name, elm->name, elm->type->name);
419 selected = elm->type_selector(td, sptr);
420 if(!selected.presence_index) {
424 /* Fetch the pointer to this member */
425 assert(elm->flags == ATF_OPEN_TYPE);
426 if(elm->flags & ATF_POINTER) {
427 memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
429 memb_ptr = (char *)sptr + elm->memb_offset;
430 memb_ptr2 = &memb_ptr;
432 if(*memb_ptr2 != NULL) {
433 /* Make sure we reset the structure first before encoding */
434 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0)
442 + elm->type->elements[selected.presence_index - 1].memb_offset;
444 rv = aper_open_type_get(opt_codec_ctx, selected.type_descriptor, NULL,
448 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
449 selected.presence_index)
459 if(elm->flags & ATF_POINTER) {
460 ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
463 ASN_STRUCT_RESET(*selected.type_descriptor,
472 OPEN_TYPE_encode_aper(const asn_TYPE_descriptor_t *td,
473 const asn_per_constraints_t *constraints,
474 const void *sptr, asn_per_outp_t *po) {
475 const void *memb_ptr; /* Pointer to the member */
476 asn_TYPE_member_t *elm; /* CHOICE's element */
477 asn_enc_rval_t er = {0,0,0};
482 present = CHOICE_variant_get_presence(td, sptr);
483 if(present == 0 || present > td->elements_count) {
489 ASN_DEBUG("Encoding %s OPEN TYPE element %d", td->name, present);
491 elm = &td->elements[present];
492 if(elm->flags & ATF_POINTER) {
493 /* Member is a pointer to another structure */
495 *(const void *const *)((const char *)sptr + elm->memb_offset);
496 if(!memb_ptr) ASN__ENCODE_FAILED;
498 memb_ptr = (const char *)sptr + elm->memb_offset;
501 if(aper_open_type_put(elm->type, NULL, memb_ptr, po) < 0) {
509 #endif /* ASN_DISABLE_PER_SUPPORT */