2 * Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
4 * Redistribution and modifications are permitted subject to BSD license.
6 #include <asn_internal.h>
8 #include <constr_CHOICE.h>
9 #include <aper_opentype.h>
12 OPEN_TYPE_aper_get(const asn_codec_ctx_t *opt_codec_ctx,
13 const asn_TYPE_descriptor_t *td, void *sptr,
14 const asn_TYPE_member_t *elm, asn_per_data_t *pd) {
15 asn_type_selector_result_t selected;
16 void *memb_ptr; /* Pointer to the member */
17 void **memb_ptr2; /* Pointer to that pointer */
21 if(!(elm->flags & ATF_OPEN_TYPE)) {
25 if(!elm->type_selector) {
26 ASN_DEBUG("Type selector is not defined for Open Type %s->%s->%s",
27 td->name, elm->name, elm->type->name);
31 selected = elm->type_selector(td, sptr);
32 if(!selected.presence_index) {
36 /* Fetch the pointer to this member */
37 assert(elm->flags == ATF_OPEN_TYPE);
38 if(elm->flags & ATF_POINTER) {
39 memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
41 memb_ptr = (char *)sptr + elm->memb_offset;
42 memb_ptr2 = &memb_ptr;
44 if(*memb_ptr2 != NULL) {
45 /* Make sure we reset the structure first before encoding */
46 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0)
54 + elm->type->elements[selected.presence_index - 1].memb_offset;
56 rv = aper_open_type_get(opt_codec_ctx, selected.type_descriptor, NULL,
60 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
61 selected.presence_index)
71 if(elm->flags & ATF_POINTER) {
72 ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
75 ASN_STRUCT_RESET(*selected.type_descriptor,
84 OPEN_TYPE_encode_aper(const asn_TYPE_descriptor_t *td,
85 const asn_per_constraints_t *constraints,
86 const void *sptr, asn_per_outp_t *po) {
87 const void *memb_ptr; /* Pointer to the member */
88 asn_TYPE_member_t *elm; /* CHOICE's element */
89 asn_enc_rval_t er = {0,0,0};
94 present = CHOICE_variant_get_presence(td, sptr);
95 if(present == 0 || present > td->elements_count) {
101 ASN_DEBUG("Encoding %s OPEN TYPE element %d", td->name, present);
103 elm = &td->elements[present];
104 if(elm->flags & ATF_POINTER) {
105 /* Member is a pointer to another structure */
107 *(const void *const *)((const char *)sptr + elm->memb_offset);
108 if(!memb_ptr) ASN__ENCODE_FAILED;
110 memb_ptr = (const char *)sptr + elm->memb_offset;
113 if(aper_open_type_put(elm->type, NULL, memb_ptr, po) < 0) {
122 int OPEN_TYPE_aper_is_unknown_type(const asn_TYPE_descriptor_t *td, void *sptr, const asn_TYPE_member_t *elm) {
123 asn_type_selector_result_t selected;
125 if(!elm->type_selector) {
129 selected = elm->type_selector(td, sptr);
130 if(!selected.presence_index) {
138 OPEN_TYPE_aper_unknown_type_discard_bytes (asn_per_data_t *pd) {
139 #define ASN_DUMMY_BYTES 256
140 unsigned char dummy[ASN_DUMMY_BYTES], *dummy_ptr = NULL;
149 bytes = aper_get_length(pd, -1, -1, -1, &repeat);
150 if (bytes > 10 * ASN_DUMMY_BYTES)
154 else if (bytes > ASN_DUMMY_BYTES)
156 dummy_ptr = CALLOC(1, bytes);
161 per_get_many_bits(pd, (dummy_ptr ? dummy_ptr : dummy), 0, bytes << 3);
172 #undef ASN_DUMMY_BYTES