blob: 6f90028d3eda1b6f2a7c3440509a6a09f483563a [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
Lev Walkin69033802017-08-25 12:15:58 -070026#ifndef ASN_DISABLE_PER_SUPPORT
27
Lev Walkinf6853ce2017-08-11 00:50:27 -070028asn_dec_rval_t
29OPEN_TYPE_uper_get(asn_codec_ctx_t *opt_codec_ctx,
30 asn_TYPE_descriptor_t *td, void *sptr,
31 asn_TYPE_member_t *elm, asn_per_data_t *pd) {
32 asn_type_selector_result_t selected;
33 void *memb_ptr; /* Pointer to the member */
34 void **memb_ptr2; /* Pointer to that pointer */
35 asn_dec_rval_t rv;
36
37 if(!(elm->flags & ATF_OPEN_TYPE) || !elm->type_selector) {
38 ASN__DECODE_FAILED;
39 }
40
41 selected = elm->type_selector(td, sptr);
42 if(!selected.presence_index) {
43 ASN__DECODE_FAILED;
44 }
45
46 /* Fetch the pointer to this member */
47 assert(elm->flags == ATF_OPEN_TYPE);
48 if(elm->flags & ATF_POINTER) {
49 memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
50 } else {
51 memb_ptr = (char *)sptr + elm->memb_offset;
52 memb_ptr2 = &memb_ptr;
53 }
54 if(*memb_ptr2 != NULL) {
55 /* Make sure we reset the structure first before encoding */
56 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0)
57 != 0) {
58 ASN__DECODE_FAILED;
59 }
60 }
61
62 void *inner_value =
63 (char *)*memb_ptr2
64 + elm->type->elements[selected.presence_index - 1].memb_offset;
65
66 rv = uper_open_type_get(opt_codec_ctx, selected.type_descriptor, NULL,
67 &inner_value, pd);
68 switch(rv.code) {
69 case RC_OK:
70 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
71 selected.presence_index)
72 == 0) {
73 break;
74 } else {
75 rv.code = RC_FAIL;
76 }
77 /* Fall through */
78 case RC_WMORE:
79 case RC_FAIL:
80 if(*memb_ptr2) {
81 asn_CHOICE_specifics_t *specs = selected.type_descriptor->specifics;
82 if(elm->flags & ATF_POINTER) {
83 ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
84 *memb_ptr2 = NULL;
85 } else {
86 ASN_STRUCT_FREE_CONTENTS_ONLY(*selected.type_descriptor,
87 inner_value);
88 memset(*memb_ptr2, 0, specs->struct_size);
89 }
90 }
91 }
92 return rv;
93}
94
Lev Walkin69033802017-08-25 12:15:58 -070095#endif /* ASN_DISABLE_PER_SUPPORT */