aboutsummaryrefslogtreecommitdiffstats
path: root/skeletons/OPEN_TYPE.c
diff options
context:
space:
mode:
authorLev Walkin <vlm@lionet.info>2017-08-11 00:50:27 -0700
committerLev Walkin <vlm@lionet.info>2017-08-11 01:37:26 -0700
commitf6853ce38eaa6f19de4cb5f340873c1cedb11fa3 (patch)
treefbd4c4d77b4252cba5f3194d605c38a0483801b0 /skeletons/OPEN_TYPE.c
parent63a35237b1704f1491f6a8c40dca6a02b3781e96 (diff)
further runtime support for information object classes
Diffstat (limited to 'skeletons/OPEN_TYPE.c')
-rw-r--r--skeletons/OPEN_TYPE.c149
1 files changed, 149 insertions, 0 deletions
diff --git a/skeletons/OPEN_TYPE.c b/skeletons/OPEN_TYPE.c
new file mode 100644
index 00000000..7a53ac31
--- /dev/null
+++ b/skeletons/OPEN_TYPE.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2017 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#include <asn_internal.h>
+#include <OPEN_TYPE.h>
+#include <constr_CHOICE.h>
+#include <per_opentype.h>
+#include <errno.h>
+
+
+asn_dec_rval_t
+OPEN_TYPE_uper_get(asn_codec_ctx_t *opt_codec_ctx,
+ asn_TYPE_descriptor_t *td, void *sptr,
+ asn_TYPE_member_t *elm, asn_per_data_t *pd) {
+ asn_type_selector_result_t selected;
+ void *memb_ptr; /* Pointer to the member */
+ void **memb_ptr2; /* Pointer to that pointer */
+ asn_dec_rval_t rv;
+
+ if(!(elm->flags & ATF_OPEN_TYPE) || !elm->type_selector) {
+ ASN__DECODE_FAILED;
+ }
+
+ selected = elm->type_selector(td, sptr);
+ if(!selected.presence_index) {
+ ASN__DECODE_FAILED;
+ }
+
+ /* Fetch the pointer to this member */
+ assert(elm->flags == ATF_OPEN_TYPE);
+ if(elm->flags & ATF_POINTER) {
+ memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
+ } else {
+ memb_ptr = (char *)sptr + elm->memb_offset;
+ memb_ptr2 = &memb_ptr;
+ }
+ if(*memb_ptr2 != NULL) {
+ /* Make sure we reset the structure first before encoding */
+ if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0)
+ != 0) {
+ ASN__DECODE_FAILED;
+ }
+ }
+
+ void *inner_value =
+ (char *)*memb_ptr2
+ + elm->type->elements[selected.presence_index - 1].memb_offset;
+
+ rv = uper_open_type_get(opt_codec_ctx, selected.type_descriptor, NULL,
+ &inner_value, pd);
+ switch(rv.code) {
+ case RC_OK:
+ if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
+ selected.presence_index)
+ == 0) {
+ break;
+ } else {
+ rv.code = RC_FAIL;
+ }
+ /* Fall through */
+ case RC_WMORE:
+ case RC_FAIL:
+ if(*memb_ptr2) {
+ asn_CHOICE_specifics_t *specs = selected.type_descriptor->specifics;
+ if(elm->flags & ATF_POINTER) {
+ ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
+ *memb_ptr2 = NULL;
+ } else {
+ ASN_STRUCT_FREE_CONTENTS_ONLY(*selected.type_descriptor,
+ inner_value);
+ memset(*memb_ptr2, 0, specs->struct_size);
+ }
+ }
+ }
+ return rv;
+}
+
+asn_dec_rval_t
+OPEN_TYPE_oer_get(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void *sptr, asn_TYPE_member_t *elm, const void *ptr,
+ size_t size) {
+ asn_type_selector_result_t selected;
+ void *memb_ptr; /* Pointer to the member */
+ void **memb_ptr2; /* Pointer to that pointer */
+ asn_dec_rval_t rv;
+ size_t ot_ret;
+
+ if(!(elm->flags & ATF_OPEN_TYPE) || !elm->type_selector) {
+ ASN__DECODE_FAILED;
+ }
+
+ selected = elm->type_selector(td, sptr);
+ if(!selected.presence_index) {
+ ASN__DECODE_FAILED;
+ }
+
+ /* Fetch the pointer to this member */
+ if(elm->flags & ATF_POINTER) {
+ memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
+ } else {
+ memb_ptr = (char *)sptr + elm->memb_offset;
+ memb_ptr2 = &memb_ptr;
+ }
+ if(*memb_ptr2 != NULL) {
+ /* Make sure we reset the structure first before encoding */
+ if(CHOICE_variant_set_presence(selected.type_descriptor, *memb_ptr2, 0)
+ != 0) {
+ ASN__DECODE_FAILED;
+ }
+ }
+
+ ot_ret = oer_open_type_get(opt_codec_ctx, selected.type_descriptor, NULL,
+ memb_ptr2, ptr, size);
+ switch(ot_ret) {
+ default:
+ if(CHOICE_variant_set_presence(selected.type_descriptor, *memb_ptr2,
+ selected.presence_index)
+ == 0) {
+ rv.code = RC_OK;
+ rv.consumed = ot_ret;
+ return rv;
+ } else {
+ /* Oh, now a full-blown failure failure */
+ }
+ /* Fall through */
+ case -1:
+ rv.code = RC_FAIL;
+ rv.consumed = 0;
+ break;
+ case 0:
+ rv.code = RC_WMORE;
+ rv.consumed = 0;
+ break;
+ }
+
+ if(*memb_ptr2) {
+ asn_CHOICE_specifics_t *specs = selected.type_descriptor->specifics;
+ if(elm->flags & ATF_POINTER) {
+ ASN_STRUCT_FREE(*selected.type_descriptor, *memb_ptr2);
+ *memb_ptr2 = NULL;
+ } else {
+ ASN_STRUCT_FREE_CONTENTS_ONLY(*selected.type_descriptor,
+ *memb_ptr2);
+ memset(*memb_ptr2, 0, specs->struct_size);
+ }
+ }
+ return rv;
+}