diff --git a/skeletons/asn_application.c b/skeletons/asn_application.c index 60c8e78c39167469a5cd21e130e74c66d1502209..d7a2bcbc2a00412f530c26b45a099d0f64dcf0e1 100644 --- a/skeletons/asn_application.c +++ b/skeletons/asn_application.c @@ -292,3 +292,51 @@ asn_encode_internal(const asn_codec_ctx_t *opt_codec_parameters, 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); + } +} + diff --git a/skeletons/asn_application.h b/skeletons/asn_application.h index 0a24018906c0cf2280cd5bc250018bb2bf3dd12a..5fea20cea4f1f67af7336ea428a64f7132074b72 100644 --- a/skeletons/asn_application.h +++ b/skeletons/asn_application.h @@ -111,6 +111,17 @@ asn_enc_rval_t asn_encode( 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 diff --git a/skeletons/converter-sample.c b/skeletons/converter-sample.c index 81200aae6938587bd7eecddf26543e8e79355623..c95b0d0950ead0f5467d6b9b3c4a59a663ae4c25 100644 --- a/skeletons/converter-sample.c +++ b/skeletons/converter-sample.c @@ -54,7 +54,6 @@ static char *argument_to_name(char *av[], int idx); int opt_debug; /* -d (or -dd) */ static int opt_check; /* -c (constraints checking) */ 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) */ #ifdef JUNKTEST /* Enable -J <probability> */ @@ -242,10 +241,6 @@ main(int ac, char *av[]) { } break; case 'p': - if(strcmp(optarg, "er-nopad") == 0) { - opt_nopad = 1; - break; - } #ifdef ASN_PDU_COLLECTION if(strcmp(optarg, "list") == 0) { asn_TYPE_descriptor_t **pdu = asn_pdu_collection; @@ -318,9 +313,6 @@ main(int ac, char *av[]) { (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 fprintf(stderr, " -p <PDU> Specify PDU type to decode\n" @@ -655,6 +647,12 @@ static void add_bytes_to_buffer(const void *data2add, size_t bytes) { (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 * 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; @@ -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); #endif - switch(isyntax) { - case ATS_BER: - case ATS_DER: - rval = ber_decode(opt_codec_ctx, pduType, - (void **)&structure, i_bptr, i_size); - break; - 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 = asn_decode(opt_codec_ctx, isyntax, pduType, (void **)&structure, + i_bptr, i_size); + if(rval.code == RC_WMORE && !restartability_supported(isyntax)) { + /* PER does not support restartability */ + ASN_STRUCT_FREE(*pduType, structure); + structure = 0; rval.consumed = 0; - /* Fall through */ + /* Continue accumulating data */ } + DEBUG("decode(%ld) consumed %ld+%db (%ld), code %d", (long)DynamicBuffer.length, (long)rval.consumed, ecbits, (long)i_size,