diff --git a/examples/sample.source.J2735/sample-MessageFrame-1.xer b/examples/sample.source.J2735/sample-MessageFrame-1.xer new file mode 100644 index 00000000..1063d088 --- /dev/null +++ b/examples/sample.source.J2735/sample-MessageFrame-1.xer @@ -0,0 +1,140 @@ + + 20 + + + + 88 + 00 00 00 00 + 59000 + 511041141 + -1341224725 + 188 + + 255 + 255 + 65535 + + + 0 + 15290 + 127 + + 2001 + 2001 + -127 + 0 + + + + 10000 + + + + + + + + + 0 + 0 + + + + + 0 + + + + + + -131072 + -131072 + -2048 + 1 + + + 131071 + 131071 + 2037 + 65535 + + + + + 32767 + 0 + + + + + + + + + + 20 + + + + 89 + FF 00 00 01 + 59000 + 511041141 + -1341224725 + 188 + + 255 + 255 + 65535 + + + 0 + 15290 + 127 + + 2001 + 2001 + -127 + 0 + + + + 10000 + + + + + + + + + 0 + 0 + + + + + 0 + + + + + + 0 + 0 + 0 + 1 + + + + + 0 + 0 + + + + + + + + diff --git a/skeletons/Makefile.am b/skeletons/Makefile.am index 1af93c2d..3d334848 100644 --- a/skeletons/Makefile.am +++ b/skeletons/Makefile.am @@ -42,7 +42,8 @@ libasn1cskeletons_la_SOURCES = \ NumericString.c NumericString.h \ OBJECT_IDENTIFIER.c OBJECT_IDENTIFIER.h \ OCTET_STRING.c OCTET_STRING.h \ - OCTET_STRING_oer.c \ + OCTET_STRING_oer.c \ + OPEN_TYPE.c OPEN_TYPE.h \ ObjectDescriptor.c ObjectDescriptor.h \ PrintableString.c PrintableString.h \ REAL.c REAL.h \ diff --git a/skeletons/OPEN_TYPE.c b/skeletons/OPEN_TYPE.c index 6f90028d..6c73eef5 100644 --- a/skeletons/OPEN_TYPE.c +++ b/skeletons/OPEN_TYPE.c @@ -23,6 +23,171 @@ asn_TYPE_operation_t asn_OP_OPEN_TYPE = { 0, /* Use generic outmost tag fetcher */ }; +#undef XER_ADVANCE +#define XER_ADVANCE(num_bytes) \ + do { \ + size_t num = num_bytes; \ + ptr = ((const char *)ptr) + num; \ + size -= num; \ + consumed_myself += num; \ + } while(0) + +asn_dec_rval_t +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, + 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; + const char *xml_tag; + asn_dec_rval_t rv; + + int xer_context = 0; + ssize_t ch_size; + pxer_chunk_type_e ch_type; + + 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; + } + } + + /* + * Confirm wrapper. + */ + for(;;) { + ch_size = xer_next_token(&xer_context, ptr, size, &ch_type); + if(ch_size <= 0) { + ASN__DECODE_FAILED; + } else { + switch(ch_type) { + case PXER_WMORE: + ASN__DECODE_STARVED; + case PXER_COMMENT: + case PXER_TEXT: + XER_ADVANCE(ch_size); + continue; + case PXER_TAG: + break; + } + break; + } + } + + /* + * Wrapper value confirmed. + */ + switch(xer_check_tag(ptr, ch_size, elm->name)) { + case XCT_OPENING: + XER_ADVANCE(ch_size); + break; + case XCT_BROKEN: + default: + ASN__DECODE_FAILED; + } + + inner_value = + (char *)*memb_ptr2 + + elm->type->elements[selected.presence_index - 1].memb_offset; + + rv = selected.type_descriptor->op->xer_decoder( + opt_codec_ctx, selected.type_descriptor, &inner_value, NULL, ptr, size); + XER_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) { + break; + } else { + rv.code = RC_FAIL; + } + /* Fall through */ + case RC_FAIL: + /* Point to a best position where failure occurred */ + rv.consumed = consumed_myself; + /* Fall through */ + case RC_WMORE: + /* Wrt. rv.consumed==0: + * In case a genuine RC_WMORE, the whole Open Type decoding + * will have to be restarted. + */ + 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; + } + + /* + * Finalize wrapper. + */ + for(;;) { + ch_size = xer_next_token(&xer_context, ptr, size, &ch_type); + if(ch_size <= 0) { + ASN__DECODE_FAILED; + } else { + switch(ch_type) { + case PXER_WMORE: + ASN__DECODE_STARVED; + case PXER_COMMENT: + case PXER_TEXT: + XER_ADVANCE(ch_size); + continue; + case PXER_TAG: + break; + } + break; + } + } + + /* + * Wrapper value confirmed. + */ + switch(xer_check_tag(ptr, ch_size, elm->name)) { + case XCT_CLOSING: + XER_ADVANCE(ch_size); + break; + case XCT_BROKEN: + default: + ASN__DECODE_FAILED; + } + + rv.consumed += consumed_myself; + + return rv; +} + + #ifndef ASN_DISABLE_PER_SUPPORT asn_dec_rval_t @@ -32,6 +197,7 @@ OPEN_TYPE_uper_get(asn_codec_ctx_t *opt_codec_ctx, 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) { @@ -59,7 +225,7 @@ OPEN_TYPE_uper_get(asn_codec_ctx_t *opt_codec_ctx, } } - void *inner_value = + inner_value = (char *)*memb_ptr2 + elm->type->elements[selected.presence_index - 1].memb_offset; diff --git a/skeletons/OPEN_TYPE.h b/skeletons/OPEN_TYPE.h index 060675a6..ff49adad 100644 --- a/skeletons/OPEN_TYPE.h +++ b/skeletons/OPEN_TYPE.h @@ -28,11 +28,11 @@ extern asn_TYPE_operation_t asn_OP_OPEN_TYPE; * Decode an Open Type which is potentially constraiend * by the other members of the parent structure. */ -asn_dec_rval_t OPEN_TYPE_uper_get(asn_codec_ctx_t *opt_codec_ctx, - asn_TYPE_descriptor_t *parent_type, - void *parent_structure, - asn_TYPE_member_t *element, - asn_per_data_t *pd); +asn_dec_rval_t OPEN_TYPE_xer_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_oer_get(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *parent_type, @@ -40,6 +40,12 @@ asn_dec_rval_t OPEN_TYPE_oer_get(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_member_t *element, const void *ptr, size_t size); +asn_dec_rval_t OPEN_TYPE_uper_get(asn_codec_ctx_t *opt_codec_ctx, + asn_TYPE_descriptor_t *parent_type, + void *parent_structure, + asn_TYPE_member_t *element, + asn_per_data_t *pd); + #ifdef __cplusplus } diff --git a/skeletons/constr_SEQUENCE.c b/skeletons/constr_SEQUENCE.c index b863d5f3..ba74067f 100644 --- a/skeletons/constr_SEQUENCE.c +++ b/skeletons/constr_SEQUENCE.c @@ -594,12 +594,13 @@ SEQUENCE_encode_der(asn_TYPE_descriptor_t *td, #undef XER_ADVANCE -#define XER_ADVANCE(num_bytes) do { \ - size_t num = num_bytes; \ - buf_ptr = ((const char *)buf_ptr) + num;\ - size -= num; \ - consumed_myself += num; \ - } while(0) +#define XER_ADVANCE(num_bytes) \ + do { \ + size_t num = (num_bytes); \ + ptr = ((const char *)ptr) + num; \ + size -= num; \ + consumed_myself += num; \ + } while(0) /* * Decode the XER (XML) data. @@ -607,7 +608,7 @@ SEQUENCE_encode_der(asn_TYPE_descriptor_t *td, asn_dec_rval_t SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **struct_ptr, const char *opt_mname, - const void *buf_ptr, size_t size) { + const void *ptr, size_t size) { /* * Bring closer parts of structure description. */ @@ -672,10 +673,14 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, memb_ptr2 = &memb_ptr; } - /* Invoke the inner type decoder, m.b. multiple times */ - tmprval = elm->type->op->xer_decoder(opt_codec_ctx, - elm->type, memb_ptr2, elm->name, - buf_ptr, size); + if((elm->flags & ATF_OPEN_TYPE) && elm->type_selector) { + tmprval = OPEN_TYPE_xer_get(opt_codec_ctx, td, st, elm, ptr, size); + } else { + /* Invoke the inner type decoder, m.b. multiple times */ + tmprval = elm->type->op->xer_decoder(opt_codec_ctx, + elm->type, memb_ptr2, elm->name, + ptr, size); + } XER_ADVANCE(tmprval.consumed); if(tmprval.code != RC_OK) RETURN(tmprval.code); @@ -689,14 +694,14 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, /* * Get the next part of the XML stream. */ - ch_size = xer_next_token(&ctx->context, buf_ptr, size, + ch_size = xer_next_token(&ctx->context, ptr, size, &ch_type); if(ch_size == -1) { RETURN(RC_FAIL); - } else { + } else { switch(ch_type) { - case PXER_WMORE: - RETURN(RC_WMORE); + case PXER_WMORE: + RETURN(RC_WMORE); case PXER_COMMENT: /* Got XML comment */ case PXER_TEXT: /* Ignore free-standing text */ XER_ADVANCE(ch_size); /* Skip silently */ @@ -706,7 +711,7 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, } } - tcv = xer_check_tag(buf_ptr, ch_size, xml_tag); + tcv = xer_check_tag(ptr, ch_size, xml_tag); ASN_DEBUG("XER/SEQUENCE: tcv = %d, ph=%d [%s]", tcv, ctx->phase, xml_tag); @@ -782,8 +787,7 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, edx_end = td->elements_count; for(n = edx; n < edx_end; n++) { elm = &td->elements[n]; - tcv = xer_check_tag(buf_ptr, - ch_size, elm->name); + tcv = xer_check_tag(ptr, ch_size, elm->name); switch(tcv) { case XCT_BOTH: case XCT_OPENING: @@ -836,12 +840,12 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, } ASN_DEBUG("Unexpected XML tag in SEQUENCE [%c%c%c%c%c%c]", - size>0?((const char *)buf_ptr)[0]:'.', - size>1?((const char *)buf_ptr)[1]:'.', - size>2?((const char *)buf_ptr)[2]:'.', - size>3?((const char *)buf_ptr)[3]:'.', - size>4?((const char *)buf_ptr)[4]:'.', - size>5?((const char *)buf_ptr)[5]:'.'); + size>0?((const char *)ptr)[0]:'.', + size>1?((const char *)ptr)[1]:'.', + size>2?((const char *)ptr)[2]:'.', + size>3?((const char *)ptr)[3]:'.', + size>4?((const char *)ptr)[4]:'.', + size>5?((const char *)ptr)[5]:'.'); break; } @@ -1135,7 +1139,7 @@ SEQUENCE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, if((elm->flags & ATF_OPEN_TYPE) && elm->type_selector) { rv = OPEN_TYPE_uper_get(opt_codec_ctx, td, st, elm, pd); } else { - rv = elm->type->op->uper_decoder(opt_codec_ctx, elm->type, + rv = elm->type->op->uper_decoder(opt_codec_ctx, elm->type, elm->per_constraints, memb_ptr2, pd); } if(rv.code != RC_OK) {