Unverified Commit 26bd22ff authored by Mouse's avatar Mouse Committed by GitHub

Merge pull request #151 from v0-e/jer-root-fix

jer: Unwrapped root
parents e74487cd a7aa90c5
...@@ -13,10 +13,6 @@ struct je2v_key { ...@@ -13,10 +13,6 @@ struct je2v_key {
const unsigned int *evmap; const unsigned int *evmap;
}; };
/*
* Some static functions here are equivalent to XER's.
* Should be joined in the future.
*/
static int static int
INTEGER_jer_st_prealloc(INTEGER_t *st, int min_size) { INTEGER_jer_st_prealloc(INTEGER_t *st, int min_size) {
void *p = MALLOC(min_size + 1); void *p = MALLOC(min_size + 1);
......
...@@ -54,52 +54,60 @@ static const struct OCTET_STRING__jer_escape_table_s { ...@@ -54,52 +54,60 @@ static const struct OCTET_STRING__jer_escape_table_s {
int size; int size;
} OCTET_STRING__jer_escape_table[] = { } OCTET_STRING__jer_escape_table[] = {
#define OSXET(s) { s, sizeof(s) - 1 } #define OSXET(s) { s, sizeof(s) - 1 }
OSXET("\074\156\165\154\057\076"), /* <nul/> */ { 0, 0 }, /* NULL */
OSXET("\074\163\157\150\057\076"), /* <soh/> */ { 0, 0 }, /* Start of header */
OSXET("\074\163\164\170\057\076"), /* <stx/> */ { 0, 0 }, /* Start of text */
OSXET("\074\145\164\170\057\076"), /* <etx/> */ { 0, 0 }, /* End of text */
OSXET("\074\145\157\164\057\076"), /* <eot/> */ { 0, 0 }, /* End of transmission */
OSXET("\074\145\156\161\057\076"), /* <enq/> */ { 0, 0 }, /* Enquiry */
OSXET("\074\141\143\153\057\076"), /* <ack/> */ { 0, 0 }, /* Ack */
OSXET("\074\142\145\154\057\076"), /* <bel/> */ { 0, 0 }, /* Bell */
OSXET("\074\142\163\057\076"), /* <bs/> */ OSXET("\134\142"), /* \b */
OSXET("\011"), /* \t */ OSXET("\134\164"), /* \t */
OSXET("\012"), /* \n */ OSXET("\134\156"), /* \n */
OSXET("\074\166\164\057\076"), /* <vt/> */ { 0, 0 }, /* Vertical tab */
OSXET("\074\146\146\057\076"), /* <ff/> */ OSXET("\134\146"), /* \f */
OSXET("\015"), /* \r */ OSXET("\134\162"), /* \r */
OSXET("\074\163\157\057\076"), /* <so/> */ { 0, 0 }, /* Shift out */
OSXET("\074\163\151\057\076"), /* <si/> */ { 0, 0 }, /* Shift in */
OSXET("\074\144\154\145\057\076"), /* <dle/> */ { 0, 0 }, /* Data link escape */
OSXET("\074\144\143\061\057\076"), /* <de1/> */ { 0, 0 }, /* Device control 1 */
OSXET("\074\144\143\062\057\076"), /* <de2/> */ { 0, 0 }, /* Device control 2 */
OSXET("\074\144\143\063\057\076"), /* <de3/> */ { 0, 0 }, /* Device control 3 */
OSXET("\074\144\143\064\057\076"), /* <de4/> */ { 0, 0 }, /* Device control 4 */
OSXET("\074\156\141\153\057\076"), /* <nak/> */ { 0, 0 }, /* Negative ack */
OSXET("\074\163\171\156\057\076"), /* <syn/> */ { 0, 0 }, /* Synchronous idle */
OSXET("\074\145\164\142\057\076"), /* <etb/> */ { 0, 0 }, /* End of transmission block */
OSXET("\074\143\141\156\057\076"), /* <can/> */ { 0, 0 }, /* Cancel */
OSXET("\074\145\155\057\076"), /* <em/> */ { 0, 0 }, /* End of medium */
OSXET("\074\163\165\142\057\076"), /* <sub/> */ { 0, 0 }, /* Substitute */
OSXET("\074\145\163\143\057\076"), /* <esc/> */ { 0, 0 }, /* Escape */
OSXET("\074\151\163\064\057\076"), /* <is4/> */ { 0, 0 }, /* File separator */
OSXET("\074\151\163\063\057\076"), /* <is3/> */ { 0, 0 }, /* Group separator */
OSXET("\074\151\163\062\057\076"), /* <is2/> */ { 0, 0 }, /* Record separator */
OSXET("\074\151\163\061\057\076"), /* <is1/> */ { 0, 0 }, /* Unit separator */
{ 0, 0 }, /* " " */ { 0, 0 }, /* " " */
{ 0, 0 }, /* ! */ { 0, 0 }, /* ! */
{ 0, 0 }, /* \" */ OSXET("\134\042"), /* \" */
{ 0, 0 }, /* # */ { 0, 0 }, /* # */
{ 0, 0 }, /* $ */ { 0, 0 }, /* $ */
{ 0, 0 }, /* % */ { 0, 0 }, /* % */
OSXET("\046\141\155\160\073"), /* &amp; */ { 0, 0 }, /* &amp; */
{ 0, 0 }, /* ' */ { 0, 0 }, /* ' */
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, /* ()*+,-./ */ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, /* ()*+,-./ */
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, /* 01234567 */ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, /* 01234567 */
{0,0},{0,0},{0,0},{0,0}, /* 89:; */ {0,0},{0,0},{0,0},{0,0}, /* 89:; */
OSXET("\046\154\164\073"), /* &lt; */ { 0, 0 }, /* &lt; */
{ 0, 0 }, /* = */ { 0, 0 }, /* = */
OSXET("\046\147\164\073"), /* &gt; */ { 0, 0 }, /* &gt; */
{ 0, 0 }, /* ? */
{ 0, 0 }, /* @ */
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, /* ABCDEFGH */
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, /* IJKLMNOP */
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, /* QRSTUVWX */
{0,0},{0,0}, /* YZ */
{ 0, 0 }, /* [ */
OSXET("\134\134"), /* \\ */
}; };
static int static int
...@@ -166,7 +174,7 @@ OCTET_STRING_encode_jer_utf8(const asn_TYPE_descriptor_t *td, const void *sptr, ...@@ -166,7 +174,7 @@ OCTET_STRING_encode_jer_utf8(const asn_TYPE_descriptor_t *td, const void *sptr,
int s_len; /* Special encoding sequence length */ int s_len; /* Special encoding sequence length */
/* /*
* Escape certain characters: X.680/11.15 * Escape certain characters
*/ */
if(ch < sizeof(OCTET_STRING__jer_escape_table) if(ch < sizeof(OCTET_STRING__jer_escape_table)
/ sizeof(OCTET_STRING__jer_escape_table[0]) / sizeof(OCTET_STRING__jer_escape_table[0])
...@@ -213,6 +221,7 @@ static ssize_t OCTET_STRING__convert_hexadecimal(void *sptr, const void *chunk_b ...@@ -213,6 +221,7 @@ static ssize_t OCTET_STRING__convert_hexadecimal(void *sptr, const void *chunk_b
break; break;
} }
} }
--pend;
for (; pend >= p; --pend) { for (; pend >= p; --pend) {
if (*pend == CQUOTE) if (*pend == CQUOTE)
break; break;
...@@ -269,7 +278,7 @@ static ssize_t OCTET_STRING__convert_hexadecimal(void *sptr, const void *chunk_b ...@@ -269,7 +278,7 @@ static ssize_t OCTET_STRING__convert_hexadecimal(void *sptr, const void *chunk_b
if(have_more) { if(have_more) {
/* /*
* Partial specification is fine, * Partial specification is fine,
* because no more more PXER_TEXT data is available. * because no more more PJER_TEXT data is available.
*/ */
*buf++ = clv << 4; *buf++ = clv << 4;
chunk_stop = p; chunk_stop = p;
...@@ -329,7 +338,7 @@ OS__strtoent(int base, const char *buf, const char *end, int32_t *ret_value) { ...@@ -329,7 +338,7 @@ OS__strtoent(int base, const char *buf, const char *end, int32_t *ret_value) {
} }
/* /*
* Convert from the plain UTF-8 format, expanding entity references: "2 &lt; 3" * Convert from the plain UTF-8 format
*/ */
static ssize_t static ssize_t
OCTET_STRING__convert_entrefs(void *sptr, const void *chunk_buf, OCTET_STRING__convert_entrefs(void *sptr, const void *chunk_buf,
...@@ -346,6 +355,7 @@ OCTET_STRING__convert_entrefs(void *sptr, const void *chunk_buf, ...@@ -346,6 +355,7 @@ OCTET_STRING__convert_entrefs(void *sptr, const void *chunk_buf,
break; break;
} }
} }
--pend;
for(; pend >= p; --pend) { for(; pend >= p; --pend) {
if (*pend == CQUOTE) if (*pend == CQUOTE)
break; break;
...@@ -367,7 +377,7 @@ OCTET_STRING__convert_entrefs(void *sptr, const void *chunk_buf, ...@@ -367,7 +377,7 @@ OCTET_STRING__convert_entrefs(void *sptr, const void *chunk_buf,
int ch = *(const unsigned char *)p; int ch = *(const unsigned char *)p;
int len; /* Length of the rest of the chunk */ int len; /* Length of the rest of the chunk */
if(ch != 0x26 /* '&' */) { if(ch != 0x5c /* '\' */) {
*buf++ = ch; *buf++ = ch;
continue; /* That was easy... */ continue; /* That was easy... */
} }
...@@ -376,8 +386,10 @@ OCTET_STRING__convert_entrefs(void *sptr, const void *chunk_buf, ...@@ -376,8 +386,10 @@ OCTET_STRING__convert_entrefs(void *sptr, const void *chunk_buf,
* Process entity reference. * Process entity reference.
*/ */
len = chunk_size - (p - (const char *)chunk_buf); len = chunk_size - (p - (const char *)chunk_buf);
if(len == 1 /* "&" */) goto want_more; if(len == 1 /* "\" */) goto want_more;
if(p[1] == 0x23 /* '#' */) { switch(p[1]) {
case 0x75: /* 'u' */
;
const char *pval; /* Pointer to start of digits */ const char *pval; /* Pointer to start of digits */
int32_t val = 0; /* Entity reference value */ int32_t val = 0; /* Entity reference value */
int base; int base;
...@@ -425,43 +437,41 @@ OCTET_STRING__convert_entrefs(void *sptr, const void *chunk_buf, ...@@ -425,43 +437,41 @@ OCTET_STRING__convert_entrefs(void *sptr, const void *chunk_buf,
*buf++ = 0x80 | ((val >> 6) & 0x3f); *buf++ = 0x80 | ((val >> 6) & 0x3f);
*buf++ = 0x80 | ((val & 0x3f)); *buf++ = 0x80 | ((val & 0x3f));
} }
} else { break;
/* case 0x22: /* " */
* Ugly, limited parsing of &amp; &gt; &lt; *buf++ = 0x22;
*/ ++p;
char *sc = (char *)memchr(p, 0x3b, len > 5 ? 5 : len); break;
if(!sc) goto want_more; case 0x5c: /* \ */
if((sc - p) == 4 *buf++ = 0x5c;
&& p[1] == 0x61 /* 'a' */ ++p;
&& p[2] == 0x6d /* 'm' */ break;
&& p[3] == 0x70 /* 'p' */) { case 0x62: /* b */
*buf++ = 0x26; *buf++ = 0x08;
p = sc; ++p;
continue; break;
} case 0x66: /* f */
if((sc - p) == 3) { *buf++ = 0x0c;
if(p[1] == 0x6c) { ++p;
*buf = 0x3c; /* '<' */ break;
} else if(p[1] == 0x67) { case 0x6e: /* n */
*buf = 0x3e; /* '>' */ *buf++ = 0x0a;
} else { ++p;
/* Unsupported entity reference */ break;
*buf++ = ch; case 0x72: /* r */
continue; *buf++ = 0x0d;
} ++p;
if(p[2] != 0x74) { break;
/* Unsupported entity reference */ case 0x74: /* t */
*buf++ = ch; *buf++ = 0x09;
continue; ++p;
} break;
buf++; default:
p = sc;
continue;
}
/* Unsupported entity reference */ /* Unsupported entity reference */
*buf++ = ch; *buf++ = ch;
++p;
continue;
} }
continue; continue;
want_more: want_more:
if(have_more) { if(have_more) {
...@@ -485,7 +495,7 @@ OCTET_STRING__convert_entrefs(void *sptr, const void *chunk_buf, ...@@ -485,7 +495,7 @@ OCTET_STRING__convert_entrefs(void *sptr, const void *chunk_buf,
} }
/* /*
* Decode OCTET STRING from the XML element's body. * Decode OCTET STRING from the JSON element's value.
*/ */
static asn_dec_rval_t static asn_dec_rval_t
OCTET_STRING__decode_jer( OCTET_STRING__decode_jer(
......
...@@ -65,20 +65,23 @@ OPEN_TYPE_jer_get(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -65,20 +65,23 @@ OPEN_TYPE_jer_get(const asn_codec_ctx_t *opt_codec_ctx,
case PJER_WMORE: case PJER_WMORE:
ASN__DECODE_STARVED; ASN__DECODE_STARVED;
case PJER_TEXT: case PJER_TEXT:
case PJER_DLM:
ADVANCE(ch_size); ADVANCE(ch_size);
continue; continue;
case PJER_KEY:
default: default:
break; break;
} }
break; break;
} }
} }
/* /*
* Wrapper value confirmed. * Wrapper value confirmed.
*/ */
switch(jer_check_sym(ptr, ch_size, elm->name)) { switch(jer_check_sym(ptr, ch_size, NULL)) {
case JCK_KEY: case JCK_UNKNOWN:
ADVANCE(ch_size); ADVANCE(ch_size);
break; break;
case JCK_BROKEN: case JCK_BROKEN:
...@@ -86,9 +89,10 @@ OPEN_TYPE_jer_get(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -86,9 +89,10 @@ OPEN_TYPE_jer_get(const asn_codec_ctx_t *opt_codec_ctx,
ASN__DECODE_FAILED; ASN__DECODE_FAILED;
} }
/* Skip colon */ /* Skip colon */
ch_size = jer_next_token(&jer_context, ptr, size, &ch_type); ch_size = jer_next_token(&jer_context, ptr, size, &ch_type);
if(ch_size < 0 || ch_type != PJER_DLM) { if(ch_size < 0 || ch_type != PJER_TEXT) {
ASN__DECODE_FAILED; ASN__DECODE_FAILED;
} else { } else {
ADVANCE(ch_size); ADVANCE(ch_size);
......
...@@ -29,6 +29,7 @@ RELATIVE_OID__jer_body_decode(const asn_TYPE_descriptor_t *td, void *sptr, ...@@ -29,6 +29,7 @@ RELATIVE_OID__jer_body_decode(const asn_TYPE_descriptor_t *td, void *sptr,
break; break;
} }
} }
--chunk_end;
for (; chunk_end >= p; --chunk_end) { for (; chunk_end >= p; --chunk_end) {
if (*chunk_end == CQUOTE) if (*chunk_end == CQUOTE)
break; break;
......
...@@ -71,6 +71,7 @@ UniversalString_encode_jer(const asn_TYPE_descriptor_t *td, const void *sptr, ...@@ -71,6 +71,7 @@ UniversalString_encode_jer(const asn_TYPE_descriptor_t *td, const void *sptr,
asn_app_consume_bytes_f *cb, void *app_key) { asn_app_consume_bytes_f *cb, void *app_key) {
const UniversalString_t *st = (const UniversalString_t *)sptr; const UniversalString_t *st = (const UniversalString_t *)sptr;
asn_enc_rval_t er = {0,0,0}; asn_enc_rval_t er = {0,0,0};
ssize_t ro_encoded = 0;
(void)ilevel; (void)ilevel;
(void)flags; (void)flags;
...@@ -78,8 +79,12 @@ UniversalString_encode_jer(const asn_TYPE_descriptor_t *td, const void *sptr, ...@@ -78,8 +79,12 @@ UniversalString_encode_jer(const asn_TYPE_descriptor_t *td, const void *sptr,
if(!st || !st->buf) if(!st || !st->buf)
ASN__ENCODE_FAILED; ASN__ENCODE_FAILED;
er.encoded = UniversalString__dump(st, cb, app_key); ASN__CALLBACK("\"", 1);
if(er.encoded < 0) ASN__ENCODE_FAILED; ro_encoded = UniversalString__dump(st, cb, app_key);
if(ro_encoded < 0) goto cb_failed;
er.encoded += ro_encoded;
ASN__CALLBACK("\"", 1);
cb_failed:
ASN__ENCODED_OK(er); ASN__ENCODED_OK(er);
} }
...@@ -26,23 +26,6 @@ ...@@ -26,23 +26,6 @@
consumed_myself += num; \ consumed_myself += num; \
} while(0) } while(0)
#undef JER_SAVE_STATE
#define JER_SAVE_STATE \
do { \
buf_ptr0 = buf_ptr; \
size0 = size; \
consumed_myself0 = consumed_myself; \
context0 = ctx->context; \
} while(0)
#undef JER_RESTORE_STATE
#define JER_RESTORE_STATE \
do { \
buf_ptr = buf_ptr0; \
size = size0; \
consumed_myself = consumed_myself0; \
ctx->context = context0; \
} while(0)
/* /*
* Decode the JER (JSON) data. * Decode the JER (JSON) data.
*/ */
...@@ -54,7 +37,6 @@ CHOICE_decode_jer(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -54,7 +37,6 @@ CHOICE_decode_jer(const asn_codec_ctx_t *opt_codec_ctx,
* Bring closer parts of structure description. * Bring closer parts of structure description.
*/ */
const asn_CHOICE_specifics_t *specs = (const asn_CHOICE_specifics_t *)td->specifics; const asn_CHOICE_specifics_t *specs = (const asn_CHOICE_specifics_t *)td->specifics;
const char *json_key = opt_mname ? opt_mname : td->xml_tag;
/* /*
* Parts of the structure being constructed. * Parts of the structure being constructed.
...@@ -65,7 +47,6 @@ CHOICE_decode_jer(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -65,7 +47,6 @@ CHOICE_decode_jer(const asn_codec_ctx_t *opt_codec_ctx,
asn_dec_rval_t rval; /* Return value of a decoder */ 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 */
size_t edx; /* Element index */ size_t edx; /* Element index */
int skip_outer = 0; /* Skip outer layer */
/* /*
* Create the target structure if it is not present already. * Create the target structure if it is not present already.
...@@ -79,23 +60,13 @@ CHOICE_decode_jer(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -79,23 +60,13 @@ CHOICE_decode_jer(const asn_codec_ctx_t *opt_codec_ctx,
* Restore parsing context. * Restore parsing context.
*/ */
ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset); ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
if(ctx->phase == 0 && !*json_key) {
/* Skip the outer key checking phase */
ctx->phase = 1;
skip_outer = 1;
}
const void* buf_ptr0 = buf_ptr;
size_t size0 = size;
ssize_t consumed_myself0 = consumed_myself; /* Consumed bytes from ptr */
int context0 = ctx->context;
/* /*
* Phases of JER/JSON processing: * Phases of JER/JSON processing:
* Phase 0: Check that the opening key matches our expectations. * Phase 0: Check that the opening key matches our expectations.
* Phase 1: Processing body and reacting on closing key. * Phase 1: Processing body and reacting on closing token.
* Phase 2: Processing inner type. * Phase 2: Processing inner type.
* Phase 3: Only waiting for closing key. * Phase 3: Only waiting for closing token.
* Phase 4: Skipping unknown extensions. * Phase 4: Skipping unknown extensions.
* Phase 5: PHASED OUT * Phase 5: PHASED OUT
*/ */
...@@ -147,14 +118,8 @@ CHOICE_decode_jer(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -147,14 +118,8 @@ CHOICE_decode_jer(const asn_codec_ctx_t *opt_codec_ctx,
/* Fall through */ /* Fall through */
} }
/* No need to wait for closing key; special mode. */
if(ctx->phase == 3 && !*json_key) {
ctx->phase = 5; /* Phase out */
RETURN(RC_OK);
}
/* /*
* Get the next part of the XML stream. * Get the next part of the JSON stream.
*/ */
ch_size = jer_next_token(&ctx->context, buf_ptr, size, &ch_type); ch_size = jer_next_token(&ctx->context, buf_ptr, size, &ch_type);
if(ch_size == -1) { if(ch_size == -1) {
...@@ -175,7 +140,7 @@ CHOICE_decode_jer(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -175,7 +140,7 @@ CHOICE_decode_jer(const asn_codec_ctx_t *opt_codec_ctx,
} }
} }
scv = jer_check_sym(buf_ptr, ch_size, ctx->phase == 0 ? json_key : NULL); scv = jer_check_sym(buf_ptr, ch_size, NULL);
ASN_DEBUG("JER/CHOICE checked [%c%c%c%c] vs [%s], scv=%d", ASN_DEBUG("JER/CHOICE checked [%c%c%c%c] vs [%s], scv=%d",
ch_size>0?((const uint8_t *)buf_ptr)[0]:'?', ch_size>0?((const uint8_t *)buf_ptr)[0]:'?',
ch_size>1?((const uint8_t *)buf_ptr)[1]:'?', ch_size>1?((const uint8_t *)buf_ptr)[1]:'?',
...@@ -210,42 +175,23 @@ CHOICE_decode_jer(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -210,42 +175,23 @@ CHOICE_decode_jer(const asn_codec_ctx_t *opt_codec_ctx,
JER_ADVANCE(ch_size); JER_ADVANCE(ch_size);
ctx->phase = 5; /* Phase out */ ctx->phase = 5; /* Phase out */
RETURN(RC_OK); RETURN(RC_OK);
case JCK_KEY:
case JCK_COMMA: case JCK_COMMA:
JER_ADVANCE(ch_size);
continue;
case JCK_OSTART:
if(ctx->phase == 0) { if(ctx->phase == 0) {
JER_ADVANCE(ch_size); JER_ADVANCE(ch_size);
ctx->phase = 1; /* Processing body phase */ ctx->phase = 1; /* Processing body phase */
continue; continue;
} }
/* Fall through */ case JCK_KEY:
case JCK_UNKNOWN: case JCK_UNKNOWN:
case JCK_OSTART:
if(ctx->phase != 1) if(ctx->phase != 1)
break; /* Really unexpected */ break; /* Really unexpected */
if (!skip_outer) {
JER_ADVANCE(ch_size); /* Skip silently */
// Save state
JER_SAVE_STATE; /* We have to look inside the object to see which
* key (choice) is present */
ctx->context = 0;
ch_size = jer_next_token(&ctx->context, buf_ptr, size, &ch_type);
if(ch_size == -1) {
RETURN(RC_FAIL);
}
if (ch_type != PJER_KEY) {
JER_ADVANCE(ch_size); /* Skip silently */
ch_size = jer_next_token(&ctx->context, buf_ptr, size, &ch_type);
if(ch_size == -1) {
RETURN(RC_FAIL);
}
}
}
/* /*
* Search which inner member corresponds to this key. * Search which inner member corresponds to this key.
*/ */
...@@ -259,6 +205,23 @@ CHOICE_decode_jer(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -259,6 +205,23 @@ CHOICE_decode_jer(const asn_codec_ctx_t *opt_codec_ctx,
*/ */
ctx->step = edx; ctx->step = edx;
ctx->phase = 2; ctx->phase = 2;
JER_ADVANCE(ch_size); /* skip key */
/* skip colon */
ch_size = jer_next_token(&ctx->context, buf_ptr, size,
&ch_type);
if(ch_size == -1) {
RETURN(RC_FAIL);
} else {
switch(ch_type) {
case PJER_WMORE:
RETURN(RC_WMORE);
case PJER_TEXT:
JER_ADVANCE(ch_size);
break;
default:
RETURN(RC_FAIL);
}
}
break; break;
case JCK_UNKNOWN: case JCK_UNKNOWN:
continue; continue;
...@@ -268,9 +231,6 @@ CHOICE_decode_jer(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -268,9 +231,6 @@ CHOICE_decode_jer(const asn_codec_ctx_t *opt_codec_ctx,
} }
break; break;
} }
if (!skip_outer) {
JER_RESTORE_STATE;
}
if(edx != td->elements_count) if(edx != td->elements_count)
continue; continue;
...@@ -346,7 +306,6 @@ CHOICE_encode_jer(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, ...@@ -346,7 +306,6 @@ CHOICE_encode_jer(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
er.encoded += tmper.encoded; er.encoded += tmper.encoded;
ASN__CALLBACK("}", 1); ASN__CALLBACK("}", 1);
// ASN__CALLBACK3("</", 2, mname, mlen, ">", 1);
} }
ASN__ENCODED_OK(er); ASN__ENCODED_OK(er);
......
...@@ -15,10 +15,6 @@ SEQUENCE_OF_encode_jer(const asn_TYPE_descriptor_t *td, const void *sptr, ...@@ -15,10 +15,6 @@ SEQUENCE_OF_encode_jer(const asn_TYPE_descriptor_t *td, const void *sptr,
const asn_SET_OF_specifics_t *specs = (const asn_SET_OF_specifics_t *)td->specifics; const asn_SET_OF_specifics_t *specs = (const asn_SET_OF_specifics_t *)td->specifics;
const asn_TYPE_member_t *elm = td->elements; const asn_TYPE_member_t *elm = td->elements;
const asn_anonymous_sequence_ *list = _A_CSEQUENCE_FROM_VOID(sptr); const asn_anonymous_sequence_ *list = _A_CSEQUENCE_FROM_VOID(sptr);
const char *mname = specs->as_XMLValueList
? 0
: ((*elm->name) ? elm->name : elm->type->xml_tag);
size_t mlen = mname ? strlen(mname) : 0;
int xcan = 0; int xcan = 0;
int i; int i;
...@@ -32,11 +28,6 @@ SEQUENCE_OF_encode_jer(const asn_TYPE_descriptor_t *td, const void *sptr, ...@@ -32,11 +28,6 @@ SEQUENCE_OF_encode_jer(const asn_TYPE_descriptor_t *td, const void *sptr,
void *memb_ptr = list->array[i]; void *memb_ptr = list->array[i];
if(!memb_ptr) continue; if(!memb_ptr) continue;
if(mname) {
if(!xcan) ASN__TEXT_INDENT(1, ilevel);
ASN__CALLBACK3("{\"", 2, mname, mlen, "\":", 2);
}
tmper = elm->type->op->jer_encoder(elm->type, memb_ptr, ilevel + 1, tmper = elm->type->op->jer_encoder(elm->type, memb_ptr, ilevel + 1,
flags, cb, app_key); flags, cb, app_key);
if(tmper.encoded == -1) return tmper; if(tmper.encoded == -1) return tmper;
...@@ -48,9 +39,6 @@ SEQUENCE_OF_encode_jer(const asn_TYPE_descriptor_t *td, const void *sptr, ...@@ -48,9 +39,6 @@ SEQUENCE_OF_encode_jer(const asn_TYPE_descriptor_t *td, const void *sptr,
ASN__CALLBACK3("\"", 1, name, len, "\"", 1); ASN__CALLBACK3("\"", 1, name, len, "\"", 1);
} }
if(mname) {
ASN__CALLBACK("}", 1);
}
if (i != list->count - 1) { if (i != list->count - 1) {
ASN__CALLBACK(",", 1); ASN__CALLBACK(",", 1);
} }
......
...@@ -34,22 +34,6 @@ ...@@ -34,22 +34,6 @@
consumed_myself += num; \ consumed_myself += num; \
} while(0) } while(0)
#define JER_SAVE_STATE \
do { \
ptr0 = ptr; \
size0 = size; \
consumed_myself0 = consumed_myself; \
context0 = ctx->context;\
} while(0)
#define JER_RESTORE_STATE \
do { \
ptr = ptr0; \
size = size0; \
consumed_myself = consumed_myself0; \
ctx->context = context0; \
} while(0)
/* /*
* Decode the JER (JSON) data. * Decode the JER (JSON) data.
*/ */
...@@ -63,7 +47,6 @@ SEQUENCE_decode_jer(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -63,7 +47,6 @@ SEQUENCE_decode_jer(const asn_codec_ctx_t *opt_codec_ctx,
const asn_SEQUENCE_specifics_t *specs const asn_SEQUENCE_specifics_t *specs
= (const asn_SEQUENCE_specifics_t *)td->specifics; = (const asn_SEQUENCE_specifics_t *)td->specifics;
asn_TYPE_member_t *elements = td->elements; asn_TYPE_member_t *elements = td->elements;
const char *json_key = opt_mname ? opt_mname : td->xml_tag;
/* /*
* ... and parts of the structure being constructed. * ... and parts of the structure being constructed.
...@@ -88,15 +71,10 @@ SEQUENCE_decode_jer(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -88,15 +71,10 @@ SEQUENCE_decode_jer(const asn_codec_ctx_t *opt_codec_ctx,
*/ */
ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset); ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
const void* ptr0 = ptr;
size_t size0 = size;
ssize_t consumed_myself0 = consumed_myself; /* Consumed bytes from ptr */
int context0 = ctx->context;
/* /*
* Phases of JER/JSON processing: * Phases of JER/JSON processing:
* Phase 0: Check that the key matches our expectations. * Phase 0: Check that the key matches our expectations.
* Phase 1: Processing body and reacting on closing key. * Phase 1: Processing body and reacting on closing token.
* Phase 2: Processing inner type. * Phase 2: Processing inner type.
* Phase 3: Skipping unknown extensions. * Phase 3: Skipping unknown extensions.
* Phase 4: PHASED OUT * Phase 4: PHASED OUT
...@@ -166,7 +144,7 @@ SEQUENCE_decode_jer(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -166,7 +144,7 @@ SEQUENCE_decode_jer(const asn_codec_ctx_t *opt_codec_ctx,
} }
} }
scv = jer_check_sym(ptr, ch_size, ctx->phase == 0 ? json_key : NULL); scv = jer_check_sym(ptr, ch_size, NULL);
ASN_DEBUG("JER/SEQUENCE: scv = %d, ph=%d [%s]", ASN_DEBUG("JER/SEQUENCE: scv = %d, ph=%d [%s]",
scv, ctx->phase, json_key); scv, ctx->phase, json_key);
...@@ -194,7 +172,6 @@ SEQUENCE_decode_jer(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -194,7 +172,6 @@ SEQUENCE_decode_jer(const asn_codec_ctx_t *opt_codec_ctx,
case JCK_OEND: case JCK_OEND:
if(ctx->phase == 0) break; if(ctx->phase == 0) break;
ctx->phase = 0; ctx->phase = 0;
/* Fall through */
if(edx >= td->elements_count || if(edx >= td->elements_count ||
/* Explicit OPTIONAL specs reaches the end */ /* Explicit OPTIONAL specs reaches the end */
...@@ -202,15 +179,18 @@ SEQUENCE_decode_jer(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -202,15 +179,18 @@ SEQUENCE_decode_jer(const asn_codec_ctx_t *opt_codec_ctx,
/* All extensions are optional */ /* All extensions are optional */
IN_EXTENSION_GROUP(specs, edx)) { IN_EXTENSION_GROUP(specs, edx)) {
JER_ADVANCE(ch_size); JER_ADVANCE(ch_size);
JER_ADVANCE(jer_whitespace_span(ptr, size));
ctx->phase = 4; /* Phase out */ ctx->phase = 4; /* Phase out */
RETURN(RC_OK); RETURN(RC_OK);
} else { } else {
ASN_DEBUG("Premature end of JER SEQUENCE"); ASN_DEBUG("Premature end of JER SEQUENCE");
RETURN(RC_FAIL); RETURN(RC_FAIL);
} }
/* Fall through */
case JCK_KEY:
case JCK_COMMA: case JCK_COMMA:
ADVANCE(ch_size);
continue;
/* Fall through */
case JCK_OSTART: /* '{' */
if(ctx->phase == 0) { if(ctx->phase == 0) {
JER_ADVANCE(ch_size); JER_ADVANCE(ch_size);
ctx->phase = 1; /* Processing body phase */ ctx->phase = 1; /* Processing body phase */
...@@ -218,8 +198,8 @@ SEQUENCE_decode_jer(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -218,8 +198,8 @@ SEQUENCE_decode_jer(const asn_codec_ctx_t *opt_codec_ctx,
} }
/* Fall through */ /* Fall through */
case JCK_KEY:
case JCK_UNKNOWN: case JCK_UNKNOWN:
case JCK_OSTART:
ASN_DEBUG("JER/SEQUENCE: scv=%d, ph=%d, edx=%" ASN_PRI_SIZE "", ASN_DEBUG("JER/SEQUENCE: scv=%d, ph=%d, edx=%" ASN_PRI_SIZE "",
scv, ctx->phase, edx); scv, ctx->phase, edx);
if(ctx->phase != 1) { if(ctx->phase != 1) {
...@@ -232,26 +212,9 @@ SEQUENCE_decode_jer(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -232,26 +212,9 @@ SEQUENCE_decode_jer(const asn_codec_ctx_t *opt_codec_ctx,
} }
if(edx < td->elements_count) { if(edx < td->elements_count) {
JER_ADVANCE(ch_size);
/* /*
* We have to check which member is next. * We have to check which member is next.
*/ */
JER_SAVE_STATE;
ctx->context = 0;
ch_size = jer_next_token(&ctx->context, ptr, size, &ch_type);
if(ch_size == -1) {
RETURN(RC_FAIL);
}
if(ch_type != PJER_KEY) {
JER_ADVANCE(ch_size); /* Skip silently */
ch_size = jer_next_token(&ctx->context, ptr, size, &ch_type);
if(ch_size == -1) {
RETURN(RC_FAIL);
}
}
size_t n; size_t n;
size_t edx_end = edx + elements[edx].optional + 1; size_t edx_end = edx + elements[edx].optional + 1;
if(edx_end > td->elements_count) { if(edx_end > td->elements_count) {
...@@ -265,6 +228,24 @@ SEQUENCE_decode_jer(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -265,6 +228,24 @@ SEQUENCE_decode_jer(const asn_codec_ctx_t *opt_codec_ctx,
case JCK_KEY: case JCK_KEY:
ctx->step = edx = n; ctx->step = edx = n;
ctx->phase = 2; ctx->phase = 2;
ADVANCE(ch_size); /* skip key */
/* skip colon */
ch_size = jer_next_token(&ctx->context, ptr, size,
&ch_type);
if(ch_size == -1) {
RETURN(RC_FAIL);
} else {
switch(ch_type) {
case PJER_WMORE:
RETURN(RC_WMORE);
case PJER_TEXT:
JER_ADVANCE(ch_size);
break;
default:
RETURN(RC_FAIL);
}
}
break; break;
case JCK_UNKNOWN: case JCK_UNKNOWN:
continue; continue;
...@@ -274,7 +255,6 @@ SEQUENCE_decode_jer(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -274,7 +255,6 @@ SEQUENCE_decode_jer(const asn_codec_ctx_t *opt_codec_ctx,
} }
break; break;
} }
JER_RESTORE_STATE;
if(n != edx_end) if(n != edx_end)
continue; continue;
} else { } else {
...@@ -299,7 +279,7 @@ SEQUENCE_decode_jer(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -299,7 +279,7 @@ SEQUENCE_decode_jer(const asn_codec_ctx_t *opt_codec_ctx,
break; break;
} }
ASN_DEBUG("Unexpected XML key in SEQUENCE [%c%c%c%c%c%c]", ASN_DEBUG("Unexpected JSON key in SEQUENCE [%c%c%c%c%c%c]",
size>0?((const char *)ptr)[0]:'.', size>0?((const char *)ptr)[0]:'.',
size>1?((const char *)ptr)[1]:'.', size>1?((const char *)ptr)[1]:'.',
size>2?((const char *)ptr)[2]:'.', size>2?((const char *)ptr)[2]:'.',
......
...@@ -39,7 +39,6 @@ SET_OF_decode_jer(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -39,7 +39,6 @@ SET_OF_decode_jer(const asn_codec_ctx_t *opt_codec_ctx,
const asn_SET_OF_specifics_t *specs = (const asn_SET_OF_specifics_t *)td->specifics; const asn_SET_OF_specifics_t *specs = (const asn_SET_OF_specifics_t *)td->specifics;
const asn_TYPE_member_t *element = td->elements; const asn_TYPE_member_t *element = td->elements;
const char *elm_tag; const char *elm_tag;
const char *json_key = opt_mname ? opt_mname : td->xml_tag;
/* /*
* ... and parts of the structure being constructed. * ... and parts of the structure being constructed.
...@@ -74,7 +73,7 @@ SET_OF_decode_jer(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -74,7 +73,7 @@ SET_OF_decode_jer(const asn_codec_ctx_t *opt_codec_ctx,
/* /*
* Phases of JER/JSON processing: * Phases of JER/JSON processing:
* Phase 0: Check that the opening tag matches our expectations. * Phase 0: Check that the opening tag matches our expectations.
* Phase 1: Processing body and reacting on closing tag. * Phase 1: Processing body and reacting on closing token.
* Phase 2: Processing inner type. * Phase 2: Processing inner type.
*/ */
for(; ctx->phase <= 2;) { for(; ctx->phase <= 2;) {
...@@ -104,12 +103,6 @@ SET_OF_decode_jer(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -104,12 +103,6 @@ SET_OF_decode_jer(const asn_codec_ctx_t *opt_codec_ctx,
JER_ADVANCE(tmprval.consumed); JER_ADVANCE(tmprval.consumed);
RETURN(tmprval.code); RETURN(tmprval.code);
} }
JER_ADVANCE(jer_whitespace_span(buf_ptr, size));
if(((const char*)buf_ptr)[0] != ']') {
ch_size = jer_next_token(&ctx->context, buf_ptr, size,
&ch_type);
JER_ADVANCE(ch_size);
}
ctx->phase = 1; /* Back to body processing */ ctx->phase = 1; /* Back to body processing */
ASN_DEBUG("JER/SET OF phase => %d", ctx->phase); ASN_DEBUG("JER/SET OF phase => %d", ctx->phase);
...@@ -117,7 +110,7 @@ SET_OF_decode_jer(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -117,7 +110,7 @@ SET_OF_decode_jer(const asn_codec_ctx_t *opt_codec_ctx,
} }
/* /*
* Get the next part of the XML stream. * Get the next part of the JSON stream.
*/ */
ch_size = jer_next_token(&ctx->context, ch_size = jer_next_token(&ctx->context,
buf_ptr, size, &ch_type); buf_ptr, size, &ch_type);
...@@ -127,8 +120,8 @@ SET_OF_decode_jer(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -127,8 +120,8 @@ SET_OF_decode_jer(const asn_codec_ctx_t *opt_codec_ctx,
switch(ch_type) { switch(ch_type) {
case PJER_WMORE: case PJER_WMORE:
RETURN(RC_WMORE); RETURN(RC_WMORE);
case PJER_TEXT: /* Got XML comment */ case PJER_TEXT:
JER_ADVANCE(ch_size); /* Skip silently */ JER_ADVANCE(ch_size);
continue; continue;
case PJER_DLM: case PJER_DLM:
...@@ -138,12 +131,10 @@ SET_OF_decode_jer(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -138,12 +131,10 @@ SET_OF_decode_jer(const asn_codec_ctx_t *opt_codec_ctx,
} }
} }
scv = jer_check_sym(buf_ptr, ch_size, ctx->phase == 0 ? json_key : NULL); scv = jer_check_sym(buf_ptr, ch_size, NULL);
ASN_DEBUG("JER/SET OF: scv = %d, ph=%d t=%s", ASN_DEBUG("JER/SET OF: scv = %d, ph=%d t=%s",
scv, ctx->phase, json_key); scv, ctx->phase, json_key);
switch(scv) { switch(scv) {
case JCK_ASTART:
continue;
case JCK_AEND: case JCK_AEND:
if(ctx->phase == 0) break; if(ctx->phase == 0) break;
ctx->phase = 0; ctx->phase = 0;
...@@ -158,13 +149,10 @@ SET_OF_decode_jer(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -158,13 +149,10 @@ SET_OF_decode_jer(const asn_codec_ctx_t *opt_codec_ctx,
/* Fall through */ /* Fall through */
case JCK_KEY: case JCK_KEY:
case JCK_COMMA: case JCK_COMMA:
case JCK_ASTART:
if(ctx->phase == 0) { if(ctx->phase == 0) {
JER_ADVANCE(ch_size); JER_ADVANCE(ch_size);
if (scv == JCK_KEY) {
ch_size = jer_next_token(&ctx->context, buf_ptr, size,
&ch_type);
JER_ADVANCE(ch_size);
}
ctx->phase = 1; /* Processing body phase */ ctx->phase = 1; /* Processing body phase */
continue; continue;
} }
...@@ -238,9 +226,6 @@ SET_OF_encode_jer(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, ...@@ -238,9 +226,6 @@ SET_OF_encode_jer(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
const asn_SET_OF_specifics_t *specs = (const asn_SET_OF_specifics_t *)td->specifics; const asn_SET_OF_specifics_t *specs = (const asn_SET_OF_specifics_t *)td->specifics;
const asn_TYPE_member_t *elm = td->elements; const asn_TYPE_member_t *elm = td->elements;
const asn_anonymous_set_ *list = _A_CSET_FROM_VOID(sptr); const asn_anonymous_set_ *list = _A_CSET_FROM_VOID(sptr);
const char *mname = specs->as_XMLValueList
? 0 : ((*elm->name) ? elm->name : elm->type->xml_tag);
size_t mlen = mname ? strlen(mname) : 0;
int xcan = 0; int xcan = 0;
jer_tmp_enc_t *encs = 0; jer_tmp_enc_t *encs = 0;
size_t encs_count = 0; size_t encs_count = 0;
...@@ -257,6 +242,7 @@ SET_OF_encode_jer(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, ...@@ -257,6 +242,7 @@ SET_OF_encode_jer(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
} }
er.encoded = 0; er.encoded = 0;
ASN__CALLBACK("[", 1);
for(i = 0; i < list->count; i++) { for(i = 0; i < list->count; i++) {
asn_enc_rval_t tmper = {0,0,0}; asn_enc_rval_t tmper = {0,0,0};
...@@ -270,11 +256,6 @@ SET_OF_encode_jer(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, ...@@ -270,11 +256,6 @@ SET_OF_encode_jer(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
encs_count++; encs_count++;
} }
if(mname) {
if(!xcan) ASN__TEXT_INDENT(1, ilevel);
ASN__CALLBACK3("\"", 1, mname, mlen, "\": ", 3);
}
if(!xcan && specs->as_XMLValueList == 1) if(!xcan && specs->as_XMLValueList == 1)
ASN__TEXT_INDENT(1, ilevel + 1); ASN__TEXT_INDENT(1, ilevel + 1);
tmper = elm->type->op->jer_encoder(elm->type, memb_ptr, tmper = elm->type->op->jer_encoder(elm->type, memb_ptr,
...@@ -285,11 +266,15 @@ SET_OF_encode_jer(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, ...@@ -285,11 +266,15 @@ SET_OF_encode_jer(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
if(tmper.encoded == 0 && specs->as_XMLValueList) { if(tmper.encoded == 0 && specs->as_XMLValueList) {
const char *name = elm->type->xml_tag; const char *name = elm->type->xml_tag;
size_t len = strlen(name); size_t len = strlen(name);
ASN__CALLBACK3("<", 1, name, len, "/>", 2); ASN__CALLBACK3("\"", 1, name, len, "\"", 1);
}
if (i != list->count - 1) {
ASN__CALLBACK(",", 1);
} }
} }
if(!xcan) ASN__TEXT_INDENT(1, ilevel - 1); if(!xcan) ASN__TEXT_INDENT(1, ilevel - 1);
ASN__CALLBACK("]", 1);
if(encs) { if(encs) {
jer_tmp_enc_t *enc = encs; jer_tmp_enc_t *enc = encs;
......
...@@ -283,7 +283,7 @@ SET_decode_jer(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -283,7 +283,7 @@ SET_decode_jer(const asn_codec_ctx_t *opt_codec_ctx,
break; break;
} }
ASN_DEBUG("Unexpected XML key in SEQUENCE [%c%c%c%c%c%c]", ASN_DEBUG("Unexpected JSON key in SEQUENCE [%c%c%c%c%c%c]",
size>0?((const char *)ptr)[0]:'.', size>0?((const char *)ptr)[0]:'.',
size>1?((const char *)ptr)[1]:'.', size>1?((const char *)ptr)[1]:'.',
size>2?((const char *)ptr)[2]:'.', size>2?((const char *)ptr)[2]:'.',
...@@ -350,8 +350,6 @@ SET_encode_jer(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, ...@@ -350,8 +350,6 @@ SET_encode_jer(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
cb, app_key); cb, app_key);
if(tmper.encoded == -1) return tmper; if(tmper.encoded == -1) return tmper;
er.encoded += tmper.encoded; er.encoded += tmper.encoded;
// ASN__CALLBACK3("</", 2, mname, mlen, ">", 1);
} }
if(!xcan) ASN__TEXT_INDENT(1, ilevel - 1); if(!xcan) ASN__TEXT_INDENT(1, ilevel - 1);
......
...@@ -162,6 +162,8 @@ static syntax_selector input_encodings[] = { ...@@ -162,6 +162,8 @@ static syntax_selector input_encodings[] = {
"Input is in Aligned PER (Packed Encoding Rules)"}, "Input is in Aligned PER (Packed Encoding Rules)"},
{"xer", ATS_BASIC_XER, CODEC_OFFSET(xer_decoder), {"xer", ATS_BASIC_XER, CODEC_OFFSET(xer_decoder),
"Input is in XER (XML Encoding Rules)"}, "Input is in XER (XML Encoding Rules)"},
{"jer", ATS_JER, CODEC_OFFSET(jer_decoder),
"Input is in JER (JSON Encoding Rules)"},
{0, ATS_INVALID, 0, 0}}; {0, ATS_INVALID, 0, 0}};
static syntax_selector output_encodings[] = { static syntax_selector output_encodings[] = {
......
...@@ -191,7 +191,7 @@ jer_check_sym(const void *buf_ptr, int size, const char *need_key) { ...@@ -191,7 +191,7 @@ jer_check_sym(const void *buf_ptr, int size, const char *need_key) {
#define JER_GOT_BODY(chunk_buf, chunk_size, size) do { \ #define JER_GOT_BODY(chunk_buf, chunk_size, size) do { \
ssize_t converted_size = body_receiver \ ssize_t converted_size = body_receiver \
(struct_key, chunk_buf, chunk_size, \ (struct_key, chunk_buf, chunk_size, \
(size_t)chunk_size < size); \ (size_t)chunk_size <= size); \
if(converted_size == -1) RETURN(RC_FAIL); \ if(converted_size == -1) RETURN(RC_FAIL); \
if(converted_size == 0 \ if(converted_size == 0 \
&& size == (size_t)chunk_size) \ && size == (size_t)chunk_size) \
...@@ -227,13 +227,12 @@ jer_decode_general(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -227,13 +227,12 @@ jer_decode_general(const asn_codec_ctx_t *opt_codec_ctx,
/* /*
* Phases of jer/JSON processing: * Phases of jer/JSON processing:
* Phase 0: Check that the opening key matches our expectations. * Phase 0: Check that the opening key matches our expectations.
* Phase 1: Processing body and reacting on closing key. * Phase 1: Processing body and reacting on closing token.
*/ */
if(ctx->phase > 1) RETURN(RC_FAIL); if(ctx->phase > 1) RETURN(RC_FAIL);
for(;;) { for(;;) {
pjer_chunk_type_e ch_type; /* jer chunk type */ pjer_chunk_type_e ch_type; /* jer chunk type */
ssize_t ch_size; /* Chunk size */ ssize_t ch_size; /* Chunk size */
jer_check_sym_e scv; /* Symbol check value */
/* /*
* Get the next part of the JSON stream. * Get the next part of the JSON stream.
...@@ -260,30 +259,9 @@ jer_decode_general(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -260,30 +259,9 @@ jer_decode_general(const asn_codec_ctx_t *opt_codec_ctx,
} }
} }
scv = jer_check_sym(buf_ptr, ch_size, ch_type == PJER_KEY ? json_key : NULL); ctx->phase = 2; /* Phase out */
/* RETURN(RC_OK);
* Phase 0:
* Expecting the opening key
* for the type being processed.
* Phase 1:
* Waiting for the closing JSON token.
*/
switch(scv) {
case JCK_KEY:
if(ctx->phase) break;
ADVANCE(ch_size);
ctx->phase = 1; /* Processing body phase */
continue;
case JCK_OEND:
case JCK_AEND:
case JCK_COMMA:
ctx->phase = 2; /* Phase out */
RETURN(RC_OK);
default:
break; /* Unexpected token */
}
ASN_DEBUG("Unexpected JSON key (expected \"%s\")", json_key);
break; /* Dark and mysterious things have just happened */ break; /* Dark and mysterious things have just happened */
} }
......
...@@ -15,24 +15,14 @@ jer_encode(const asn_TYPE_descriptor_t *td, const void *sptr, ...@@ -15,24 +15,14 @@ jer_encode(const asn_TYPE_descriptor_t *td, const void *sptr,
void *app_key) { void *app_key) {
asn_enc_rval_t er = {0, 0, 0}; asn_enc_rval_t er = {0, 0, 0};
asn_enc_rval_t tmper; asn_enc_rval_t tmper;
const char *mname;
size_t mlen;
if(!td || !sptr) goto cb_failed; if(!td || !sptr) goto cb_failed;
mname = td->xml_tag; int xFail = 1; /* TODO JER flags */
mlen = strlen(mname); tmper = td->op->jer_encoder(td, sptr, 1, xFail, cb, app_key);
ASN__CALLBACK3("{\n\"", 3, mname, mlen, "\":", 2);
int xFlag = 0;
tmper = td->op->jer_encoder(td, sptr, 1, xFlag, cb, app_key);
if(tmper.encoded == -1) return tmper; if(tmper.encoded == -1) return tmper;
er.encoded += tmper.encoded; er.encoded += tmper.encoded;
ASN__CALLBACK("}", 1);
// ASN__CALLBACK3("</", 2, mname, mlen, ">\n", xcan);
ASN__ENCODED_OK(er); ASN__ENCODED_OK(er);
cb_failed: cb_failed:
ASN__ENCODE_FAILED; ASN__ENCODE_FAILED;
......
...@@ -84,6 +84,8 @@ pjson_parse(int *stateContext, const void *jsonbuf, size_t size, ...@@ -84,6 +84,8 @@ pjson_parse(int *stateContext, const void *jsonbuf, size_t size,
const char *end = p + size; const char *end = p + size;
int include = 0; int include = 0;
int in_string = 0;
int escaped = 0;
for(; p < end; p++) { for(; p < end; p++) {
int C = *(const unsigned char *)p; int C = *(const unsigned char *)p;
...@@ -93,27 +95,44 @@ pjson_parse(int *stateContext, const void *jsonbuf, size_t size, ...@@ -93,27 +95,44 @@ pjson_parse(int *stateContext, const void *jsonbuf, size_t size,
* Initial state: we're in the middle of some text, * Initial state: we're in the middle of some text,
* or just have started. * or just have started.
*/ */
switch(C) {
case LCBRAC: if(C == CQUOTE && !escaped) { /* " */
/* We're now in an object */ in_string = !in_string;
state = ST_KEY;
break;
case CQUOTE:
TOKEN_CB(PJSON_TEXT, ST_KEY_BODY, 0);
break;
case RSBRAC:
include = !(p - chunk_start);
TOKEN_CB_FINAL(PJSON_VALUE, ST_TEXT, include);
break;
case RCBRAC:
include = !(p - chunk_start);
TOKEN_CB_FINAL(PJSON_VALUE, ST_TEXT, include);
break;
case CCOMMA:
TOKEN_CB_FINAL(PJSON_VALUE, ST_TEXT, 0);
break;
default:
break; break;
} else {
if (C == '\\') {
escaped = !escaped;
break;
} else {
escaped = 0;
}
}
if (!in_string) {
switch(C) {
case LCBRAC:
/* We're now in an object */
TOKEN_CB(PJSON_DLM, ST_KEY, 1);
break;
case LSBRAC:
/* We're now in an array */
TOKEN_CB(PJSON_DLM, ST_ARRAY_VALUE, 1);
break;
case RSBRAC:
include = !(p - chunk_start);
TOKEN_CB_FINAL(PJSON_VALUE, ST_TEXT, include);
break;
case RCBRAC:
include = !(p - chunk_start);
TOKEN_CB_FINAL(PJSON_VALUE, ST_TEXT, include);
break;
case CCOMMA:
TOKEN_CB_FINAL(PJSON_VALUE, ST_TEXT, 0);
break;
default:
break;
}
} }
break; break;
...@@ -155,14 +174,8 @@ pjson_parse(int *stateContext, const void *jsonbuf, size_t size, ...@@ -155,14 +174,8 @@ pjson_parse(int *stateContext, const void *jsonbuf, size_t size,
break; break;
} else { } else {
switch(C) { switch(C) {
case LCBRAC:
TOKEN_CB(PJSON_DLM, ST_VALUE, 1);
break;
case CCOMMA: case CCOMMA:
TOKEN_CB(PJSON_DLM, ST_VALUE, 1); TOKEN_CB(PJSON_DLM, ST_KEY, 1);
break;
case LSBRAC:
TOKEN_CB(PJSON_DLM, ST_ARRAY_VALUE, 1);
break; break;
case RCBRAC: case RCBRAC:
TOKEN_CB(PJSON_DLM, ST_END, 1); TOKEN_CB(PJSON_DLM, ST_END, 1);
...@@ -184,7 +197,7 @@ pjson_parse(int *stateContext, const void *jsonbuf, size_t size, ...@@ -184,7 +197,7 @@ pjson_parse(int *stateContext, const void *jsonbuf, size_t size,
break; break;
case CCOMMA: case CCOMMA:
include = !(p - chunk_start); include = !(p - chunk_start);
TOKEN_CB_FINAL(PJSON_VALUE, ST_VALUE, include); TOKEN_CB_FINAL(PJSON_VALUE, ST_KEY, include);
break; break;
default: default:
break; break;
...@@ -217,17 +230,17 @@ pjson_parse(int *stateContext, const void *jsonbuf, size_t size, ...@@ -217,17 +230,17 @@ pjson_parse(int *stateContext, const void *jsonbuf, size_t size,
case ST_ARRAY_VALUE_BODY: /* Inside array value */ case ST_ARRAY_VALUE_BODY: /* Inside array value */
switch(C) { switch(C) {
case RCBRAC:
include = !(p - chunk_start);
TOKEN_CB_FINAL(PJSON_VALUE, ST_ARRAY_VALUE, include);
break;
case RSBRAC: case RSBRAC:
include = !(p - chunk_start); include = !(p - chunk_start);
TOKEN_CB_FINAL(PJSON_VALUE, ST_ARRAY_VALUE, include); TOKEN_CB_FINAL(PJSON_VALUE, ST_TEXT, include);
break; break;
case CCOMMA: case CCOMMA:
include = !(p - chunk_start); include = !(p - chunk_start);
TOKEN_CB_FINAL(PJSON_VALUE, ST_ARRAY_VALUE, include); if (!include) {
TOKEN_CB_FINAL(PJSON_VALUE, ST_ARRAY_VALUE, 0);
} else {
TOKEN_CB(PJSON_DLM, ST_ARRAY_VALUE, 0);
}
break; break;
default: default:
break; break;
...@@ -252,7 +265,7 @@ pjson_parse(int *stateContext, const void *jsonbuf, size_t size, ...@@ -252,7 +265,7 @@ pjson_parse(int *stateContext, const void *jsonbuf, size_t size,
if(p - chunk_start) { if(p - chunk_start) {
switch (state) { switch (state) {
case ST_TEXT: case ST_TEXT:
TOKEN_CB(PJSON_TEXT, state, 0); TOKEN_CB_FINAL(PJSON_VALUE, state, 0);
break; break;
default: default:
break; break;
......
...@@ -23,6 +23,7 @@ static const struct encoding_map { ...@@ -23,6 +23,7 @@ static const struct encoding_map {
{"OER", "oer", ATS_CANONICAL_OER}, {"OER", "oer", ATS_CANONICAL_OER},
{"UPER", "uper", ATS_UNALIGNED_CANONICAL_PER}, {"UPER", "uper", ATS_UNALIGNED_CANONICAL_PER},
{"XER", "xer", ATS_CANONICAL_XER}, {"XER", "xer", ATS_CANONICAL_XER},
{"JER", "jer", ATS_JER},
}; };
static enum asn_transfer_syntax static enum asn_transfer_syntax
...@@ -52,7 +53,7 @@ static void __attribute__((constructor)) initialize() { ...@@ -52,7 +53,7 @@ static void __attribute__((constructor)) initialize() {
syntax = lookup_syntax(data_dir); syntax = lookup_syntax(data_dir);
if(syntax == ATS_INVALID) { if(syntax == ATS_INVALID) {
fprintf(stderr, fprintf(stderr,
"Expected ASN1_DATA_DIR={der,oer,uper,xer} environment " "Expected ASN1_DATA_DIR={der,oer,uper,xer,jer} environment "
"variable.\n"); "variable.\n");
exit(EX_UNAVAILABLE); exit(EX_UNAVAILABLE);
} }
...@@ -93,7 +94,8 @@ usage(const char *progname) { ...@@ -93,7 +94,8 @@ usage(const char *progname) {
"BER)\n" "BER)\n"
" OER Canonical Octet Encoding Rules\n" " OER Canonical Octet Encoding Rules\n"
" UPER Canonical Unaligned Packed Encoding Rules\n" " UPER Canonical Unaligned Packed Encoding Rules\n"
" XER XML Encoding Rules\n", " XER XML Encoding Rules\n"
" JER JSON Encoding Rules\n",
progname); progname);
} }
......
...@@ -456,85 +456,84 @@ main() { ...@@ -456,85 +456,84 @@ main() {
#endif #endif
CHECK_JER(-1, "", 0); CHECK_JER(-1, "", 0);
CHECK_JER(-1, "{\"INTEGER\":}", 0); CHECK_JER(-1, " ", 0);
CHECK_JER(-1, "{\"INTEGER\": }", 0); CHECK_JER(-1, "-", 0);
CHECK_JER(-1, "{\"INTEGER\":-}", 0); CHECK_JER(-1, "+", 0);
CHECK_JER(-1, "{\"INTEGER\":+}", 0); CHECK_JER(-1, "+-", 0);
CHECK_JER(-1, "{\"INTEGER\":+-}", 0); CHECK_JER(-1, " -", 0);
CHECK_JER(-1, "{\"INTEGER\": -}", 0); CHECK_JER(-1, " +", 0);
CHECK_JER(-1, "{\"INTEGER\": +}", 0); CHECK_JER(-1, " +-", 0);
CHECK_JER(-1, "{\"INTEGER\": +-}", 0); CHECK_JER(-1, "- ", 0);
CHECK_JER(-1, "{\"INTEGER\":- }", 0); CHECK_JER(-1, "+ ", 0);
CHECK_JER(-1, "{\"INTEGER\":+ }", 0); CHECK_JER(-1, "+- ", 0);
CHECK_JER(-1, "{\"INTEGER\":+- }", 0); CHECK_JER(-1, " - ", 0);
CHECK_JER(-1, "{\"INTEGER\": - }", 0); CHECK_JER(-1, " + ", 0);
CHECK_JER(-1, "{\"INTEGER\": + }", 0); CHECK_JER(-1, " +- ", 0);
CHECK_JER(-1, "{\"INTEGER\": +- }", 0); CHECK_JER(-1, "+0", 0);
CHECK_JER(-1, "{\"INTEGER\":+0}", 0); CHECK_JER(0, "-0", 0);
CHECK_JER(0, "{\"INTEGER\":-0}", 0); CHECK_JER(-1, "+1", 0);
CHECK_JER(-1, "{\"INTEGER\":+1}", 0); CHECK_JER(0, "-1", -1);
CHECK_JER(0, "{\"INTEGER\":-1}", -1); CHECK_JER(0, "1", 1);
CHECK_JER(0, "{\"INTEGER\":1}", 1); CHECK_JER(0, "-15", -15);
CHECK_JER(0, "{\"INTEGER\":-15}", -15); CHECK_JER(-1, "+15", 0);
CHECK_JER(-1, "{\"INTEGER\":+15}", 0); CHECK_JER(0, "15", 15);
CHECK_JER(0, "{\"INTEGER\":15}", 15); CHECK_JER(0, " 15", 15);
CHECK_JER(0, "{\"INTEGER\": 15}", 15); CHECK_JER(0, " 15 ", 15);
CHECK_JER(0, "{\"INTEGER\": 15 }", 15); CHECK_JER(0, "15 ", 15);
CHECK_JER(0, "{\"INTEGER\":15 }", 15); CHECK_JER(-1, " +15 ", 0);
CHECK_JER(-1, "{\"INTEGER\": +15 }", 0); CHECK_JER(-1, " 015 ", 0);
CHECK_JER(-1, "{\"INTEGER\": 015 }", 0); CHECK_JER(-1, "015 ", 0);
CHECK_JER(-1, "{\"INTEGER\":015 }", 0); CHECK_JER(-1, " 015", 0);
CHECK_JER(-1, "{\"INTEGER\": 015}", 0); CHECK_JER(-1, " 0 15", 0);
CHECK_JER(-1, "{\"INTEGER\": 0 15}", 0); CHECK_JER(-1, " 0 15 ", 0);
CHECK_JER(-1, "{\"INTEGER\": 0 15 }", 0); CHECK_JER(-1, "0 15", 0);
CHECK_JER(-1, "{\"INTEGER\":0 15}", 0); CHECK_JER(-1, " +15 -", 0);
CHECK_JER(-1, "{\"INTEGER\": +15 -}", 0); CHECK_JER(-1, " +15 1", 0);
CHECK_JER(-1, "{\"INTEGER\": +15 1}", 0); CHECK_JER(-1, "+ 15", 0);
CHECK_JER(-1, "{\"INTEGER\":+ 15}", 0); CHECK_JER(-1, "12e34", 0);
CHECK_JER(-1, "{\"INTEGER\":12e34}", 0); CHECK_JER(-1, "12 e34", 0);
CHECK_JER(-1, "{\"INTEGER\":12 e34}", 0); CHECK_JER(-1, "12 e", 0);
CHECK_JER(-1, "{\"INTEGER\":12 e}", 0); CHECK_JER(0, "1234", 1234);
CHECK_JER(0, "{\"INTEGER\":1234}", 1234); CHECK_JER(-1, "1234 5678", 0);
CHECK_JER(-1, "{\"INTEGER\":1234 5678}", 0); CHECK_JER(0, "-2147483647", -2147483647);
CHECK_JER(0, "{\"INTEGER\":-2147483647}", -2147483647); CHECK_JER(0, "-2147483648", -2147483647-1);
CHECK_JER(0, "{\"INTEGER\":-2147483648}", -2147483647-1); CHECK_JER(-1, "+2147483647", 0);
CHECK_JER(-1, "{\"INTEGER\":+2147483647}", 0); CHECK_JER(0, "2147483647", 2147483647);
CHECK_JER(0, "{\"INTEGER\":2147483647}", 2147483647);
if(sizeof(long) == 4) { if(sizeof(long) == 4) {
CHECK_JER( 0, "{\"INTEGER\":-2147483648}", -2147483648); CHECK_JER( 0, "-2147483648", -2147483648);
CHECK_JER(-1, "{\"INTEGER\":-2147483649}", 0); CHECK_JER(-1, "-2147483649", 0);
CHECK_JER(-1, "{\"INTEGER\":2147483648}", 0); CHECK_JER(-1, "2147483648", 0);
CHECK_JER(-1, "{\"INTEGER\":2147483649}", 0); CHECK_JER(-1, "2147483649", 0);
CHECK_JER(-1, "{\"INTEGER\":3147483649}", 0); CHECK_JER(-1, "3147483649", 0);
CHECK_JER(-1, "{\"INTEGER\":4147483649}", 0); CHECK_JER(-1, "4147483649", 0);
CHECK_JER(-1, "{\"INTEGER\":5147483649}", 0); /* special */ CHECK_JER(-1, "5147483649", 0); /* special */
CHECK_JER(-1, "{\"INTEGER\":9147483649}", 0); CHECK_JER(-1, "9147483649", 0);
CHECK_JER(-1, "{\"INTEGER\":9999999999}", 0); CHECK_JER(-1, "9999999999", 0);
CHECK_JER(-1, "{\"INTEGER\":-5147483649}", 0);/* special */ CHECK_JER(-1, "-5147483649", 0);/* special */
CHECK_JER(-1, "{\"INTEGER\":-9147483649}", 0); CHECK_JER(-1, "-9147483649", 0);
CHECK_JER(-1, "{\"INTEGER\":-9999999999}", 0); CHECK_JER(-1, "-9999999999", 0);
} }
#ifdef TEST_64BIT #ifdef TEST_64BIT
if(sizeof(long) == 8) { if(sizeof(long) == 8) {
CHECK_JER(0, "{\"INTEGER\":2147483648}", 2147483648); CHECK_JER(0, "2147483648", 2147483648);
CHECK_JER(0, "{\"INTEGER\":2147483649}", 2147483649); CHECK_JER(0, "2147483649", 2147483649);
CHECK_JER(0, "{\"INTEGER\":3147483649}", 3147483649); CHECK_JER(0, "3147483649", 3147483649);
CHECK_JER(0, "{\"INTEGER\":4147483649}", 4147483649); CHECK_JER(0, "4147483649", 4147483649);
CHECK_JER(0, "{\"INTEGER\":5147483649}", 5147483649); CHECK_JER(0, "5147483649", 5147483649);
CHECK_JER(0, "{\"INTEGER\":9147483649}", 9147483649); CHECK_JER(0, "9147483649", 9147483649);
CHECK_JER(0, "{\"INTEGER\":9999999999}", 9999999999); CHECK_JER(0, "9999999999", 9999999999);
CHECK_JER(0, "{\"INTEGER\":9223372036854775807}", 9223372036854775807); CHECK_JER(0, "9223372036854775807", 9223372036854775807);
CHECK_JER(-1, "{\"INTEGER\":9223372036854775808}", 0); CHECK_JER(-1, "9223372036854775808", 0);
CHECK_JER(-1, "{\"INTEGER\":10223372036854775807}", 0); CHECK_JER(-1, "10223372036854775807", 0);
CHECK_JER(-1, "{\"INTEGER\":50223372036854775807}", 0); CHECK_JER(-1, "50223372036854775807", 0);
CHECK_JER(-1, "{\"INTEGER\":100223372036854775807}", 0); CHECK_JER(-1, "100223372036854775807", 0);
CHECK_JER(-1, "{\"INTEGER\":500223372036854775807}", 0); CHECK_JER(-1, "500223372036854775807", 0);
CHECK_JER(0, "{\"INTEGER\":-9223372036854775808}", -9223372036854775807-1); CHECK_JER(0, "-9223372036854775808", -9223372036854775807-1);
CHECK_JER(-1, "{\"INTEGER\":-9223372036854775809}", 0); CHECK_JER(-1, "-9223372036854775809", 0);
CHECK_JER(-1, "{\"INTEGER\":-10223372036854775807}", 0); CHECK_JER(-1, "-10223372036854775807", 0);
CHECK_JER(-1, "{\"INTEGER\":-50223372036854775807}", 0); CHECK_JER(-1, "-50223372036854775807", 0);
CHECK_JER(-1, "{\"INTEGER\":-100223372036854775807}", 0); CHECK_JER(-1, "-100223372036854775807", 0);
CHECK_JER(-1, "{\"INTEGER\":-500223372036854775807}", 0); CHECK_JER(-1, "-500223372036854775807", 0);
} else { } else {
assert(sizeof(long) == 8); assert(sizeof(long) == 8);
} }
......
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