mirror of https://gerrit.osmocom.org/asn1c
decode Open Type in XER
This commit is contained in:
parent
5a0436c80a
commit
f59dac9887
|
@ -0,0 +1,140 @@
|
|||
<MessageFrame>
|
||||
<messageId>20</messageId>
|
||||
<value>
|
||||
<BasicSafetyMessage>
|
||||
<coreData>
|
||||
<msgCnt>88</msgCnt>
|
||||
<id>00 00 00 00</id>
|
||||
<secMark>59000</secMark>
|
||||
<lat>511041141</lat>
|
||||
<long>-1341224725</long>
|
||||
<elev>188</elev>
|
||||
<accuracy>
|
||||
<semiMajor>255</semiMajor>
|
||||
<semiMinor>255</semiMinor>
|
||||
<orientation>65535</orientation>
|
||||
</accuracy>
|
||||
<transmission><unavailable/></transmission>
|
||||
<speed>0</speed>
|
||||
<heading>15290</heading>
|
||||
<angle>127</angle>
|
||||
<accelSet>
|
||||
<long>2001</long>
|
||||
<lat>2001</lat>
|
||||
<vert>-127</vert>
|
||||
<yaw>0</yaw>
|
||||
</accelSet>
|
||||
<brakes>
|
||||
<wheelBrakes>
|
||||
10000
|
||||
</wheelBrakes>
|
||||
<traction><unavailable/></traction>
|
||||
<abs><unavailable/></abs>
|
||||
<scs><unavailable/></scs>
|
||||
<brakeBoost><unavailable/></brakeBoost>
|
||||
<auxBrakes><unavailable/></auxBrakes>
|
||||
</brakes>
|
||||
<size>
|
||||
<width>0</width>
|
||||
<length>0</length>
|
||||
</size>
|
||||
</coreData>
|
||||
<partII>
|
||||
<PartIIcontent>
|
||||
<partII-Id>0</partII-Id>
|
||||
<partII-Value>
|
||||
<VehicleSafetyExtensions>
|
||||
<pathHistory>
|
||||
<crumbData>
|
||||
<PathHistoryPoint>
|
||||
<latOffset>-131072</latOffset>
|
||||
<lonOffset>-131072</lonOffset>
|
||||
<elevationOffset>-2048</elevationOffset>
|
||||
<timeOffset>1</timeOffset>
|
||||
</PathHistoryPoint>
|
||||
<PathHistoryPoint>
|
||||
<latOffset>131071</latOffset>
|
||||
<lonOffset>131071</lonOffset>
|
||||
<elevationOffset>2037</elevationOffset>
|
||||
<timeOffset>65535</timeOffset>
|
||||
</PathHistoryPoint>
|
||||
</crumbData>
|
||||
</pathHistory>
|
||||
<pathPrediction>
|
||||
<radiusOfCurve>32767</radiusOfCurve>
|
||||
<confidence>0</confidence>
|
||||
</pathPrediction>
|
||||
</VehicleSafetyExtensions>
|
||||
</partII-Value>
|
||||
</PartIIcontent>
|
||||
</partII>
|
||||
</BasicSafetyMessage>
|
||||
</value>
|
||||
</MessageFrame>
|
||||
<MessageFrame>
|
||||
<messageId>20</messageId>
|
||||
<value>
|
||||
<BasicSafetyMessage>
|
||||
<coreData>
|
||||
<msgCnt>89</msgCnt>
|
||||
<id>FF 00 00 01</id>
|
||||
<secMark>59000</secMark>
|
||||
<lat>511041141</lat>
|
||||
<long>-1341224725</long>
|
||||
<elev>188</elev>
|
||||
<accuracy>
|
||||
<semiMajor>255</semiMajor>
|
||||
<semiMinor>255</semiMinor>
|
||||
<orientation>65535</orientation>
|
||||
</accuracy>
|
||||
<transmission><unavailable/></transmission>
|
||||
<speed>0</speed>
|
||||
<heading>15290</heading>
|
||||
<angle>127</angle>
|
||||
<accelSet>
|
||||
<long>2001</long>
|
||||
<lat>2001</lat>
|
||||
<vert>-127</vert>
|
||||
<yaw>0</yaw>
|
||||
</accelSet>
|
||||
<brakes>
|
||||
<wheelBrakes>
|
||||
10000
|
||||
</wheelBrakes>
|
||||
<traction><unavailable/></traction>
|
||||
<abs><unavailable/></abs>
|
||||
<scs><unavailable/></scs>
|
||||
<brakeBoost><unavailable/></brakeBoost>
|
||||
<auxBrakes><unavailable/></auxBrakes>
|
||||
</brakes>
|
||||
<size>
|
||||
<width>0</width>
|
||||
<length>0</length>
|
||||
</size>
|
||||
</coreData>
|
||||
<partII>
|
||||
<PartIIcontent>
|
||||
<partII-Id>0</partII-Id>
|
||||
<partII-Value>
|
||||
<VehicleSafetyExtensions>
|
||||
<pathHistory>
|
||||
<crumbData>
|
||||
<PathHistoryPoint>
|
||||
<latOffset>0</latOffset>
|
||||
<lonOffset>0</lonOffset>
|
||||
<elevationOffset>0</elevationOffset>
|
||||
<timeOffset>1</timeOffset>
|
||||
</PathHistoryPoint>
|
||||
</crumbData>
|
||||
</pathHistory>
|
||||
<pathPrediction>
|
||||
<radiusOfCurve>0</radiusOfCurve>
|
||||
<confidence>0</confidence>
|
||||
</pathPrediction>
|
||||
</VehicleSafetyExtensions>
|
||||
</partII-Value>
|
||||
</PartIIcontent>
|
||||
</partII>
|
||||
</BasicSafetyMessage>
|
||||
</value>
|
||||
</MessageFrame>
|
|
@ -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 \
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue