Commit c61f3868 authored by Lev Walkin's avatar Lev Walkin

more XER decoding

parent b2c3fa95
...@@ -1103,26 +1103,34 @@ OCTET_STRING__decode_xer(asn_codec_ctx_t *opt_codec_ctx, ...@@ -1103,26 +1103,34 @@ OCTET_STRING__decode_xer(asn_codec_ctx_t *opt_codec_ctx,
(void *struct_ptr, void *chunk_buf, size_t chunk_size, (void *struct_ptr, void *chunk_buf, size_t chunk_size,
int have_more) int have_more)
) { ) {
OCTET_STRING_t *st = *sptr;
asn_OCTET_STRING_specifics_t *specs = td->specifics asn_OCTET_STRING_specifics_t *specs = td->specifics
? (asn_OCTET_STRING_specifics_t *)td->specifics ? (asn_OCTET_STRING_specifics_t *)td->specifics
: &asn_DEF_OCTET_STRING_specs; : &asn_DEF_OCTET_STRING_specs;
const char *xml_tag = opt_mname ? opt_mname : td->xml_tag; const char *xml_tag = opt_mname ? opt_mname : td->xml_tag;
asn_struct_ctx_t *ctx; /* Per-structure parser context */ asn_struct_ctx_t *ctx; /* Per-structure parser context */
asn_dec_rval_t rval; /* Return value from the decoder */
int st_allocated;
/* /*
* Create the string if does not exist. * Create the string if does not exist.
*/ */
if(!*sptr) { if(!st) {
OCTET_STRING_t *st;
st = (OCTET_STRING_t *)CALLOC(1, specs->struct_size); st = (OCTET_STRING_t *)CALLOC(1, specs->struct_size);
if(st) st->buf = (uint8_t *)CALLOC(1, 1);
*sptr = (void *)st; *sptr = (void *)st;
if(!st || !st->buf) { if(!st) goto sta_failed;
asn_dec_rval_t rval; st_allocated = 1;
if(*sptr) FREEMEM(*sptr); } else st_allocated = 0;
rval.code = RC_FAIL; if(!st->buf) {
rval.consumed = 0; /* This is separate from above section */
return rval; st->buf = (uint8_t *)CALLOC(1, 1);
if(!st->buf) {
if(st_allocated) {
*sptr = 0;
goto stb_failed;
} else {
goto sta_failed;
}
} }
} }
...@@ -1131,6 +1139,13 @@ OCTET_STRING__decode_xer(asn_codec_ctx_t *opt_codec_ctx, ...@@ -1131,6 +1139,13 @@ OCTET_STRING__decode_xer(asn_codec_ctx_t *opt_codec_ctx,
return xer_decode_general(opt_codec_ctx, ctx, *sptr, xml_tag, return xer_decode_general(opt_codec_ctx, ctx, *sptr, xml_tag,
buf_ptr, size, opt_unexpected_tag_decoder, body_receiver); buf_ptr, size, opt_unexpected_tag_decoder, body_receiver);
stb_failed:
FREEMEM(st);
sta_failed:
rval.code = RC_FAIL;
rval.consumed = 0;
return rval;
} }
/* /*
......
/*- /*-
* Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved. * Copyright (c) 2003, 2004, 2005 Lev Walkin <vlm@lionet.info>.
* All rights reserved.
* Redistribution and modifications are permitted subject to BSD license. * Redistribution and modifications are permitted subject to BSD license.
*/ */
#include <asn_internal.h> #include <asn_internal.h>
...@@ -539,7 +540,6 @@ CHOICE_constraint(asn_TYPE_descriptor_t *td, const void *sptr, ...@@ -539,7 +540,6 @@ CHOICE_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
} }
} }
#undef ADVANCE /* Just in case */
#undef XER_ADVANCE #undef XER_ADVANCE
#define XER_ADVANCE(num_bytes) do { \ #define XER_ADVANCE(num_bytes) do { \
size_t num = num_bytes; \ size_t num = num_bytes; \
...@@ -548,6 +548,9 @@ CHOICE_constraint(asn_TYPE_descriptor_t *td, const void *sptr, ...@@ -548,6 +548,9 @@ CHOICE_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
consumed_myself += num; \ consumed_myself += num; \
} while(0) } while(0)
/*
* Decode the XER (XML) data.
*/
asn_dec_rval_t asn_dec_rval_t
CHOICE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, CHOICE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
void **struct_ptr, const char *opt_mname, void **struct_ptr, const char *opt_mname,
...@@ -564,7 +567,7 @@ CHOICE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, ...@@ -564,7 +567,7 @@ CHOICE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
void *st = *struct_ptr; /* Target structure. */ void *st = *struct_ptr; /* Target structure. */
asn_struct_ctx_t *ctx; /* Decoder context */ asn_struct_ctx_t *ctx; /* Decoder context */
asn_dec_rval_t rval; asn_dec_rval_t rval; /* Return value of a decoder */
ssize_t consumed_myself = 0; /* Consumed bytes from ptr */ ssize_t consumed_myself = 0; /* Consumed bytes from ptr */
int xer_state; /* XER low level parsing context */ int xer_state; /* XER low level parsing context */
int edx; /* Element index */ int edx; /* Element index */
...@@ -590,9 +593,7 @@ CHOICE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, ...@@ -590,9 +593,7 @@ CHOICE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
* Phase 2: Processing inner type. * Phase 2: Processing inner type.
* Phase 3: Only waiting for closing tag * Phase 3: Only waiting for closing tag
*/ */
for(xer_state = ctx->left, edx = ctx->step; ctx->phase <= 3;) {
if(ctx->phase > 3) RETURN(RC_FAIL);
for(xer_state = ctx->left, edx = ctx->step;;) {
pxer_chunk_type_e ch_type; /* XER chunk type */ pxer_chunk_type_e ch_type; /* XER chunk type */
ssize_t ch_size; /* Chunk size */ ssize_t ch_size; /* Chunk size */
xer_check_tag_e tcv; /* Tag check value */ xer_check_tag_e tcv; /* Tag check value */
...@@ -617,12 +618,19 @@ CHOICE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, ...@@ -617,12 +618,19 @@ CHOICE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
memb_ptr2 = &memb_ptr; memb_ptr2 = &memb_ptr;
} }
/* Start/Continue decoding the inner member */
tmprval = elm->type->xer_decoder(opt_codec_ctx, tmprval = elm->type->xer_decoder(opt_codec_ctx,
elm->type, memb_ptr2, elm->name, elm->type, memb_ptr2, elm->name,
buf_ptr, size); buf_ptr, size);
XER_ADVANCE(tmprval.consumed); XER_ADVANCE(tmprval.consumed);
ASN_DEBUG("XER/CHOICE: itdf: code=%d, xs=%d", tmprval.code, xer_state);
if(tmprval.code != RC_OK) if(tmprval.code != RC_OK)
RETURN(tmprval.code); RETURN(tmprval.code);
assert(_fetch_present_idx(st,
specs->pres_offset, specs->pres_size) == 0);
/* Record what we've got */
_set_present_idx(st,
specs->pres_offset, specs->pres_size, edx + 1);
ctx->left = xer_state = 0; /* New, clean state */ ctx->left = xer_state = 0; /* New, clean state */
ctx->phase = 3; ctx->phase = 3;
/* Fall through */ /* Fall through */
...@@ -648,25 +656,22 @@ CHOICE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, ...@@ -648,25 +656,22 @@ CHOICE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
} }
} }
tcv = xer_check_tag(buf_ptr, size, xml_tag); tcv = xer_check_tag(buf_ptr, ch_size, xml_tag);
printf("XER/CHOICE tcv=%d ph=%d\n", tcv, ctx->phase);
switch(tcv) { switch(tcv) {
case XCT_BOTH: case XCT_BOTH:
if(ctx->phase == 3) break; /* No CHOICE? */
break;
case XCT_CLOSING: case XCT_CLOSING:
if(ctx->phase == 0) if(ctx->phase != 3)
break; break;
XER_ADVANCE(ch_size); XER_ADVANCE(ch_size);
ctx->phase = 4; ctx->phase = 4; /* Phase out */
RETURN(RC_OK); RETURN(RC_OK);
case XCT_OPENING: case XCT_OPENING:
if(ctx->phase == 0) { if(ctx->phase == 0) {
XER_ADVANCE(ch_size); XER_ADVANCE(ch_size);
ctx->phase = 1; /* Processing body phase */ ctx->phase = 1; /* Processing body phase */
continue; continue;
} else if(ctx->phase == 3) {
/* But we're waiting for closing! */
break;
} }
/* Fall through */ /* Fall through */
case XCT_UNEXPECTED: case XCT_UNEXPECTED:
...@@ -675,11 +680,11 @@ CHOICE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, ...@@ -675,11 +680,11 @@ CHOICE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
break; /* Really unexpected */ break; /* Really unexpected */
/* /*
* Search which member corresponds to this tag. * Search which inner member corresponds to this tag.
*/ */
for(edx = 0; edx < td->elements_count; edx++) { for(edx = 0; edx < td->elements_count; edx++) {
elm = &td->elements[edx]; elm = &td->elements[edx];
tcv = xer_check_tag(buf_ptr, size, elm->name); tcv = xer_check_tag(buf_ptr,ch_size,elm->name);
switch(tcv) { switch(tcv) {
case XCT_BOTH: case XCT_BOTH:
case XCT_OPENING: case XCT_OPENING:
...@@ -704,7 +709,7 @@ CHOICE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, ...@@ -704,7 +709,7 @@ CHOICE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
break; break;
} }
ASN_DEBUG("Unexpected XML tag in SEQUENCE"); ASN_DEBUG("Unexpected XML tag in CHOICE");
break; break;
} }
......
/*- /*-
* Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved. * Copyright (c) 2003, 2004, 2005 Lev Walkin <vlm@lionet.info>.
* All rights reserved.
* Redistribution and modifications are permitted subject to BSD license. * Redistribution and modifications are permitted subject to BSD license.
*/ */
#include <asn_internal.h> #include <asn_internal.h>
...@@ -588,7 +589,7 @@ SEQUENCE_encode_der(asn_TYPE_descriptor_t *td, ...@@ -588,7 +589,7 @@ SEQUENCE_encode_der(asn_TYPE_descriptor_t *td,
return erval; return erval;
} }
#undef ADVANCE /* Just in case */
#undef XER_ADVANCE #undef XER_ADVANCE
#define XER_ADVANCE(num_bytes) do { \ #define XER_ADVANCE(num_bytes) do { \
size_t num = num_bytes; \ size_t num = num_bytes; \
...@@ -597,6 +598,9 @@ SEQUENCE_encode_der(asn_TYPE_descriptor_t *td, ...@@ -597,6 +598,9 @@ SEQUENCE_encode_der(asn_TYPE_descriptor_t *td,
consumed_myself += num; \ consumed_myself += num; \
} while(0) } while(0)
/*
* Decode the XER (XML) data.
*/
asn_dec_rval_t asn_dec_rval_t
SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
void **struct_ptr, const char *opt_mname, void **struct_ptr, const char *opt_mname,
...@@ -604,17 +608,18 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, ...@@ -604,17 +608,18 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
/* /*
* Bring closer parts of structure description. * Bring closer parts of structure description.
*/ */
asn_SEQUENCE_specifics_t *specs = (asn_SEQUENCE_specifics_t *)td->specifics; asn_SEQUENCE_specifics_t *specs
= (asn_SEQUENCE_specifics_t *)td->specifics;
asn_TYPE_member_t *elements = td->elements; asn_TYPE_member_t *elements = td->elements;
const char *xml_tag = opt_mname ? opt_mname : td->xml_tag; const char *xml_tag = opt_mname ? opt_mname : td->xml_tag;
/* /*
* Parts of the structure being constructed. * ... and parts of the structure being constructed.
*/ */
void *st = *struct_ptr; /* Target structure. */ void *st = *struct_ptr; /* Target structure. */
asn_struct_ctx_t *ctx; /* Decoder context */ asn_struct_ctx_t *ctx; /* Decoder context */
asn_dec_rval_t rval; asn_dec_rval_t rval; /* Return value from a decoder */
ssize_t consumed_myself = 0; /* Consumed bytes from ptr */ ssize_t consumed_myself = 0; /* Consumed bytes from ptr */
int xer_state; /* XER low level parsing context */ int xer_state; /* XER low level parsing context */
int edx; /* Element index */ int edx; /* Element index */
...@@ -639,16 +644,14 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, ...@@ -639,16 +644,14 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
* Phase 1: Processing body and reacting on closing tag. * Phase 1: Processing body and reacting on closing tag.
* Phase 2: Processing inner type. * Phase 2: Processing inner type.
*/ */
for(xer_state = ctx->left, edx = ctx->step; ctx->phase <= 2;) {
if(ctx->phase > 2) RETURN(RC_FAIL);
for(xer_state = ctx->left, edx = ctx->step;;) {
pxer_chunk_type_e ch_type; /* XER chunk type */ pxer_chunk_type_e ch_type; /* XER chunk type */
ssize_t ch_size; /* Chunk size */ ssize_t ch_size; /* Chunk size */
xer_check_tag_e tcv; /* Tag check value */ xer_check_tag_e tcv; /* Tag check value */
asn_TYPE_member_t *elm; asn_TYPE_member_t *elm;
/* /*
* Go inside the member. * Go inside the inner member of a sequence.
*/ */
if(ctx->phase == 2) { if(ctx->phase == 2) {
asn_dec_rval_t tmprval; asn_dec_rval_t tmprval;
...@@ -666,15 +669,18 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, ...@@ -666,15 +669,18 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
memb_ptr2 = &memb_ptr; memb_ptr2 = &memb_ptr;
} }
/* Invoke the inner type decoder, m.b. multiple times */
tmprval = elm->type->xer_decoder(opt_codec_ctx, tmprval = elm->type->xer_decoder(opt_codec_ctx,
elm->type, memb_ptr2, elm->name, elm->type, memb_ptr2, elm->name,
buf_ptr, size); buf_ptr, size);
XER_ADVANCE(tmprval.consumed); XER_ADVANCE(tmprval.consumed);
if(tmprval.code != RC_OK) if(tmprval.code != RC_OK)
RETURN(tmprval.code); RETURN(tmprval.code);
ctx->phase = 1; ctx->phase = 1; /* Back to body processing */
ctx->left = xer_state = 0; /* New, clean state */ ctx->left = xer_state = 0; /* New, clean state */
ctx->step = ++edx; ctx->step = ++edx;
ASN_DEBUG("XER/SEQUENCE phase => %d, step => %d",
ctx->phase, ctx->step);
/* Fall through */ /* Fall through */
} }
...@@ -698,11 +704,11 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, ...@@ -698,11 +704,11 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
} }
} }
tcv = xer_check_tag(buf_ptr, size, xml_tag); tcv = xer_check_tag(buf_ptr, ch_size, xml_tag);
ASN_DEBUG("XER/SEQUENCE: tcv = %d, ph=%d", tcv, ctx->phase);
switch(tcv) { switch(tcv) {
case XCT_CLOSING: case XCT_CLOSING:
if(ctx->phase == 0) break; if(ctx->phase == 0) break;
XER_ADVANCE(ch_size);
ctx->phase = 0; ctx->phase = 0;
/* Fall through */ /* Fall through */
case XCT_BOTH: case XCT_BOTH:
...@@ -720,7 +726,7 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, ...@@ -720,7 +726,7 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
) { ) {
XER_ADVANCE(ch_size); XER_ADVANCE(ch_size);
ctx->phase = 3; /* Phase out */ ctx->phase = 3; /* Phase out */
continue; RETURN(RC_OK);
} else { } else {
ASN_DEBUG("Premature end of XER SEQUENCE"); ASN_DEBUG("Premature end of XER SEQUENCE");
RETURN(RC_FAIL); RETURN(RC_FAIL);
...@@ -738,7 +744,9 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, ...@@ -738,7 +744,9 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
int edx_end; int edx_end;
int n; int n;
if(!ctx->phase ASN_DEBUG("XER/SEQUENCE: tcv=%d, ph=%d",
tcv, ctx->phase);
if(ctx->phase != 1
|| edx >= td->elements_count) || edx >= td->elements_count)
break; /* Really unexpected */ break; /* Really unexpected */
...@@ -748,7 +756,7 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, ...@@ -748,7 +756,7 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
edx_end = edx + elements[edx].optional + 1; edx_end = edx + elements[edx].optional + 1;
for(n = edx; n < edx_end; n++) { for(n = edx; n < edx_end; n++) {
elm = &td->elements[n]; elm = &td->elements[n];
tcv = xer_check_tag(buf_ptr, size, elm->name); tcv = xer_check_tag(buf_ptr,ch_size,elm->name);
switch(tcv) { switch(tcv) {
case XCT_BOTH: case XCT_BOTH:
case XCT_OPENING: case XCT_OPENING:
...@@ -778,7 +786,7 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, ...@@ -778,7 +786,7 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
break; break;
} }
ctx->phase = 3; /* Phase out, just in case */ ctx->phase = 3; /* "Phase out" on hard failure */
RETURN(RC_FAIL); RETURN(RC_FAIL);
} }
......
...@@ -55,9 +55,10 @@ xer_next_token(int *stateContext, void *buffer, size_t size, ...@@ -55,9 +55,10 @@ xer_next_token(int *stateContext, void *buffer, size_t size,
pxer_chunk_type_e *ch_type) { pxer_chunk_type_e *ch_type) {
struct xer__cb_arg arg; struct xer__cb_arg arg;
ssize_t ret; ssize_t ret;
int new_stateContext = *stateContext;
arg.callback_not_invoked = 1; arg.callback_not_invoked = 1;
ret = pxml_parse(stateContext, buffer, size, xer__token_cb, &arg); ret = pxml_parse(&new_stateContext, buffer, size, xer__token_cb, &arg);
if(ret < 0) return -1; if(ret < 0) return -1;
if(arg.callback_not_invoked) { if(arg.callback_not_invoked) {
assert(ret == 0); /* No data was consumed */ assert(ret == 0); /* No data was consumed */
...@@ -84,6 +85,7 @@ xer_next_token(int *stateContext, void *buffer, size_t size, ...@@ -84,6 +85,7 @@ xer_next_token(int *stateContext, void *buffer, size_t size,
break; break;
} }
*stateContext = new_stateContext; /* Update the context */
return arg.chunk_size; return arg.chunk_size;
} }
...@@ -98,6 +100,8 @@ xer_check_tag(const void *buf_ptr, int size, const char *need_tag) { ...@@ -98,6 +100,8 @@ xer_check_tag(const void *buf_ptr, int size, const char *need_tag) {
xer_check_tag_e ct = XCT_OPENING; xer_check_tag_e ct = XCT_OPENING;
if(size < 2 || buf[0] != LANGLE || buf[size-1] != RANGLE) { if(size < 2 || buf[0] != LANGLE || buf[size-1] != RANGLE) {
if(size >= 2)
ASN_DEBUG("Broken XML tag: \"%c...%c\"", buf[0], buf[size - 1]);
return XCT_BROKEN; return XCT_BROKEN;
} }
......
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