1 /*****************************************************************************
3 # Copyright 2019 AT&T Intellectual Property *
5 # Licensed under the Apache License, Version 2.0 (the "License"); *
6 # you may not use this file except in compliance with the License. *
7 # You may obtain a copy of the License at *
9 # http://www.apache.org/licenses/LICENSE-2.0 *
11 # Unless required by applicable law or agreed to in writing, software *
12 # distributed under the License is distributed on an "AS IS" BASIS, *
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
14 # See the License for the specific language governing permissions and *
15 # limitations under the License. *
17 ******************************************************************************/
20 * Copyright (c) 2017 Lev Walkin <vlm@lionet.info>. All rights reserved.
21 * Redistribution and modifications are permitted subject to BSD license.
23 #include <asn_internal.h>
24 #include <OPEN_TYPE.h>
25 #include <constr_CHOICE.h>
26 #include <per_opentype.h>
29 asn_TYPE_operation_t asn_OP_OPEN_TYPE = {
37 #ifdef ASN_DISABLE_OER_SUPPORT
38 0, 0, /* No OER support, use "-gen-OER" to enable */
43 #ifdef ASN_DISABLE_PER_SUPPORT
46 OPEN_TYPE_decode_uper,
47 OPEN_TYPE_encode_uper,
48 OPEN_TYPE_decode_aper,
49 OPEN_TYPE_encode_aper,
51 0, /* Random fill is not supported for open type */
52 0 /* Use generic outmost tag fetcher */
56 #define ADVANCE(num_bytes) \
58 size_t num = num_bytes; \
59 ptr = ((const char *)ptr) + num; \
61 consumed_myself += num; \
65 OPEN_TYPE_ber_get(const asn_codec_ctx_t *opt_codec_ctx,
66 const asn_TYPE_descriptor_t *td, void *sptr,
67 const asn_TYPE_member_t *elm, const void *ptr, size_t size) {
68 size_t consumed_myself = 0;
69 asn_type_selector_result_t selected;
70 void *memb_ptr; /* Pointer to the member */
71 void **memb_ptr2; /* Pointer to that pointer */
75 if(!(elm->flags & ATF_OPEN_TYPE)) {
79 if(!elm->type_selector) {
80 ASN_DEBUG("Type selector is not defined for Open Type %s->%s->%s",
81 td->name, elm->name, elm->type->name);
85 selected = elm->type_selector(td, sptr);
86 if(!selected.presence_index) {
90 /* Fetch the pointer to this member */
91 if(elm->flags & ATF_POINTER) {
92 memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
94 memb_ptr = (char *)sptr + elm->memb_offset;
95 memb_ptr2 = &memb_ptr;
97 if(*memb_ptr2 != NULL) {
98 /* Make sure we reset the structure first before encoding */
99 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0) != 0) {
106 + elm->type->elements[selected.presence_index - 1].memb_offset;
108 ASN_DEBUG("presence %d\n", selected.presence_index);
110 rv = selected.type_descriptor->op->ber_decoder(
111 opt_codec_ctx, selected.type_descriptor, &inner_value, ptr, size,
113 ADVANCE(rv.consumed);
117 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
118 selected.presence_index)
121 rv.consumed = consumed_myself;
124 /* Oh, now a full-blown failure failure */
128 rv.consumed = consumed_myself;
135 if(elm->flags & ATF_POINTER) {
136 ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
139 ASN_STRUCT_RESET(*selected.type_descriptor,
147 OPEN_TYPE_xer_get(const asn_codec_ctx_t *opt_codec_ctx,
148 const asn_TYPE_descriptor_t *td, void *sptr,
149 const asn_TYPE_member_t *elm, const void *ptr, size_t size) {
150 size_t consumed_myself = 0;
151 asn_type_selector_result_t selected;
152 void *memb_ptr; /* Pointer to the member */
153 void **memb_ptr2; /* Pointer to that pointer */
159 pxer_chunk_type_e ch_type;
161 if(!(elm->flags & ATF_OPEN_TYPE)) {
165 if(!elm->type_selector) {
166 ASN_DEBUG("Type selector is not defined for Open Type %s->%s->%s",
167 td->name, elm->name, elm->type->name);
171 selected = elm->type_selector(td, sptr);
172 if(!selected.presence_index) {
176 /* Fetch the pointer to this member */
177 assert(elm->flags == ATF_OPEN_TYPE);
178 if(elm->flags & ATF_POINTER) {
179 memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
181 memb_ptr = (char *)sptr + elm->memb_offset;
182 memb_ptr2 = &memb_ptr;
184 if(*memb_ptr2 != NULL) {
185 /* Make sure we reset the structure first before encoding */
186 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0)
196 ch_size = xer_next_token(&xer_context, ptr, size, &ch_type);
215 * Wrapper value confirmed.
217 switch(xer_check_tag(ptr, ch_size, elm->name)) {
228 + elm->type->elements[selected.presence_index - 1].memb_offset;
230 rv = selected.type_descriptor->op->xer_decoder(
231 opt_codec_ctx, selected.type_descriptor, &inner_value, NULL, ptr, size);
232 ADVANCE(rv.consumed);
236 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
237 selected.presence_index)
245 /* Point to a best position where failure occurred */
246 rv.consumed = consumed_myself;
249 /* Wrt. rv.consumed==0:
250 * In case a genuine RC_WMORE, the whole Open Type decoding
251 * will have to be restarted.
254 if(elm->flags & ATF_POINTER) {
255 ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
258 ASN_STRUCT_RESET(*selected.type_descriptor,
269 ch_size = xer_next_token(&xer_context, ptr, size, &ch_type);
288 * Wrapper value confirmed.
290 switch(xer_check_tag(ptr, ch_size, elm->name)) {
299 rv.consumed += consumed_myself;
305 #ifndef ASN_DISABLE_PER_SUPPORT
308 OPEN_TYPE_uper_get(const asn_codec_ctx_t *opt_codec_ctx,
309 const asn_TYPE_descriptor_t *td, void *sptr,
310 const asn_TYPE_member_t *elm, asn_per_data_t *pd) {
311 asn_type_selector_result_t selected;
312 void *memb_ptr; /* Pointer to the member */
313 void **memb_ptr2; /* Pointer to that pointer */
317 if(!(elm->flags & ATF_OPEN_TYPE)) {
321 if(!elm->type_selector) {
322 ASN_DEBUG("Type selector is not defined for Open Type %s->%s->%s",
323 td->name, elm->name, elm->type->name);
327 selected = elm->type_selector(td, sptr);
328 if(!selected.presence_index) {
332 /* Fetch the pointer to this member */
333 assert(elm->flags == ATF_OPEN_TYPE);
334 if(elm->flags & ATF_POINTER) {
335 memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
337 memb_ptr = (char *)sptr + elm->memb_offset;
338 memb_ptr2 = &memb_ptr;
340 if(*memb_ptr2 != NULL) {
341 /* Make sure we reset the structure first before encoding */
342 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0)
350 + elm->type->elements[selected.presence_index - 1].memb_offset;
352 rv = uper_open_type_get(opt_codec_ctx, selected.type_descriptor, NULL,
356 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
357 selected.presence_index)
367 if(elm->flags & ATF_POINTER) {
368 ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
371 ASN_STRUCT_RESET(*selected.type_descriptor,
380 OPEN_TYPE_encode_uper(const asn_TYPE_descriptor_t *td,
381 const asn_per_constraints_t *constraints,
382 const void *sptr, asn_per_outp_t *po) {
383 const void *memb_ptr; /* Pointer to the member */
384 asn_TYPE_member_t *elm; /* CHOICE's element */
385 asn_enc_rval_t er = {0,0,0};
390 present = CHOICE_variant_get_presence(td, sptr);
391 if(present == 0 || present > td->elements_count) {
397 ASN_DEBUG("Encoding %s OPEN TYPE element %d", td->name, present);
399 elm = &td->elements[present];
400 if(elm->flags & ATF_POINTER) {
401 /* Member is a pointer to another structure */
403 *(const void *const *)((const char *)sptr + elm->memb_offset);
404 if(!memb_ptr) ASN__ENCODE_FAILED;
406 memb_ptr = (const char *)sptr + elm->memb_offset;
409 if(uper_open_type_put(elm->type, NULL, memb_ptr, po) < 0) {
418 OPEN_TYPE_aper_get(const asn_codec_ctx_t *opt_codec_ctx,
419 const asn_TYPE_descriptor_t *td, void *sptr,
420 const asn_TYPE_member_t *elm, asn_per_data_t *pd) {
421 asn_type_selector_result_t selected;
422 void *memb_ptr; /* Pointer to the member */
423 void **memb_ptr2; /* Pointer to that pointer */
427 if(!(elm->flags & ATF_OPEN_TYPE)) {
431 if(!elm->type_selector) {
432 ASN_DEBUG("Type selector is not defined for Open Type %s->%s->%s",
433 td->name, elm->name, elm->type->name);
437 selected = elm->type_selector(td, sptr);
438 if(!selected.presence_index) {
442 /* Fetch the pointer to this member */
443 assert(elm->flags == ATF_OPEN_TYPE);
444 if(elm->flags & ATF_POINTER) {
445 memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
447 memb_ptr = (char *)sptr + elm->memb_offset;
448 memb_ptr2 = &memb_ptr;
450 if(*memb_ptr2 != NULL) {
451 /* Make sure we reset the structure first before encoding */
452 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0)
460 + elm->type->elements[selected.presence_index - 1].memb_offset;
462 rv = aper_open_type_get(opt_codec_ctx, selected.type_descriptor, NULL,
466 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
467 selected.presence_index)
477 if(elm->flags & ATF_POINTER) {
478 ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
481 ASN_STRUCT_RESET(*selected.type_descriptor,
490 OPEN_TYPE_encode_aper(const asn_TYPE_descriptor_t *td,
491 const asn_per_constraints_t *constraints,
492 const void *sptr, asn_per_outp_t *po) {
493 const void *memb_ptr; /* Pointer to the member */
494 asn_TYPE_member_t *elm; /* CHOICE's element */
495 asn_enc_rval_t er = {0,0,0};
500 present = CHOICE_variant_get_presence(td, sptr);
501 if(present == 0 || present > td->elements_count) {
507 ASN_DEBUG("Encoding %s OPEN TYPE element %d", td->name, present);
509 elm = &td->elements[present];
510 if(elm->flags & ATF_POINTER) {
511 /* Member is a pointer to another structure */
513 *(const void *const *)((const char *)sptr + elm->memb_offset);
514 if(!memb_ptr) ASN__ENCODE_FAILED;
516 memb_ptr = (const char *)sptr + elm->memb_offset;
519 if(aper_open_type_put(elm->type, NULL, memb_ptr, po) < 0) {
527 #endif /* ASN_DISABLE_PER_SUPPORT */