Commit e8bbe93a authored by Lev Walkin's avatar Lev Walkin

generic asn_decoder

parent 625d4804
...@@ -292,3 +292,51 @@ asn_encode_internal(const asn_codec_ctx_t *opt_codec_parameters, ...@@ -292,3 +292,51 @@ asn_encode_internal(const asn_codec_ctx_t *opt_codec_parameters,
return er; return er;
} }
asn_dec_rval_t
asn_decode(const asn_codec_ctx_t *opt_codec_parameters,
enum asn_transfer_syntax syntax, struct asn_TYPE_descriptor_s *td,
void **sptr, const void *buffer, size_t size) {
(void)opt_codec_parameters;
asn_codec_ctx_t *opt_ctx = 0;
if(!td || !sptr || (size && !buffer)) {
ASN__DECODE_FAILED;
}
switch(syntax) {
case ATS_CER:
case ATS_NONSTANDARD_PLAINTEXT:
default:
errno = ENOENT;
ASN__DECODE_FAILED;
case ATS_DER:
case ATS_BER:
return ber_decode(opt_ctx, td, sptr, buffer, size);
case ATS_BASIC_OER:
case ATS_CANONICAL_OER:
#ifdef ASN_DISABLE_OER_SUPPORT
errno = ENOENT;
ASN__DECODE_FAILED;
#else
return oer_decode(opt_ctx, td, sptr, buffer, size);
#endif
case ATS_UNALIGNED_BASIC_PER:
case ATS_UNALIGNED_CANONICAL_PER:
#ifdef ASN_DISABLE_PER_SUPPORT
errno = ENOENT;
ASN__DECODE_FAILED;
#else
return uper_decode_complete(opt_ctx, td, sptr, buffer, size);
#endif
case ATS_BASIC_XER:
case ATS_CANONICAL_XER:
return xer_decode(opt_ctx, td, sptr, buffer, size);
}
}
...@@ -111,6 +111,17 @@ asn_enc_rval_t asn_encode( ...@@ -111,6 +111,17 @@ asn_enc_rval_t asn_encode(
asn_app_consume_bytes_f *callback, void *callback_key); asn_app_consume_bytes_f *callback, void *callback_key);
/*
* A generic decoder for any supported transfer syntax.
*/
asn_dec_rval_t asn_decode(
const asn_codec_ctx_t *opt_codec_parameters, enum asn_transfer_syntax,
struct asn_TYPE_descriptor_s *type_to_decode,
void **structure_ptr, /* Pointer to a target structure's pointer */
const void *buffer, /* Data to be decoded */
size_t size /* Size of that buffer */
);
/* /*
* A callback of this type is called whenever constraint validation fails * A callback of this type is called whenever constraint validation fails
......
...@@ -54,7 +54,6 @@ static char *argument_to_name(char *av[], int idx); ...@@ -54,7 +54,6 @@ static char *argument_to_name(char *av[], int idx);
int opt_debug; /* -d (or -dd) */ int opt_debug; /* -d (or -dd) */
static int opt_check; /* -c (constraints checking) */ static int opt_check; /* -c (constraints checking) */
static int opt_stack; /* -s (maximum stack size) */ static int opt_stack; /* -s (maximum stack size) */
static int opt_nopad; /* -per-nopad (PER input is not padded) */
static int opt_onepdu; /* -1 (decode single PDU) */ static int opt_onepdu; /* -1 (decode single PDU) */
#ifdef JUNKTEST /* Enable -J <probability> */ #ifdef JUNKTEST /* Enable -J <probability> */
...@@ -242,10 +241,6 @@ main(int ac, char *av[]) { ...@@ -242,10 +241,6 @@ main(int ac, char *av[]) {
} }
break; break;
case 'p': case 'p':
if(strcmp(optarg, "er-nopad") == 0) {
opt_nopad = 1;
break;
}
#ifdef ASN_PDU_COLLECTION #ifdef ASN_PDU_COLLECTION
if(strcmp(optarg, "list") == 0) { if(strcmp(optarg, "list") == 0) {
asn_TYPE_descriptor_t **pdu = asn_pdu_collection; asn_TYPE_descriptor_t **pdu = asn_pdu_collection;
...@@ -318,9 +313,6 @@ main(int ac, char *av[]) { ...@@ -318,9 +313,6 @@ main(int ac, char *av[]) {
(sel->syntax == osyntax) ? " (DEFAULT)" : ""); (sel->syntax == osyntax) ? " (DEFAULT)" : "");
} }
} }
if(pduType->op->uper_decoder)
fprintf(stderr,
" -per-nopad Assume PER PDUs are not padded (-iper)\n");
#ifdef ASN_PDU_COLLECTION #ifdef ASN_PDU_COLLECTION
fprintf(stderr, fprintf(stderr,
" -p <PDU> Specify PDU type to decode\n" " -p <PDU> Specify PDU type to decode\n"
...@@ -655,6 +647,12 @@ static void add_bytes_to_buffer(const void *data2add, size_t bytes) { ...@@ -655,6 +647,12 @@ static void add_bytes_to_buffer(const void *data2add, size_t bytes) {
(long)DynamicBuffer.allocated); (long)DynamicBuffer.allocated);
} }
static int
restartability_supported(enum asn_transfer_syntax syntax) {
return (syntax != ATS_UNALIGNED_BASIC_PER
&& syntax != ATS_UNALIGNED_CANONICAL_PER);
}
static void * static void *
data_decode_from_file(enum asn_transfer_syntax isyntax, asn_TYPE_descriptor_t *pduType, FILE *file, const char *name, ssize_t suggested_bufsize, int on_first_pdu) { data_decode_from_file(enum asn_transfer_syntax isyntax, asn_TYPE_descriptor_t *pduType, FILE *file, const char *name, ssize_t suggested_bufsize, int on_first_pdu) {
static uint8_t *fbuf; static uint8_t *fbuf;
...@@ -734,66 +732,16 @@ data_decode_from_file(enum asn_transfer_syntax isyntax, asn_TYPE_descriptor_t *p ...@@ -734,66 +732,16 @@ data_decode_from_file(enum asn_transfer_syntax isyntax, asn_TYPE_descriptor_t *p
junk_bytes_with_probability(i_bptr, i_size, opt_jprob); junk_bytes_with_probability(i_bptr, i_size, opt_jprob);
#endif #endif
switch(isyntax) { rval = asn_decode(opt_codec_ctx, isyntax, pduType, (void **)&structure,
case ATS_BER: i_bptr, i_size);
case ATS_DER: if(rval.code == RC_WMORE && !restartability_supported(isyntax)) {
rval = ber_decode(opt_codec_ctx, pduType, /* PER does not support restartability */
(void **)&structure, i_bptr, i_size); ASN_STRUCT_FREE(*pduType, structure);
break; structure = 0;
case ATS_BASIC_OER:
case ATS_CANONICAL_OER:
#ifdef ASN_DISABLE_OER_SUPPORT
rval.code = RC_FAIL;
rval.consumed = 0;
#else
rval = oer_decode(opt_codec_ctx, pduType,
(void **)&structure, i_bptr, i_size);
#endif
break;
case ATS_BASIC_XER:
case ATS_CANONICAL_XER:
rval = xer_decode(opt_codec_ctx, pduType,
(void **)&structure, i_bptr, i_size);
break;
case ATS_UNALIGNED_BASIC_PER:
case ATS_UNALIGNED_CANONICAL_PER:
#ifdef ASN_DISABLE_PER_SUPPORT
rval.code = RC_FAIL;
rval.consumed = 0;
#else
if(opt_nopad)
rval = uper_decode(opt_codec_ctx, pduType,
(void **)&structure, i_bptr, i_size, 0,
DynamicBuffer.unbits);
else
rval = uper_decode_complete(opt_codec_ctx, pduType,
(void **)&structure, i_bptr, i_size);
#endif
switch(rval.code) {
case RC_OK:
/* Fall through */
case RC_FAIL:
if(opt_nopad) {
/* uper_decode() returns bits! */
/* Extra bits */
ecbits = rval.consumed % 8;
/* Convert into bytes! */
rval.consumed /= 8;
}
break;
case RC_WMORE:
/* PER does not support restartability */
ASN_STRUCT_FREE(*pduType, structure);
structure = 0;
rval.consumed = 0;
/* Continue accumulating data */
break;
}
break;
default:
rval.consumed = 0; rval.consumed = 0;
/* Fall through */ /* Continue accumulating data */
} }
DEBUG("decode(%ld) consumed %ld+%db (%ld), code %d", DEBUG("decode(%ld) consumed %ld+%db (%ld), code %d",
(long)DynamicBuffer.length, (long)DynamicBuffer.length,
(long)rval.consumed, ecbits, (long)i_size, (long)rval.consumed, ecbits, (long)i_size,
......
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