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 0, 0, /* No OER support, use "-gen-OER" to enable */
20 #ifdef ASN_DISABLE_PER_SUPPORT
23 OPEN_TYPE_decode_uper,
24 OPEN_TYPE_encode_uper,
26 0, /* Random fill is not supported for open type */
27 0, /* Use generic outmost tag fetcher */
31 #define ADVANCE(num_bytes) \
33 size_t num = num_bytes; \
34 ptr = ((const char *)ptr) + num; \
36 consumed_myself += num; \
40 OPEN_TYPE_ber_get(const asn_codec_ctx_t *opt_codec_ctx,
41 const asn_TYPE_descriptor_t *td, void *sptr,
42 const asn_TYPE_member_t *elm, const void *ptr, size_t size) {
43 size_t consumed_myself = 0;
44 asn_type_selector_result_t selected;
45 void *memb_ptr; /* Pointer to the member */
46 void **memb_ptr2; /* Pointer to that pointer */
50 if(!(elm->flags & ATF_OPEN_TYPE)) {
54 if(!elm->type_selector) {
55 ASN_DEBUG("Type selector is not defined for Open Type %s->%s->%s",
56 td->name, elm->name, elm->type->name);
60 selected = elm->type_selector(td, sptr);
61 if(!selected.presence_index) {
65 /* Fetch the pointer to this member */
66 if(elm->flags & ATF_POINTER) {
67 memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
69 memb_ptr = (char *)sptr + elm->memb_offset;
70 memb_ptr2 = &memb_ptr;
72 if(*memb_ptr2 != NULL) {
73 /* Make sure we reset the structure first before encoding */
74 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0) != 0) {
81 + elm->type->elements[selected.presence_index - 1].memb_offset;
83 ASN_DEBUG("presence %d\n", selected.presence_index);
85 rv = selected.type_descriptor->op->ber_decoder(
86 opt_codec_ctx, selected.type_descriptor, &inner_value, ptr, size,
92 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
93 selected.presence_index)
96 rv.consumed = consumed_myself;
99 /* Oh, now a full-blown failure failure */
103 rv.consumed = consumed_myself;
110 const asn_CHOICE_specifics_t *specs =
111 selected.type_descriptor->specifics;
112 if(elm->flags & ATF_POINTER) {
113 ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
116 ASN_STRUCT_FREE_CONTENTS_ONLY(*selected.type_descriptor,
118 memset(*memb_ptr2, 0, specs->struct_size);
125 OPEN_TYPE_xer_get(const asn_codec_ctx_t *opt_codec_ctx,
126 const asn_TYPE_descriptor_t *td, void *sptr,
127 const asn_TYPE_member_t *elm, const void *ptr, size_t size) {
128 size_t consumed_myself = 0;
129 asn_type_selector_result_t selected;
130 void *memb_ptr; /* Pointer to the member */
131 void **memb_ptr2; /* Pointer to that pointer */
137 pxer_chunk_type_e ch_type;
139 if(!(elm->flags & ATF_OPEN_TYPE)) {
143 if(!elm->type_selector) {
144 ASN_DEBUG("Type selector is not defined for Open Type %s->%s->%s",
145 td->name, elm->name, elm->type->name);
149 selected = elm->type_selector(td, sptr);
150 if(!selected.presence_index) {
154 /* Fetch the pointer to this member */
155 assert(elm->flags == ATF_OPEN_TYPE);
156 if(elm->flags & ATF_POINTER) {
157 memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
159 memb_ptr = (char *)sptr + elm->memb_offset;
160 memb_ptr2 = &memb_ptr;
162 if(*memb_ptr2 != NULL) {
163 /* Make sure we reset the structure first before encoding */
164 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0)
174 ch_size = xer_next_token(&xer_context, ptr, size, &ch_type);
193 * Wrapper value confirmed.
195 switch(xer_check_tag(ptr, ch_size, elm->name)) {
206 + elm->type->elements[selected.presence_index - 1].memb_offset;
208 rv = selected.type_descriptor->op->xer_decoder(
209 opt_codec_ctx, selected.type_descriptor, &inner_value, NULL, ptr, size);
210 ADVANCE(rv.consumed);
214 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
215 selected.presence_index)
223 /* Point to a best position where failure occurred */
224 rv.consumed = consumed_myself;
227 /* Wrt. rv.consumed==0:
228 * In case a genuine RC_WMORE, the whole Open Type decoding
229 * will have to be restarted.
232 const asn_CHOICE_specifics_t *specs =
233 selected.type_descriptor->specifics;
234 if(elm->flags & ATF_POINTER) {
235 ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
238 ASN_STRUCT_FREE_CONTENTS_ONLY(*selected.type_descriptor,
240 memset(*memb_ptr2, 0, specs->struct_size);
250 ch_size = xer_next_token(&xer_context, ptr, size, &ch_type);
269 * Wrapper value confirmed.
271 switch(xer_check_tag(ptr, ch_size, elm->name)) {
280 rv.consumed += consumed_myself;
286 #ifndef ASN_DISABLE_PER_SUPPORT
289 OPEN_TYPE_uper_get(const asn_codec_ctx_t *opt_codec_ctx,
290 const asn_TYPE_descriptor_t *td, void *sptr,
291 const asn_TYPE_member_t *elm, asn_per_data_t *pd) {
292 asn_type_selector_result_t selected;
293 void *memb_ptr; /* Pointer to the member */
294 void **memb_ptr2; /* Pointer to that pointer */
298 if(!(elm->flags & ATF_OPEN_TYPE)) {
302 if(!elm->type_selector) {
303 ASN_DEBUG("Type selector is not defined for Open Type %s->%s->%s",
304 td->name, elm->name, elm->type->name);
308 selected = elm->type_selector(td, sptr);
309 if(!selected.presence_index) {
313 /* Fetch the pointer to this member */
314 assert(elm->flags == ATF_OPEN_TYPE);
315 if(elm->flags & ATF_POINTER) {
316 memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
318 memb_ptr = (char *)sptr + elm->memb_offset;
319 memb_ptr2 = &memb_ptr;
321 if(*memb_ptr2 != NULL) {
322 /* Make sure we reset the structure first before encoding */
323 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0)
331 + elm->type->elements[selected.presence_index - 1].memb_offset;
333 rv = uper_open_type_get(opt_codec_ctx, selected.type_descriptor, NULL,
337 if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
338 selected.presence_index)
348 const asn_CHOICE_specifics_t *specs =
349 selected.type_descriptor->specifics;
350 if(elm->flags & ATF_POINTER) {
351 ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
354 ASN_STRUCT_FREE_CONTENTS_ONLY(*selected.type_descriptor,
356 memset(*memb_ptr2, 0, specs->struct_size);
364 OPEN_TYPE_encode_uper(const asn_TYPE_descriptor_t *td,
365 const asn_per_constraints_t *constraints,
366 const void *sptr, asn_per_outp_t *po) {
367 const void *memb_ptr; /* Pointer to the member */
368 asn_TYPE_member_t *elm; /* CHOICE's element */
374 present = CHOICE_variant_get_presence(td, sptr);
375 if(present == 0 || present > td->elements_count) {
381 ASN_DEBUG("Encoding %s OPEN TYPE element %d", td->name, present);
383 elm = &td->elements[present];
384 if(elm->flags & ATF_POINTER) {
385 /* Member is a pointer to another structure */
387 *(const void *const *)((const char *)sptr + elm->memb_offset);
388 if(!memb_ptr) ASN__ENCODE_FAILED;
390 memb_ptr = (const char *)sptr + elm->memb_offset;
393 if(uper_open_type_put(elm->type, NULL, memb_ptr, po) < 0) {
402 #endif /* ASN_DISABLE_PER_SUPPORT */