decode Open Type in XER

This commit is contained in:
Lev Walkin 2017-08-26 21:26:51 -07:00
parent 5a0436c80a
commit f59dac9887
5 changed files with 349 additions and 32 deletions

View File

@ -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>

View File

@ -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 \

View File

@ -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;

View File

@ -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
}

View File

@ -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) {