Commit c10d30a3 authored by Lev Walkin's avatar Lev Walkin

BER open type fix

parent 2e5caa51
...@@ -23,8 +23,8 @@ asn_TYPE_operation_t asn_OP_OPEN_TYPE = { ...@@ -23,8 +23,8 @@ asn_TYPE_operation_t asn_OP_OPEN_TYPE = {
0, /* Use generic outmost tag fetcher */ 0, /* Use generic outmost tag fetcher */
}; };
#undef XER_ADVANCE #undef ADVANCE
#define XER_ADVANCE(num_bytes) \ #define ADVANCE(num_bytes) \
do { \ do { \
size_t num = num_bytes; \ size_t num = num_bytes; \
ptr = ((const char *)ptr) + num; \ ptr = ((const char *)ptr) + num; \
...@@ -32,6 +32,84 @@ asn_TYPE_operation_t asn_OP_OPEN_TYPE = { ...@@ -32,6 +32,84 @@ asn_TYPE_operation_t asn_OP_OPEN_TYPE = {
consumed_myself += num; \ consumed_myself += num; \
} while(0) } while(0)
asn_dec_rval_t
OPEN_TYPE_ber_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) {
size_t consumed_myself = 0;
asn_type_selector_result_t selected;
void *memb_ptr; /* Pointer to the member */
void **memb_ptr2; /* Pointer to that pointer */
void *inner_value;
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 */
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;
}
}
inner_value =
(char *)*memb_ptr2
+ elm->type->elements[selected.presence_index - 1].memb_offset;
ASN_DEBUG("presence %d\n", selected.presence_index);
rv = selected.type_descriptor->op->ber_decoder(
opt_codec_ctx, selected.type_descriptor, &inner_value, ptr, size,
elm->tag_mode);
ADVANCE(rv.consumed);
rv.consumed = 0;
switch(rv.code) {
case RC_OK:
if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
selected.presence_index)
== 0) {
rv.code = RC_OK;
rv.consumed = consumed_myself;
return rv;
} else {
/* Oh, now a full-blown failure failure */
}
/* Fall through */
case RC_FAIL:
rv.consumed = consumed_myself;
/* Fall through */
case RC_WMORE:
break;
}
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 asn_dec_rval_t
OPEN_TYPE_xer_get(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, OPEN_TYPE_xer_get(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
void *sptr, asn_TYPE_member_t *elm, const void *ptr, void *sptr, asn_TYPE_member_t *elm, const void *ptr,
...@@ -86,7 +164,7 @@ OPEN_TYPE_xer_get(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, ...@@ -86,7 +164,7 @@ OPEN_TYPE_xer_get(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
ASN__DECODE_STARVED; ASN__DECODE_STARVED;
case PXER_COMMENT: case PXER_COMMENT:
case PXER_TEXT: case PXER_TEXT:
XER_ADVANCE(ch_size); ADVANCE(ch_size);
continue; continue;
case PXER_TAG: case PXER_TAG:
break; break;
...@@ -100,7 +178,7 @@ OPEN_TYPE_xer_get(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, ...@@ -100,7 +178,7 @@ OPEN_TYPE_xer_get(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
*/ */
switch(xer_check_tag(ptr, ch_size, elm->name)) { switch(xer_check_tag(ptr, ch_size, elm->name)) {
case XCT_OPENING: case XCT_OPENING:
XER_ADVANCE(ch_size); ADVANCE(ch_size);
break; break;
case XCT_BROKEN: case XCT_BROKEN:
default: default:
...@@ -113,7 +191,7 @@ OPEN_TYPE_xer_get(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, ...@@ -113,7 +191,7 @@ OPEN_TYPE_xer_get(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
rv = selected.type_descriptor->op->xer_decoder( rv = selected.type_descriptor->op->xer_decoder(
opt_codec_ctx, selected.type_descriptor, &inner_value, NULL, ptr, size); opt_codec_ctx, selected.type_descriptor, &inner_value, NULL, ptr, size);
XER_ADVANCE(rv.consumed); ADVANCE(rv.consumed);
rv.consumed = 0; rv.consumed = 0;
switch(rv.code) { switch(rv.code) {
case RC_OK: case RC_OK:
...@@ -161,7 +239,7 @@ OPEN_TYPE_xer_get(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, ...@@ -161,7 +239,7 @@ OPEN_TYPE_xer_get(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
ASN__DECODE_STARVED; ASN__DECODE_STARVED;
case PXER_COMMENT: case PXER_COMMENT:
case PXER_TEXT: case PXER_TEXT:
XER_ADVANCE(ch_size); ADVANCE(ch_size);
continue; continue;
case PXER_TAG: case PXER_TAG:
break; break;
...@@ -175,7 +253,7 @@ OPEN_TYPE_xer_get(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, ...@@ -175,7 +253,7 @@ OPEN_TYPE_xer_get(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
*/ */
switch(xer_check_tag(ptr, ch_size, elm->name)) { switch(xer_check_tag(ptr, ch_size, elm->name)) {
case XCT_CLOSING: case XCT_CLOSING:
XER_ADVANCE(ch_size); ADVANCE(ch_size);
break; break;
case XCT_BROKEN: case XCT_BROKEN:
default: default:
......
...@@ -27,6 +27,12 @@ extern asn_TYPE_operation_t asn_OP_OPEN_TYPE; ...@@ -27,6 +27,12 @@ extern asn_TYPE_operation_t asn_OP_OPEN_TYPE;
* Decode an Open Type which is potentially constraiend * Decode an Open Type which is potentially constraiend
* by the other members of the parent structure. * by the other members of the parent structure.
*/ */
asn_dec_rval_t OPEN_TYPE_ber_get(asn_codec_ctx_t *opt_codec_ctx,
asn_TYPE_descriptor_t *parent_type,
void *parent_structure,
asn_TYPE_member_t *element, const void *ptr,
size_t size);
asn_dec_rval_t OPEN_TYPE_xer_get(asn_codec_ctx_t *opt_codec_ctx, asn_dec_rval_t OPEN_TYPE_xer_get(asn_codec_ctx_t *opt_codec_ctx,
asn_TYPE_descriptor_t *parent_type, asn_TYPE_descriptor_t *parent_type,
void *parent_structure, void *parent_structure,
......
...@@ -410,10 +410,14 @@ SEQUENCE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, ...@@ -410,10 +410,14 @@ SEQUENCE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
/* /*
* Invoke the member fetch routine according to member's type * Invoke the member fetch routine according to member's type
*/ */
if((elements[edx].flags & ATF_OPEN_TYPE) && elements[edx].type_selector) {
rval = OPEN_TYPE_ber_get(opt_codec_ctx, td, st, &elements[edx], ptr, LEFT);
} else {
rval = elements[edx].type->op->ber_decoder(opt_codec_ctx, rval = elements[edx].type->op->ber_decoder(opt_codec_ctx,
elements[edx].type, elements[edx].type,
memb_ptr2, ptr, LEFT, memb_ptr2, ptr, LEFT,
elements[edx].tag_mode); elements[edx].tag_mode);
}
ASN_DEBUG("In %s SEQUENCE decoded %zu %s of %d " ASN_DEBUG("In %s SEQUENCE decoded %zu %s of %d "
"in %d bytes rval.code %d, size=%d", "in %d bytes rval.code %d, size=%d",
td->name, edx, elements[edx].type->name, td->name, edx, elements[edx].type->name,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment