From e129848fbe9a149c8da955d16ea7e9ed07257c29 Mon Sep 17 00:00:00 2001 From: "Bi-Ruei, Chiu" Date: Mon, 28 Aug 2017 17:07:30 +0800 Subject: [PATCH] Merge APER implementation from mouse07410's repository --- libasn1compiler/asn1c_C.c | 10 +- skeletons/ANY.c | 4 +- skeletons/ANY.h | 2 + skeletons/BIT_STRING.c | 4 + skeletons/BIT_STRING.h | 2 + skeletons/BMPString.c | 4 + skeletons/BMPString.h | 2 + skeletons/BOOLEAN.c | 57 +++ skeletons/BOOLEAN.h | 2 + skeletons/ENUMERATED.c | 45 +- skeletons/ENUMERATED.h | 2 + skeletons/GeneralString.c | 4 + skeletons/GeneralString.h | 2 + skeletons/GeneralizedTime.c | 4 + skeletons/GeneralizedTime.h | 2 + skeletons/GraphicString.c | 4 + skeletons/GraphicString.h | 2 + skeletons/IA5String.c | 4 + skeletons/IA5String.h | 2 + skeletons/INTEGER.c | 380 ++++++++++++++++ skeletons/INTEGER.h | 4 + skeletons/ISO646String.c | 4 + skeletons/ISO646String.h | 2 + skeletons/NULL.c | 49 ++ skeletons/NULL.h | 2 + skeletons/NativeEnumerated.c | 141 ++++++ skeletons/NativeEnumerated.h | 2 + skeletons/NativeInteger.c | 66 +++ skeletons/NativeInteger.h | 2 + skeletons/NativeReal.c | 70 +++ skeletons/NativeReal.h | 2 + skeletons/NumericString.c | 4 + skeletons/NumericString.h | 2 + skeletons/OBJECT_IDENTIFIER.c | 4 + skeletons/OBJECT_IDENTIFIER.h | 2 + skeletons/OCTET_STRING.c | 366 +++++++++++++++ skeletons/OCTET_STRING.h | 2 + skeletons/OPEN_TYPE.c | 6 +- skeletons/OPEN_TYPE.h | 2 + skeletons/ObjectDescriptor.c | 4 + skeletons/ObjectDescriptor.h | 2 + skeletons/PrintableString.c | 4 + skeletons/PrintableString.h | 2 + skeletons/REAL.c | 21 + skeletons/REAL.h | 2 + skeletons/RELATIVE-OID.c | 4 + skeletons/RELATIVE-OID.h | 2 + skeletons/T61String.c | 4 + skeletons/T61String.h | 2 + skeletons/TeletexString.c | 4 + skeletons/TeletexString.h | 2 + skeletons/UTCTime.c | 4 + skeletons/UTCTime.h | 2 + skeletons/UTF8String.c | 4 + skeletons/UTF8String.h | 2 + skeletons/UniversalString.c | 4 + skeletons/UniversalString.h | 2 + skeletons/VideotexString.c | 4 + skeletons/VideotexString.h | 2 + skeletons/VisibleString.c | 4 + skeletons/VisibleString.h | 2 + skeletons/asn_application.h | 2 + skeletons/constr_CHOICE.c | 169 +++++++ skeletons/constr_CHOICE.h | 2 + skeletons/constr_SEQUENCE.c | 426 ++++++++++++++++++ skeletons/constr_SEQUENCE.h | 2 + skeletons/constr_SEQUENCE_OF.c | 74 +++ skeletons/constr_SEQUENCE_OF.h | 4 +- skeletons/constr_SET.c | 2 + skeletons/constr_SET_OF.c | 94 ++++ skeletons/constr_SET_OF.h | 2 + skeletons/constr_TYPE.h | 2 + skeletons/converter-example.c | 22 +- skeletons/per_decoder.c | 84 ++++ skeletons/per_decoder.h | 23 + skeletons/per_encoder.c | 110 +++++ skeletons/per_encoder.h | 21 + skeletons/per_opentype.c | 136 ++++++ skeletons/per_opentype.h | 12 + skeletons/per_support.c | 194 ++++++++ skeletons/per_support.h | 15 + ...-inherit-per-constraints-OK.asn1.-Pgen-PER | 4 + ...154-with-REAL-components-OK.asn1.-Pgen-PER | 18 + ...tion-more-than-two-level-OK.asn1.-Pgen-PER | 12 + .../50-constraint-OK.asn1.-Pgen-PER | 52 +++ .../90-cond-int-type-OK.asn1.-Pgen-PER | 36 ++ 86 files changed, 2854 insertions(+), 17 deletions(-) diff --git a/libasn1compiler/asn1c_C.c b/libasn1compiler/asn1c_C.c index 15244cbf6..09b2c7142 100644 --- a/libasn1compiler/asn1c_C.c +++ b/libasn1compiler/asn1c_C.c @@ -1433,12 +1433,14 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) { OUT("xer_type_decoder_f %s_decode_xer;\n", p); OUT("xer_type_encoder_f %s_encode_xer;\n", p); if(arg->flags & A1C_GEN_OER) { - OUT("oer_type_decoder_f %s_decode_oer;\n", p); - OUT("oer_type_encoder_f %s_encode_oer;\n", p); + OUT("oer_type_decoder_f %s_decode_oer;\n", p); + OUT("oer_type_encoder_f %s_encode_oer;\n", p); } if(arg->flags & A1C_GEN_PER) { - OUT("per_type_decoder_f %s_decode_uper;\n", p); - OUT("per_type_encoder_f %s_encode_uper;\n", p); + OUT("per_type_decoder_f %s_decode_uper;\n", p); + OUT("per_type_encoder_f %s_encode_uper;\n", p); + OUT("per_type_decoder_f %s_decode_aper;\n", p); + OUT("per_type_encoder_f %s_encode_aper;\n", p); } } diff --git a/skeletons/ANY.c b/skeletons/ANY.c index 6bd5e67a5..be8412f48 100644 --- a/skeletons/ANY.c +++ b/skeletons/ANY.c @@ -27,10 +27,12 @@ asn_TYPE_operation_t asn_OP_ANY = { 0, #endif /* ASN_DISABLE_OER_SUPPORT */ #ifdef ASN_DISABLE_PER_SUPPORT - 0, 0, + 0, 0, 0, 0, #else ANY_decode_uper, ANY_encode_uper, + ANY_decode_aper, + ANY_encode_aper, #endif /* ASN_DISABLE_PER_SUPPORT */ 0, /* Random fill is not defined for ANY type */ 0 /* Use generic outmost tag fetcher */ diff --git a/skeletons/ANY.h b/skeletons/ANY.h index 70d42a9e9..0bc6805ed 100644 --- a/skeletons/ANY.h +++ b/skeletons/ANY.h @@ -29,6 +29,8 @@ der_type_encoder_f ANY_encode_der; xer_type_encoder_f ANY_encode_xer; per_type_decoder_f ANY_decode_uper; per_type_encoder_f ANY_encode_uper; +per_type_decoder_f ANY_decode_aper; +per_type_encoder_f ANY_encode_aper; #define ANY_free OCTET_STRING_free #define ANY_print OCTET_STRING_print diff --git a/skeletons/BIT_STRING.c b/skeletons/BIT_STRING.c index 0cff7706f..87246f1f7 100644 --- a/skeletons/BIT_STRING.c +++ b/skeletons/BIT_STRING.c @@ -35,9 +35,13 @@ asn_TYPE_operation_t asn_OP_BIT_STRING = { #ifdef ASN_DISABLE_PER_SUPPORT 0, 0, + 0, + 0, #else BIT_STRING_decode_uper, /* Unaligned PER decoder */ BIT_STRING_encode_uper, /* Unaligned PER encoder */ + OCTET_STRING_decode_aper, /* Aligned PER decoder */ + OCTET_STRING_encode_aper, /* Aligned PER encoder */ #endif /* ASN_DISABLE_PER_SUPPORT */ BIT_STRING_random_fill, 0 /* Use generic outmost tag fetcher */ diff --git a/skeletons/BIT_STRING.h b/skeletons/BIT_STRING.h index bd2d23db0..c1bdbbcfb 100644 --- a/skeletons/BIT_STRING.h +++ b/skeletons/BIT_STRING.h @@ -38,6 +38,8 @@ asn_random_fill_f BIT_STRING_random_fill; #define BIT_STRING_decode_ber OCTET_STRING_decode_ber #define BIT_STRING_encode_der OCTET_STRING_encode_der #define BIT_STRING_decode_xer OCTET_STRING_decode_xer_binary +#define BIT_STRING_decode_aper OCTET_STRING_decode_aper +#define BIT_STRING_encode_aper OCTET_STRING_encode_aper #ifdef __cplusplus } diff --git a/skeletons/BMPString.c b/skeletons/BMPString.c index 86223fe9f..327321615 100644 --- a/skeletons/BMPString.c +++ b/skeletons/BMPString.c @@ -41,9 +41,13 @@ asn_TYPE_operation_t asn_OP_BMPString = { #ifdef ASN_DISABLE_PER_SUPPORT 0, 0, + 0, + 0, #else OCTET_STRING_decode_uper, OCTET_STRING_encode_uper, + OCTET_STRING_decode_aper, + OCTET_STRING_encode_aper, #endif /* ASN_DISABLE_PER_SUPPORT */ OCTET_STRING_random_fill, 0 /* Use generic outmost tag fetcher */ diff --git a/skeletons/BMPString.h b/skeletons/BMPString.h index b3be16302..af14588bd 100644 --- a/skeletons/BMPString.h +++ b/skeletons/BMPString.h @@ -29,6 +29,8 @@ xer_type_encoder_f BMPString_encode_xer; #define BMPString_encode_der OCTET_STRING_encode_der #define BMPString_decode_uper OCTET_STRING_decode_uper #define BMPString_encode_uper OCTET_STRING_encode_uper +#define BMPString_decode_aper OCTET_STRING_decode_aper +#define BMPString_encode_aper OCTET_STRING_encode_aper #ifdef __cplusplus } diff --git a/skeletons/BOOLEAN.c b/skeletons/BOOLEAN.c index fd8b80c1e..b6f266c51 100644 --- a/skeletons/BOOLEAN.c +++ b/skeletons/BOOLEAN.c @@ -30,9 +30,13 @@ asn_TYPE_operation_t asn_OP_BOOLEAN = { #ifdef ASN_DISABLE_PER_SUPPORT 0, 0, + 0, + 0, #else BOOLEAN_decode_uper, /* Unaligned PER decoder */ BOOLEAN_encode_uper, /* Unaligned PER encoder */ + BOOLEAN_decode_aper, /* Aligned PER decoder */ + BOOLEAN_encode_aper, /* Aligned PER encoder */ #endif /* ASN_DISABLE_PER_SUPPORT */ BOOLEAN_random_fill, 0 /* Use generic outmost tag fetcher */ @@ -310,6 +314,59 @@ BOOLEAN_encode_uper(const asn_TYPE_descriptor_t *td, ASN__ENCODED_OK(er); } +asn_dec_rval_t +BOOLEAN_decode_aper(const asn_codec_ctx_t *opt_codec_ctx, const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { + asn_dec_rval_t rv; + BOOLEAN_t *st = (BOOLEAN_t *)*sptr; + + (void)opt_codec_ctx; + (void)constraints; + (void)td; + + if(!st) { + st = (BOOLEAN_t *)(*sptr = MALLOC(sizeof(*st))); + if(!st) ASN__DECODE_FAILED; + } + + /* + * Extract a single bit + */ + switch(per_get_few_bits(pd, 1)) { + case 1: + *st = 1; + break; + case 0: + *st = 0; + break; + case -1: + default: + ASN__DECODE_STARVED; + } + + ASN_DEBUG("%s decoded as %s", td->name, *st ? "TRUE" : "FALSE"); + + rv.code = RC_OK; + rv.consumed = 1; + return rv; +} + +asn_enc_rval_t +BOOLEAN_encode_aper(const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, + const void *sptr, asn_per_outp_t *po) { + const BOOLEAN_t *st = (const BOOLEAN_t *)sptr; + asn_enc_rval_t er; + + (void)constraints; + + if(!st) ASN__ENCODE_FAILED; + + per_put_few_bits(po, *st ? 1 : 0, 1); + + ASN__ENCODED_OK(er); +} + #endif /* ASN_DISABLE_PER_SUPPORT */ #ifndef ASN_DISABLE_OER_SUPPORT diff --git a/skeletons/BOOLEAN.h b/skeletons/BOOLEAN.h index 7e6b8fb59..620acf7f1 100644 --- a/skeletons/BOOLEAN.h +++ b/skeletons/BOOLEAN.h @@ -30,6 +30,8 @@ oer_type_decoder_f BOOLEAN_decode_oer; oer_type_encoder_f BOOLEAN_encode_oer; per_type_decoder_f BOOLEAN_decode_uper; per_type_encoder_f BOOLEAN_encode_uper; +per_type_decoder_f BOOLEAN_decode_aper; +per_type_encoder_f BOOLEAN_encode_aper; xer_type_decoder_f BOOLEAN_decode_xer; xer_type_encoder_f BOOLEAN_encode_xer; asn_random_fill_f BOOLEAN_random_fill; diff --git a/skeletons/ENUMERATED.c b/skeletons/ENUMERATED.c index c5c197eaa..e16cdd9f0 100644 --- a/skeletons/ENUMERATED.c +++ b/skeletons/ENUMERATED.c @@ -20,7 +20,7 @@ asn_TYPE_operation_t asn_OP_ENUMERATED = { INTEGER_compare, /* Implemented in terms of INTEGER */ ber_decode_primitive, INTEGER_encode_der, /* Implemented in terms of INTEGER */ - INTEGER_decode_xer, /* This is temporary! */ + INTEGER_decode_xer, /* This is temporary! */ INTEGER_encode_xer, #ifdef ASN_DISABLE_OER_SUPPORT 0, @@ -32,9 +32,13 @@ asn_TYPE_operation_t asn_OP_ENUMERATED = { #ifdef ASN_DISABLE_PER_SUPPORT 0, 0, + 0, + 0, #else - ENUMERATED_decode_uper, /* Unaligned PER decoder */ - ENUMERATED_encode_uper, /* Unaligned PER encoder */ + ENUMERATED_decode_uper, /* Unaligned PER decoder */ + ENUMERATED_encode_uper, /* Unaligned PER encoder */ + ENUMERATED_decode_aper, /* Aligned PER decoder */ + ENUMERATED_encode_aper, /* Aligned PER encoder */ #endif /* ASN_DISABLE_PER_SUPPORT */ ENUMERATED_random_fill, 0 /* Use generic outmost tag fetcher */ @@ -138,4 +142,39 @@ ENUMERATED_encode_uper(const asn_TYPE_descriptor_t *td, return NativeEnumerated_encode_uper(td, constraints, &value, po); } +asn_dec_rval_t +ENUMERATED_decode_aper(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { + asn_dec_rval_t rval; + ENUMERATED_t *st = (ENUMERATED_t *)*sptr; + long value; + void *vptr = &value; + + if(!st) { + st = (ENUMERATED_t *)(*sptr = CALLOC(1, sizeof(*st))); + if(!st) ASN__DECODE_FAILED; + } + + rval = NativeEnumerated_decode_aper(opt_codec_ctx, td, constraints, + (void **)&vptr, pd); + if(rval.code == RC_OK) + if(asn_long2INTEGER(st, value)) + rval.code = RC_FAIL; + return rval; +} + +asn_enc_rval_t +ENUMERATED_encode_aper(const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, + const void *sptr, asn_per_outp_t *po) { + const ENUMERATED_t *st = (const ENUMERATED_t *)sptr; + long value; + + if(asn_INTEGER2long(st, &value)) + ASN__ENCODE_FAILED; + + return NativeEnumerated_encode_aper(td, constraints, &value, po); +} #endif /* ASN_DISABLE_PER_SUPPORT */ + diff --git a/skeletons/ENUMERATED.h b/skeletons/ENUMERATED.h index 5bb6a2e15..8fd04de71 100644 --- a/skeletons/ENUMERATED.h +++ b/skeletons/ENUMERATED.h @@ -20,6 +20,8 @@ oer_type_decoder_f ENUMERATED_decode_oer; oer_type_encoder_f ENUMERATED_encode_oer; per_type_decoder_f ENUMERATED_decode_uper; per_type_encoder_f ENUMERATED_encode_uper; +per_type_decoder_f ENUMERATED_decode_aper; +per_type_encoder_f ENUMERATED_encode_aper; #define ENUMERATED_free ASN__PRIMITIVE_TYPE_free #define ENUMERATED_print INTEGER_print diff --git a/skeletons/GeneralString.c b/skeletons/GeneralString.c index 16b6f2ff9..cc35a3a2b 100644 --- a/skeletons/GeneralString.c +++ b/skeletons/GeneralString.c @@ -30,9 +30,13 @@ asn_TYPE_operation_t asn_OP_GeneralString = { #ifdef ASN_DISABLE_PER_SUPPORT 0, 0, + 0, + 0, #else OCTET_STRING_decode_uper, /* Implemented in terms of OCTET STRING */ OCTET_STRING_encode_uper, + OCTET_STRING_decode_aper, /* Implemented in terms of OCTET STRING */ + OCTET_STRING_encode_aper, #endif /* ASN_DISABLE_PER_SUPPORT */ OCTET_STRING_random_fill, 0 /* Use generic outmost tag fetcher */ diff --git a/skeletons/GeneralString.h b/skeletons/GeneralString.h index 074c3647a..fb5de1c3e 100644 --- a/skeletons/GeneralString.h +++ b/skeletons/GeneralString.h @@ -26,6 +26,8 @@ extern asn_TYPE_operation_t asn_OP_GeneralString; #define GeneralString_encode_xer OCTET_STRING_encode_xer #define GeneralString_decode_uper OCTET_STRING_decode_uper #define GeneralString_encode_uper OCTET_STRING_encode_uper +#define GeneralString_decode_aper OCTET_STRING_decode_aper +#define GeneralString_encode_aper OCTET_STRING_encode_aper #ifdef __cplusplus } diff --git a/skeletons/GeneralizedTime.c b/skeletons/GeneralizedTime.c index b2d06034b..a42606584 100644 --- a/skeletons/GeneralizedTime.c +++ b/skeletons/GeneralizedTime.c @@ -191,9 +191,13 @@ asn_TYPE_operation_t asn_OP_GeneralizedTime = { #ifdef ASN_DISABLE_PER_SUPPORT 0, 0, + 0, + 0, #else OCTET_STRING_decode_uper, OCTET_STRING_encode_uper, + OCTET_STRING_decode_aper, + OCTET_STRING_encode_aper, #endif /* ASN_DISABLE_PER_SUPPORT */ GeneralizedTime_random_fill, 0 /* Use generic outmost tag fetcher */ diff --git a/skeletons/GeneralizedTime.h b/skeletons/GeneralizedTime.h index c4e5c56f8..02bffe0a8 100644 --- a/skeletons/GeneralizedTime.h +++ b/skeletons/GeneralizedTime.h @@ -28,6 +28,8 @@ asn_random_fill_f GeneralizedTime_random_fill; #define GeneralizedTime_decode_xer OCTET_STRING_decode_xer_utf8 #define GeneralizedTime_decode_uper OCTET_STRING_decode_uper #define GeneralizedTime_encode_uper OCTET_STRING_encode_uper +#define GeneralizedTime_decode_aper OCTET_STRING_decode_aper +#define GeneralizedTime_encode_aper OCTET_STRING_encode_aper /*********************** * Some handy helpers. * diff --git a/skeletons/GraphicString.c b/skeletons/GraphicString.c index 7ec7945a2..e6642c9ae 100644 --- a/skeletons/GraphicString.c +++ b/skeletons/GraphicString.c @@ -30,9 +30,13 @@ asn_TYPE_operation_t asn_OP_GraphicString = { #ifdef ASN_DISABLE_PER_SUPPORT 0, 0, + 0, + 0, #else OCTET_STRING_decode_uper, /* Implemented in terms of OCTET STRING */ OCTET_STRING_encode_uper, + OCTET_STRING_decode_aper, /* Implemented in terms of OCTET STRING */ + OCTET_STRING_encode_aper, #endif /* ASN_DISABLE_PER_SUPPORT */ OCTET_STRING_random_fill, 0 /* Use generic outmost tag fetcher */ diff --git a/skeletons/GraphicString.h b/skeletons/GraphicString.h index 82b1929c6..19cac6852 100644 --- a/skeletons/GraphicString.h +++ b/skeletons/GraphicString.h @@ -26,6 +26,8 @@ extern asn_TYPE_operation_t asn_OP_GraphicString; #define GraphicString_encode_xer OCTET_STRING_encode_xer #define GraphicString_decode_uper OCTET_STRING_decode_uper #define GraphicString_encode_uper OCTET_STRING_encode_uper +#define GraphicString_decode_aper OCTET_STRING_decode_aper +#define GraphicString_encode_aper OCTET_STRING_encode_aper #ifdef __cplusplus } diff --git a/skeletons/IA5String.c b/skeletons/IA5String.c index 43970416f..1aeebf41b 100644 --- a/skeletons/IA5String.c +++ b/skeletons/IA5String.c @@ -35,9 +35,13 @@ asn_TYPE_operation_t asn_OP_IA5String = { #ifdef ASN_DISABLE_PER_SUPPORT 0, 0, + 0, + 0, #else OCTET_STRING_decode_uper, OCTET_STRING_encode_uper, + OCTET_STRING_decode_aper, + OCTET_STRING_encode_aper, #endif /* ASN_DISABLE_PER_SUPPORT */ OCTET_STRING_random_fill, 0 /* Use generic outmost tag fetcher */ diff --git a/skeletons/IA5String.h b/skeletons/IA5String.h index 5a4d5f2cc..321f0c7e6 100644 --- a/skeletons/IA5String.h +++ b/skeletons/IA5String.h @@ -30,6 +30,8 @@ asn_constr_check_f IA5String_constraint; #define IA5String_encode_xer OCTET_STRING_encode_xer_utf8 #define IA5String_decode_uper OCTET_STRING_decode_uper #define IA5String_encode_uper OCTET_STRING_encode_uper +#define IA5String_decode_aper OCTET_STRING_decode_aper +#define IA5String_encode_aper OCTET_STRING_encode_aper #ifdef __cplusplus } diff --git a/skeletons/INTEGER.c b/skeletons/INTEGER.c index 73da66592..bdd794e9a 100644 --- a/skeletons/INTEGER.c +++ b/skeletons/INTEGER.c @@ -32,9 +32,13 @@ asn_TYPE_operation_t asn_OP_INTEGER = { #ifdef ASN_DISABLE_PER_SUPPORT 0, 0, + 0, + 0, #else INTEGER_decode_uper, /* Unaligned PER decoder */ INTEGER_encode_uper, /* Unaligned PER encoder */ + INTEGER_decode_aper, /* Aligned PER decoder */ + INTEGER_encode_aper, /* Aligned PER encoder */ #endif /* ASN_DISABLE_PER_SUPPORT */ INTEGER_random_fill, 0 /* Use generic outmost tag fetcher */ @@ -797,6 +801,301 @@ INTEGER_encode_uper(const asn_TYPE_descriptor_t *td, ASN__ENCODED_OK(er); } +asn_dec_rval_t +INTEGER_decode_aper(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { + const asn_INTEGER_specifics_t *specs = (const asn_INTEGER_specifics_t *)td->specifics; + asn_dec_rval_t rval = { RC_OK, 0 }; + INTEGER_t *st = (INTEGER_t *)*sptr; + const asn_per_constraint_t *ct; + int repeat; + + (void)opt_codec_ctx; + + if(!st) { + st = (INTEGER_t *)(*sptr = CALLOC(1, sizeof(*st))); + if(!st) ASN__DECODE_FAILED; + } + + if(!constraints) constraints = td->encoding_constraints.per_constraints; + ct = constraints ? &constraints->value : 0; + + if(ct && ct->flags & APC_EXTENSIBLE) { + int inext = per_get_few_bits(pd, 1); + if(inext < 0) ASN__DECODE_STARVED; + if(inext) ct = 0; + } + + FREEMEM(st->buf); + st->buf = 0; + st->size = 0; + if(ct) { + if(ct->flags & APC_SEMI_CONSTRAINED) { + st->buf = (uint8_t *)CALLOC(1, 2); + if(!st->buf) ASN__DECODE_FAILED; + st->size = 1; + } else if(ct->flags & APC_CONSTRAINED && ct->range_bits >= 0) { + size_t size = (ct->range_bits + 7) >> 3; + st->buf = (uint8_t *)MALLOC(1 + size + 1); + if(!st->buf) ASN__DECODE_FAILED; + st->size = size; + } + } + + /* X.691, #12.2.2 */ + if(ct && ct->flags != APC_UNCONSTRAINED) { + /* #10.5.6 */ + ASN_DEBUG("Integer with range %d bits", ct->range_bits); + if(ct->range_bits >= 0) { + if (ct->range_bits > 16) { + int max_range_bytes = (ct->range_bits >> 3) + + (((ct->range_bits % 8) > 0) ? 1 : 0); + int length = 0, i; + long value = 0; + + for (i = 1; ; i++) { + int upper = 1 << i; + if (upper >= max_range_bytes) + break; + } + ASN_DEBUG("Can encode %d (%d bytes) in %d bits", ct->range_bits, + max_range_bytes, i); + + if ((length = per_get_few_bits(pd, i)) < 0) + ASN__DECODE_FAILED; + + /* X.691 #12.2.6 length determinant + lb (1) */ + length += 1; + ASN_DEBUG("Got length %d", length); + if (aper_get_align(pd) != 0) + ASN__DECODE_FAILED; + while (length--) { + int buf = per_get_few_bits(pd, 8); + if (buf < 0) + ASN__DECODE_FAILED; + value += (((long)buf) << (8 * length)); + } + + value += ct->lower_bound; + if((specs && specs->field_unsigned) + ? asn_uint642INTEGER(st, value) + : asn_int642INTEGER(st, value)) + ASN__DECODE_FAILED; + ASN_DEBUG("Got value %ld + low %ld", + value, ct->lower_bound); + } else { + long value = 0; + if (ct->range_bits < 8) { + value = per_get_few_bits(pd, ct->range_bits); + if(value < 0) ASN__DECODE_STARVED; + } else if (ct->range_bits == 8) { + if (aper_get_align(pd) < 0) + ASN__DECODE_FAILED; + value = per_get_few_bits(pd, ct->range_bits); + if(value < 0) ASN__DECODE_STARVED; + } else { + /* Align */ + if (aper_get_align(pd) < 0) + ASN__DECODE_FAILED; + value = per_get_few_bits(pd, 16); + if(value < 0) ASN__DECODE_STARVED; + } + value += ct->lower_bound; + if((specs && specs->field_unsigned) + ? asn_ulong2INTEGER(st, value) + : asn_long2INTEGER(st, value)) + ASN__DECODE_FAILED; + ASN_DEBUG("Got value %ld + low %ld", + value, ct->lower_bound); + } + return rval; + } else { + ASN__DECODE_FAILED; + } + } else { + ASN_DEBUG("Decoding unconstrained integer %s", td->name); + } + + /* X.691, #12.2.3, #12.2.4 */ + do { + ssize_t len; + void *p; + int ret; + + /* Get the PER length */ + len = aper_get_length(pd, -1, -1, &repeat); + if(len < 0) ASN__DECODE_STARVED; + + p = REALLOC(st->buf, st->size + len + 1); + if(!p) ASN__DECODE_FAILED; + st->buf = (uint8_t *)p; + + ret = per_get_many_bits(pd, &st->buf[st->size], 0, 8 * len); + if(ret < 0) ASN__DECODE_STARVED; + st->size += len; + } while(repeat); + st->buf[st->size] = 0; /* JIC */ + + /* #12.2.3 */ + if(ct && ct->lower_bound) { + /* + * TODO: replace by in-place arithmetics. + */ + long value; + if(asn_INTEGER2long(st, &value)) + ASN__DECODE_FAILED; + if(asn_long2INTEGER(st, value + ct->lower_bound)) + ASN__DECODE_FAILED; + } + + return rval; +} + +asn_enc_rval_t +INTEGER_encode_aper(const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, + const void *sptr, asn_per_outp_t *po) { + const asn_INTEGER_specifics_t *specs = (const asn_INTEGER_specifics_t *)td->specifics; + asn_enc_rval_t er; + const INTEGER_t *st = (const INTEGER_t *)sptr; + const uint8_t *buf; + const uint8_t *end; + const asn_per_constraint_t *ct; + long value = 0; + + if(!st || st->size == 0) ASN__ENCODE_FAILED; + + if(!constraints) constraints = td->encoding_constraints.per_constraints; + ct = constraints ? &constraints->value : 0; + + er.encoded = 0; + + if(ct) { + int inext = 0; + if(specs && specs->field_unsigned) { + unsigned long uval; + if(asn_INTEGER2ulong(st, &uval)) + ASN__ENCODE_FAILED; + /* Check proper range */ + if(ct->flags & APC_SEMI_CONSTRAINED) { + if(uval < (unsigned long)ct->lower_bound) + inext = 1; + } else if(ct->range_bits >= 0) { + if(uval < (unsigned long)ct->lower_bound + || uval > (unsigned long)ct->upper_bound) + inext = 1; + } + ASN_DEBUG("Value %lu (%02x/%lu) lb %ld ub %ld %s", + uval, st->buf[0], st->size, + ct->lower_bound, ct->upper_bound, + inext ? "ext" : "fix"); + value = uval; + } else { + if(asn_INTEGER2long(st, &value)) ASN__ENCODE_FAILED; + /* Check proper range */ + if(ct->flags & APC_SEMI_CONSTRAINED) { + if(value < ct->lower_bound) + inext = 1; + } else if(ct->range_bits >= 0) { + if(value < ct->lower_bound + || value > ct->upper_bound) + inext = 1; + } + ASN_DEBUG("Value %lu (%02x/%lu) lb %ld ub %ld %s", + value, st->buf[0], st->size, + ct->lower_bound, ct->upper_bound, + inext ? "ext" : "fix"); + } + if(ct->flags & APC_EXTENSIBLE) { + if(per_put_few_bits(po, inext, 1)) + ASN__ENCODE_FAILED; + if(inext) ct = 0; + } else if(inext) { + ASN__ENCODE_FAILED; + } + } + + /* X.691, #12.2.2 */ + if(ct && ct->range_bits >= 0) { + unsigned long v; + + /* #10.5.6 */ + ASN_DEBUG("Encoding integer %ld (%lu) with range %d bits", + value, value - ct->lower_bound, ct->range_bits); + + v = value - ct->lower_bound; + + /* #12 <= 8 -> alignment ? */ + if (ct->range_bits < 8) { + if(per_put_few_bits(po, 0x00 | v, ct->range_bits)) + ASN__ENCODE_FAILED; + } else if (ct->range_bits == 8) { + if(aper_put_align(po) < 0) + ASN__ENCODE_FAILED; + if(per_put_few_bits(po, 0x00 | v, ct->range_bits)) + ASN__ENCODE_FAILED; + } else if (ct->range_bits <= 16) { + /* Consume the bytes to align on octet */ + if(aper_put_align(po) < 0) + ASN__ENCODE_FAILED; + if(per_put_few_bits(po, 0x0000 | v, + 16)) + ASN__ENCODE_FAILED; + } else { + /* TODO: extend to >64 bits */ + long v64 = v; + int i, j; + int max_range_bytes = (ct->range_bits >> 3) + + (((ct->range_bits % 8) > 0) ? 1 : 0); + + for (i = 1; ; i++) { + int upper = 1 << i; + if (upper >= max_range_bytes) + break; + } + + for (j = sizeof(int64_t) -1; j != 0; j--) { + uint8_t val; + val = v64 >> (j * 8); + if (val != 0) + break; + } + + /* Putting length in the minimum number of bits ex: 5 = 3bits */ + if (per_put_few_bits(po, j, i)) + ASN__ENCODE_FAILED; + + /* Consume the bits to align on octet */ + if (aper_put_align(po) < 0) + ASN__ENCODE_FAILED; + /* Put the value */ + for (i = 0; i <= j; i++) { + if(per_put_few_bits(po, (v64 >> (8 * (j - i))) & 0xff, 8)) + ASN__ENCODE_FAILED; + } + } + ASN__ENCODED_OK(er); + } + + if(ct && ct->lower_bound) { + ASN_DEBUG("Adjust lower bound to %ld", ct->lower_bound); + /* TODO: adjust lower bound */ + ASN__ENCODE_FAILED; + } + + for(buf = st->buf, end = st->buf + st->size; buf < end;) { + ssize_t mayEncode = aper_put_length(po, -1, end - buf); + if(mayEncode < 0) + ASN__ENCODE_FAILED; + if(per_put_many_bits(po, buf, 8 * mayEncode)) + ASN__ENCODE_FAILED; + buf += mayEncode; + } + + ASN__ENCODED_OK(er); +} + #endif /* ASN_DISABLE_PER_SUPPORT */ static intmax_t @@ -1024,6 +1323,87 @@ asn_ulong2INTEGER(INTEGER_t *st, unsigned long value) { return asn_imax2INTEGER(st, value); } + +int +asn_uint642INTEGER(INTEGER_t *st, uint64_t value) { + uint8_t *buf; + uint8_t *end; + uint8_t *b; + int shr; + + if(value <= INT64_MAX) + return asn_int642INTEGER(st, value); + + buf = (uint8_t *)MALLOC(1 + sizeof(value)); + if(!buf) return -1; + + end = buf + (sizeof(value) + 1); + buf[0] = 0; + for(b = buf + 1, shr = (sizeof(value)-1)*8; b < end; shr -= 8, b++) + *b = (uint8_t)(value >> shr); + + if(st->buf) FREEMEM(st->buf); + st->buf = buf; + st->size = 1 + sizeof(value); + + return 0; +} + +int +asn_int642INTEGER(INTEGER_t *st, int64_t value) { + uint8_t *buf, *bp; + uint8_t *p; + uint8_t *pstart; + uint8_t *pend1; + int littleEndian = 1; /* Run-time detection */ + int add; + + if(!st) { + errno = EINVAL; + return -1; + } + + buf = (uint8_t *)MALLOC(sizeof(value)); + if(!buf) return -1; + + if(*(char *)&littleEndian) { + pstart = (uint8_t *)&value + sizeof(value) - 1; + pend1 = (uint8_t *)&value; + add = -1; + } else { + pstart = (uint8_t *)&value; + pend1 = pstart + sizeof(value) - 1; + add = 1; + } + + /* + * If the contents octet consists of more than one octet, + * then bits of the first octet and bit 8 of the second octet: + * a) shall not all be ones; and + * b) shall not all be zero. + */ + for(p = pstart; p != pend1; p += add) { + switch(*p) { + case 0x00: if((*(p+add) & 0x80) == 0) + continue; + break; + case 0xff: if((*(p+add) & 0x80)) + continue; + break; + } + break; + } + /* Copy the integer body */ + for(pstart = p, bp = buf, pend1 += add; p != pend1; p += add) + *bp++ = *p; + + if(st->buf) FREEMEM(st->buf); + st->buf = buf; + st->size = bp - buf; + + return 0; +} + /* * Parse the number in the given string until the given *end position, * returning the position after the last parsed character back using the diff --git a/skeletons/INTEGER.h b/skeletons/INTEGER.h index 8efd75c0e..564d42750 100644 --- a/skeletons/INTEGER.h +++ b/skeletons/INTEGER.h @@ -48,6 +48,8 @@ oer_type_decoder_f INTEGER_decode_oer; oer_type_encoder_f INTEGER_encode_oer; per_type_decoder_f INTEGER_decode_uper; per_type_encoder_f INTEGER_encode_uper; +per_type_decoder_f INTEGER_decode_aper; +per_type_encoder_f INTEGER_encode_aper; asn_random_fill_f INTEGER_random_fill; /*********************************** @@ -74,6 +76,8 @@ int asn_INTEGER2long(const INTEGER_t *i, long *l); int asn_INTEGER2ulong(const INTEGER_t *i, unsigned long *l); int asn_long2INTEGER(INTEGER_t *i, long l); int asn_ulong2INTEGER(INTEGER_t *i, unsigned long l); +int asn_int642INTEGER(INTEGER_t *i, int64_t l); +int asn_uint642INTEGER(INTEGER_t *i, uint64_t l); /* A version of strtol/strtoimax(3) with nicer error reporting. */ enum asn_strtox_result_e { diff --git a/skeletons/ISO646String.c b/skeletons/ISO646String.c index 86b128bf2..f5fc69e7f 100644 --- a/skeletons/ISO646String.c +++ b/skeletons/ISO646String.c @@ -35,9 +35,13 @@ asn_TYPE_operation_t asn_OP_ISO646String = { #ifdef ASN_DISABLE_PER_SUPPORT 0, 0, + 0, + 0, #else OCTET_STRING_decode_uper, OCTET_STRING_encode_uper, + OCTET_STRING_decode_aper, + OCTET_STRING_encode_aper, #endif /* ASN_DISABLE_PER_SUPPORT */ OCTET_STRING_random_fill, 0 /* Use generic outmost tag fetcher */ diff --git a/skeletons/ISO646String.h b/skeletons/ISO646String.h index dcaa414ac..cd24a68cc 100644 --- a/skeletons/ISO646String.h +++ b/skeletons/ISO646String.h @@ -27,6 +27,8 @@ extern asn_TYPE_operation_t asn_OP_ISO646String; #define ISO646String_encode_xer OCTET_STRING_encode_xer_utf8 #define ISO646String_decode_uper OCTET_STRING_decode_uper #define ISO646String_encode_uper OCTET_STRING_encode_uper +#define ISO646String_decode_aper OCTET_STRING_decode_aper +#define ISO646String_encode_aper OCTET_STRING_encode_aper #ifdef __cplusplus } diff --git a/skeletons/NULL.c b/skeletons/NULL.c index a43d412b5..d882500e0 100644 --- a/skeletons/NULL.c +++ b/skeletons/NULL.c @@ -31,9 +31,13 @@ asn_TYPE_operation_t asn_OP_NULL = { #ifdef ASN_DISABLE_PER_SUPPORT 0, 0, + 0, + 0, #else NULL_decode_uper, /* Unaligned PER decoder */ NULL_encode_uper, /* Unaligned PER encoder */ + NULL_decode_aper, /* Aligned PER decoder */ + NULL_encode_aper, /* Aligned PER encoder */ #endif /* ASN_DISABLE_PER_SUPPORT */ NULL_random_fill, 0 /* Use generic outmost tag fetcher */ @@ -222,6 +226,51 @@ NULL_encode_uper(const asn_TYPE_descriptor_t *td, ASN__ENCODED_OK(er); } +asn_dec_rval_t +NULL_decode_aper(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { + asn_dec_rval_t rv; + + (void)opt_codec_ctx; + (void)td; + (void)constraints; + (void)pd; + + if(!*sptr) { + *sptr = MALLOC(sizeof(NULL_t)); + if(*sptr) { + *(NULL_t *)*sptr = 0; + } else { + ASN__DECODE_FAILED; + } + } + + /* + * NULL type does not have content octets. + */ + + rv.code = RC_OK; + rv.consumed = 0; + return rv; +} + + +asn_enc_rval_t +NULL_encode_aper(const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, + const void *sptr, asn_per_outp_t *po) { + asn_enc_rval_t er; + + (void)td; + (void)constraints; + (void)sptr; + (void)po; + + er.encoded = 0; + ASN__ENCODED_OK(er); +} + #endif /* ASN_DISABLE_PER_SUPPORT */ asn_random_fill_result_t diff --git a/skeletons/NULL.h b/skeletons/NULL.h index 50f53ca06..802d12c00 100644 --- a/skeletons/NULL.h +++ b/skeletons/NULL.h @@ -30,6 +30,8 @@ oer_type_decoder_f NULL_decode_oer; oer_type_encoder_f NULL_encode_oer; per_type_decoder_f NULL_decode_uper; per_type_encoder_f NULL_encode_uper; +per_type_decoder_f NULL_decode_aper; +per_type_encoder_f NULL_encode_aper; asn_random_fill_f NULL_random_fill; #define NULL_free BOOLEAN_free diff --git a/skeletons/NativeEnumerated.c b/skeletons/NativeEnumerated.c index 4ed8749d0..7c069e78d 100644 --- a/skeletons/NativeEnumerated.c +++ b/skeletons/NativeEnumerated.c @@ -36,9 +36,13 @@ asn_TYPE_operation_t asn_OP_NativeEnumerated = { #ifdef ASN_DISABLE_PER_SUPPORT 0, 0, + 0, + 0, #else NativeEnumerated_decode_uper, NativeEnumerated_encode_uper, + NativeEnumerated_decode_aper, + NativeEnumerated_encode_aper, #endif /* ASN_DISABLE_PER_SUPPORT */ NativeEnumerated_random_fill, 0 /* Use generic outmost tag fetcher */ @@ -224,3 +228,140 @@ NativeEnumerated_encode_uper(const asn_TYPE_descriptor_t *td, ASN__ENCODED_OK(er); } +asn_dec_rval_t +NativeEnumerated_decode_aper(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, + void **sptr, asn_per_data_t *pd) { + const asn_INTEGER_specifics_t *specs = (const asn_INTEGER_specifics_t *)td->specifics; + asn_dec_rval_t rval = { RC_OK, 0 }; + long *native = (long *)*sptr; + const asn_per_constraint_t *ct; + long value; + + (void)opt_codec_ctx; + + if(constraints) ct = &constraints->value; + else if(td->encoding_constraints.per_constraints) + ct = &td->encoding_constraints.per_constraints->value; + else ASN__DECODE_FAILED; /* Mandatory! */ + if(!specs) ASN__DECODE_FAILED; + + if(!native) { + native = (long *)(*sptr = CALLOC(1, sizeof(*native))); + if(!native) ASN__DECODE_FAILED; + } + + ASN_DEBUG("Decoding %s as NativeEnumerated", td->name); + + if(ct->flags & APC_EXTENSIBLE) { + int inext = per_get_few_bits(pd, 1); + if(inext < 0) ASN__DECODE_STARVED; + if(inext) ct = 0; + } + + /* Deal with APER padding */ + if(ct && ct->upper_bound >= 255) { + int padding = 0; + padding = (8 - (pd->moved % 8)) % 8; + ASN_DEBUG("For NativeEnumerated %s,offset= %lu Padding bits = %d", td->name, pd->moved, padding); + ASN_DEBUG("For NativeEnumerated %s, upper bound = %lu", td->name, ct->upper_bound); + if(padding > 0) + per_get_few_bits(pd, padding); + } + + if(ct && ct->range_bits >= 0) { + value = per_get_few_bits(pd, ct->range_bits); + if(value < 0) ASN__DECODE_STARVED; + if(value >= (specs->extension + ? specs->extension - 1 : specs->map_count)) + ASN__DECODE_FAILED; + } else { + if(!specs->extension) + ASN__DECODE_FAILED; + /* + * X.691, #10.6: normally small non-negative whole number; + */ + value = uper_get_nsnnwn(pd); + if(value < 0) ASN__DECODE_STARVED; + value += specs->extension - 1; + if(value >= specs->map_count) + ASN__DECODE_FAILED; + } + + *native = specs->value2enum[value].nat_value; + ASN_DEBUG("Decoded %s = %ld", td->name, *native); + + return rval; +} + +asn_enc_rval_t +NativeEnumerated_encode_aper(const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, + const void *sptr, asn_per_outp_t *po) { + const asn_INTEGER_specifics_t *specs = (const asn_INTEGER_specifics_t *)td->specifics; + asn_enc_rval_t er; + long native, value; + const asn_per_constraint_t *ct; + int inext = 0; + asn_INTEGER_enum_map_t key; + asn_INTEGER_enum_map_t *kf; + + if(!sptr) ASN__ENCODE_FAILED; + if(!specs) ASN__ENCODE_FAILED; + + if(constraints) ct = &constraints->value; + else if(td->encoding_constraints.per_constraints) + ct = &td->encoding_constraints.per_constraints->value; + else ASN__ENCODE_FAILED; /* Mandatory! */ + + ASN_DEBUG("Encoding %s as NativeEnumerated", td->name); + + er.encoded = 0; + + native = *(const long *)sptr; + if(native < 0) ASN__ENCODE_FAILED; + + key.nat_value = native; + kf = bsearch(&key, specs->value2enum, specs->map_count, + sizeof(key), NativeEnumerated__compar_value2enum); + if(!kf) { + ASN_DEBUG("No element corresponds to %ld", native); + ASN__ENCODE_FAILED; + } + value = kf - specs->value2enum; + + if(ct->range_bits >= 0) { + int cmpWith = specs->extension + ? specs->extension - 1 : specs->map_count; + if(value >= cmpWith) + inext = 1; + } + if(ct->flags & APC_EXTENSIBLE) { + if(per_put_few_bits(po, inext, 1)) + ASN__ENCODE_FAILED; + if(inext) ct = 0; + } else if(inext) { + ASN__ENCODE_FAILED; + } + + if(ct && ct->range_bits >= 0) { + if(per_put_few_bits(po, value, ct->range_bits)) + ASN__ENCODE_FAILED; + ASN__ENCODED_OK(er); + } + + if(!specs->extension) + ASN__ENCODE_FAILED; + + /* + * X.691, #10.6: normally small non-negative whole number; + */ + ASN_DEBUG("value = %ld, ext = %d, inext = %d, res = %ld", + value, specs->extension, inext, + value - (inext ? (specs->extension - 1) : 0)); + if(uper_put_nsnnwn(po, value - (inext ? (specs->extension - 1) : 0))) + ASN__ENCODE_FAILED; + + ASN__ENCODED_OK(er); +} diff --git a/skeletons/NativeEnumerated.h b/skeletons/NativeEnumerated.h index 4d897a0ba..459f0e633 100644 --- a/skeletons/NativeEnumerated.h +++ b/skeletons/NativeEnumerated.h @@ -26,6 +26,8 @@ oer_type_decoder_f NativeEnumerated_decode_oer; oer_type_encoder_f NativeEnumerated_encode_oer; per_type_decoder_f NativeEnumerated_decode_uper; per_type_encoder_f NativeEnumerated_encode_uper; +per_type_decoder_f NativeEnumerated_decode_aper; +per_type_encoder_f NativeEnumerated_encode_aper; #define NativeEnumerated_free NativeInteger_free #define NativeEnumerated_print NativeInteger_print diff --git a/skeletons/NativeInteger.c b/skeletons/NativeInteger.c index f17243753..8c00d54c3 100644 --- a/skeletons/NativeInteger.c +++ b/skeletons/NativeInteger.c @@ -37,9 +37,13 @@ asn_TYPE_operation_t asn_OP_NativeInteger = { #ifdef ASN_DISABLE_PER_SUPPORT 0, 0, + 0, + 0, #else NativeInteger_decode_uper, /* Unaligned PER decoder */ NativeInteger_encode_uper, /* Unaligned PER encoder */ + NativeInteger_decode_aper, /* Aligned PER decoder */ + NativeInteger_encode_aper, /* Aligned PER encoder */ #endif /* ASN_DISABLE_PER_SUPPORT */ NativeInteger_random_fill, 0 /* Use generic outmost tag fetcher */ @@ -315,6 +319,68 @@ NativeInteger_encode_uper(const asn_TYPE_descriptor_t *td, return er; } +asn_dec_rval_t +NativeInteger_decode_aper(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { + + const asn_INTEGER_specifics_t *specs = (const asn_INTEGER_specifics_t *)td->specifics; + asn_dec_rval_t rval; + long *native = (long *)*sptr; + INTEGER_t tmpint; + void *tmpintptr = &tmpint; + + (void)opt_codec_ctx; + ASN_DEBUG("Decoding NativeInteger %s (APER)", td->name); + + if(!native) { + native = (long *)(*sptr = CALLOC(1, sizeof(*native))); + if(!native) ASN__DECODE_FAILED; + } + + memset(&tmpint, 0, sizeof tmpint); + rval = INTEGER_decode_aper(opt_codec_ctx, td, constraints, + &tmpintptr, pd); + if(rval.code == RC_OK) { + if((specs&&specs->field_unsigned) + ? asn_INTEGER2ulong(&tmpint, (unsigned long *)native) + : asn_INTEGER2long(&tmpint, native)) + rval.code = RC_FAIL; + else + ASN_DEBUG("NativeInteger %s got value %ld", + td->name, *native); + } + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &tmpint); + + return rval; +} + +asn_enc_rval_t +NativeInteger_encode_aper(const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, + const void *sptr, asn_per_outp_t *po) { + + const asn_INTEGER_specifics_t *specs = (const asn_INTEGER_specifics_t *)td->specifics; + asn_enc_rval_t er; + long native; + INTEGER_t tmpint; + + if(!sptr) ASN__ENCODE_FAILED; + + native = *(const long *)sptr; + + ASN_DEBUG("Encoding NativeInteger %s %ld (APER)", td->name, native); + + memset(&tmpint, 0, sizeof(tmpint)); + if((specs&&specs->field_unsigned) + ? asn_ulong2INTEGER(&tmpint, (unsigned long)native) + : asn_long2INTEGER(&tmpint, native)) + ASN__ENCODE_FAILED; + er = INTEGER_encode_aper(td, constraints, &tmpint, po); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &tmpint); + return er; +} + #endif /* ASN_DISABLE_PER_SUPPORT */ /* diff --git a/skeletons/NativeInteger.h b/skeletons/NativeInteger.h index e2741c201..c74406a8a 100644 --- a/skeletons/NativeInteger.h +++ b/skeletons/NativeInteger.h @@ -33,6 +33,8 @@ oer_type_decoder_f NativeInteger_decode_oer; oer_type_encoder_f NativeInteger_encode_oer; per_type_decoder_f NativeInteger_decode_uper; per_type_encoder_f NativeInteger_encode_uper; +per_type_decoder_f NativeInteger_decode_aper; +per_type_encoder_f NativeInteger_encode_aper; asn_random_fill_f NativeInteger_random_fill; #define NativeInteger_constraint asn_generic_no_constraint diff --git a/skeletons/NativeReal.c b/skeletons/NativeReal.c index b1d1a7ede..d4c14ad74 100644 --- a/skeletons/NativeReal.c +++ b/skeletons/NativeReal.c @@ -58,9 +58,13 @@ asn_TYPE_operation_t asn_OP_NativeReal = { #ifdef ASN_DISABLE_PER_SUPPORT 0, 0, + 0, + 0, #else NativeReal_decode_uper, NativeReal_encode_uper, + NativeReal_decode_aper, + NativeReal_encode_aper, #endif /* ASN_DISABLE_PER_SUPPORT */ NativeReal_random_fill, 0 /* Use generic outmost tag fetcher */ @@ -262,6 +266,72 @@ NativeReal_encode_uper(const asn_TYPE_descriptor_t *td, return erval; } + +asn_dec_rval_t +NativeReal_decode_aper(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, + void **dbl_ptr, asn_per_data_t *pd) { + double *Dbl = (double *)*dbl_ptr; + asn_dec_rval_t rval; + REAL_t tmp; + void *ptmp = &tmp; + int ret; + + (void)constraints; + + /* + * If the structure is not there, allocate it. + */ + if(Dbl == NULL) { + *dbl_ptr = CALLOC(1, sizeof(*Dbl)); + Dbl = (double *)*dbl_ptr; + if(Dbl == NULL) + ASN__DECODE_FAILED; + } + + memset(&tmp, 0, sizeof(tmp)); + rval = OCTET_STRING_decode_aper(opt_codec_ctx, td, NULL, + &ptmp, pd); + if(rval.code != RC_OK) { + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_REAL, &tmp); + return rval; + } + + ret = asn_REAL2double(&tmp, Dbl); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_REAL, &tmp); + if(ret) ASN__DECODE_FAILED; + + return rval; +} + +asn_enc_rval_t +NativeReal_encode_aper(const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, + const void *sptr, asn_per_outp_t *po) { + double Dbl = *(const double *)sptr; + asn_enc_rval_t erval; + REAL_t tmp; + + (void)constraints; + + /* Prepare a temporary clean structure */ + memset(&tmp, 0, sizeof(tmp)); + + if(asn_double2REAL(&tmp, Dbl)) + ASN__ENCODE_FAILED; + + /* Encode a DER REAL */ + erval = OCTET_STRING_encode_aper(td, NULL, &tmp, po); + if(erval.encoded == -1) + erval.structure_ptr = sptr; + + /* Free possibly allocated members of the temporary structure */ + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_REAL, &tmp); + + return erval; +} + #endif /* ASN_DISABLE_PER_SUPPORT */ #ifndef ASN_DISABLE_OER_SUPPORT diff --git a/skeletons/NativeReal.h b/skeletons/NativeReal.h index b6d16d6c1..1bfdc966a 100644 --- a/skeletons/NativeReal.h +++ b/skeletons/NativeReal.h @@ -31,6 +31,8 @@ ber_type_decoder_f NativeReal_decode_ber; der_type_encoder_f NativeReal_encode_der; per_type_decoder_f NativeReal_decode_uper; per_type_encoder_f NativeReal_encode_uper; +per_type_decoder_f NativeReal_decode_aper; +per_type_encoder_f NativeReal_encode_aper; oer_type_decoder_f NativeReal_decode_oer; oer_type_encoder_f NativeReal_encode_oer; xer_type_decoder_f NativeReal_decode_xer; diff --git a/skeletons/NumericString.c b/skeletons/NumericString.c index c89597ef9..ec98ba53a 100644 --- a/skeletons/NumericString.c +++ b/skeletons/NumericString.c @@ -55,9 +55,13 @@ asn_TYPE_operation_t asn_OP_NumericString = { #ifdef ASN_DISABLE_PER_SUPPORT 0, 0, + 0, + 0, #else OCTET_STRING_decode_uper, OCTET_STRING_encode_uper, + OCTET_STRING_decode_aper, + OCTET_STRING_encode_aper, #endif /* ASN_DISABLE_PER_SUPPORT */ OCTET_STRING_random_fill, 0 /* Use generic outmost tag fetcher */ diff --git a/skeletons/NumericString.h b/skeletons/NumericString.h index ae7987317..5f3348409 100644 --- a/skeletons/NumericString.h +++ b/skeletons/NumericString.h @@ -27,6 +27,8 @@ asn_constr_check_f NumericString_constraint; #define NumericString_encode_xer OCTET_STRING_encode_xer_utf8 #define NumericString_decode_uper OCTET_STRING_decode_uper #define NumericString_encode_uper OCTET_STRING_encode_uper +#define NumericString_decode_aper OCTET_STRING_decode_aper +#define NumericString_encode_aper OCTET_STRING_encode_aper #ifdef __cplusplus } diff --git a/skeletons/OBJECT_IDENTIFIER.c b/skeletons/OBJECT_IDENTIFIER.c index 290545d1c..80ab797e7 100644 --- a/skeletons/OBJECT_IDENTIFIER.c +++ b/skeletons/OBJECT_IDENTIFIER.c @@ -33,9 +33,13 @@ asn_TYPE_operation_t asn_OP_OBJECT_IDENTIFIER = { #ifdef ASN_DISABLE_PER_SUPPORT 0, 0, + 0, + 0, #else OCTET_STRING_decode_uper, OCTET_STRING_encode_uper, + OCTET_STRING_decode_aper, + OCTET_STRING_encode_aper, #endif /* ASN_DISABLE_PER_SUPPORT */ OBJECT_IDENTIFIER_random_fill, 0 /* Use generic outmost tag fetcher */ diff --git a/skeletons/OBJECT_IDENTIFIER.h b/skeletons/OBJECT_IDENTIFIER.h index aa0d5c708..087c6fda1 100644 --- a/skeletons/OBJECT_IDENTIFIER.h +++ b/skeletons/OBJECT_IDENTIFIER.h @@ -36,6 +36,8 @@ asn_random_fill_f OBJECT_IDENTIFIER_random_fill; #define OBJECT_IDENTIFIER_encode_oer oer_encode_primitive #define OBJECT_IDENTIFIER_decode_uper OCTET_STRING_decode_uper #define OBJECT_IDENTIFIER_encode_uper OCTET_STRING_encode_uper +#define OBJECT_IDENTIFIER_decode_aper OCTET_STRING_decode_aper +#define OBJECT_IDENTIFIER_encode_aper OCTET_STRING_encode_aper /********************************** * Some handy conversion routines * diff --git a/skeletons/OCTET_STRING.c b/skeletons/OCTET_STRING.c index a69285166..922b687de 100644 --- a/skeletons/OCTET_STRING.c +++ b/skeletons/OCTET_STRING.c @@ -38,9 +38,13 @@ asn_TYPE_operation_t asn_OP_OCTET_STRING = { #ifdef ASN_DISABLE_PER_SUPPORT 0, 0, + 0, + 0, #else OCTET_STRING_decode_uper, /* Unaligned PER decoder */ OCTET_STRING_encode_uper, /* Unaligned PER encoder */ + OCTET_STRING_decode_aper, /* Aligned PER decoder */ + OCTET_STRING_encode_aper, /* Aligned PER encoder */ #endif /* ASN_DISABLE_PER_SUPPORT */ OCTET_STRING_random_fill, 0 /* Use generic outmost tag fetcher */ @@ -1643,6 +1647,368 @@ OCTET_STRING_encode_uper(const asn_TYPE_descriptor_t *td, ASN__ENCODED_OK(er); } +asn_dec_rval_t +OCTET_STRING_decode_aper(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, + void **sptr, asn_per_data_t *pd) { + + const asn_OCTET_STRING_specifics_t *specs = td->specifics + ? (const asn_OCTET_STRING_specifics_t *)td->specifics + : &asn_SPC_OCTET_STRING_specs; + const asn_per_constraints_t *pc = constraints ? constraints + : td->encoding_constraints.per_constraints; + const asn_per_constraint_t *cval; + const asn_per_constraint_t *csiz; + asn_dec_rval_t rval = { RC_OK, 0 }; + BIT_STRING_t *st = (BIT_STRING_t *)*sptr; + ssize_t consumed_myself = 0; + int repeat; + enum { + OS__BPC_BIT = 0, + OS__BPC_CHAR = 1, + OS__BPC_U16 = 2, + OS__BPC_U32 = 4 + } bpc; /* Bytes per character */ + unsigned int unit_bits; + unsigned int canonical_unit_bits; + + (void)opt_codec_ctx; + + if(pc) { + cval = &pc->value; + csiz = &pc->size; + } else { + cval = &asn_DEF_OCTET_STRING_constraints.value; + csiz = &asn_DEF_OCTET_STRING_constraints.size; + } + + switch(specs->subvariant) { + default: +/* case ASN_OSUBV_ANY: + ASN_DEBUG("Unrecognized subvariant %d", specs->subvariant); + RETURN(RC_FAIL); +*/ + case ASN_OSUBV_BIT: + canonical_unit_bits = unit_bits = 1; + bpc = OS__BPC_BIT; + break; + case ASN_OSUBV_ANY: + case ASN_OSUBV_STR: + canonical_unit_bits = unit_bits = 8; +/* if(cval->flags & APC_CONSTRAINED) + unit_bits = cval->range_bits; +*/ + bpc = OS__BPC_CHAR; + break; + case ASN_OSUBV_U16: + canonical_unit_bits = unit_bits = 16; + if(cval->flags & APC_CONSTRAINED) + unit_bits = cval->range_bits; + bpc = OS__BPC_U16; + break; + case ASN_OSUBV_U32: + canonical_unit_bits = unit_bits = 32; + if(cval->flags & APC_CONSTRAINED) + unit_bits = cval->range_bits; + bpc = OS__BPC_U32; + break; + } + + /* + * Allocate the string. + */ + if(!st) { + st = (BIT_STRING_t *)(*sptr = CALLOC(1, specs->struct_size)); + if(!st) RETURN(RC_FAIL); + } + + ASN_DEBUG("PER Decoding %s size %ld .. %ld bits %d", + csiz->flags & APC_EXTENSIBLE ? "extensible" : "non-extensible", + csiz->lower_bound, csiz->upper_bound, csiz->effective_bits); + + if(csiz->flags & APC_EXTENSIBLE) { + int inext = per_get_few_bits(pd, 1); + if(inext < 0) RETURN(RC_WMORE); + if(inext) { + csiz = &asn_DEF_OCTET_STRING_constraints.size; + cval = &asn_DEF_OCTET_STRING_constraints.value; + unit_bits = canonical_unit_bits; + } + } + + if(csiz->effective_bits >= 0) { + FREEMEM(st->buf); + if(bpc) { + st->size = csiz->upper_bound * bpc; + } else { + st->size = (csiz->upper_bound + 7) >> 3; + } + st->buf = (uint8_t *)MALLOC(st->size + 1); + if(!st->buf) { st->size = 0; RETURN(RC_FAIL); } + } + + /* X.691, #16.5: zero-length encoding */ + /* X.691, #16.6: short fixed length encoding (up to 2 octets) */ + /* X.691, #16.7: long fixed length encoding (up to 64K octets) */ + if(csiz->effective_bits == 0) { + int ret; + if (st->size > 2) { /* X.691 #16 NOTE 1 */ + if (aper_get_align(pd) < 0) + RETURN(RC_FAIL); + } + if(bpc) { + ASN_DEBUG("Decoding OCTET STRING size %ld", + csiz->upper_bound); + ret = OCTET_STRING_per_get_characters(pd, st->buf, + csiz->upper_bound, bpc, unit_bits, + cval->lower_bound, cval->upper_bound, pc); + if(ret > 0) RETURN(RC_FAIL); + } else { + ASN_DEBUG("Decoding BIT STRING size %ld", + csiz->upper_bound); + ret = per_get_many_bits(pd, st->buf, 0, + unit_bits * csiz->upper_bound); + } + if(ret < 0) RETURN(RC_WMORE); + consumed_myself += unit_bits * csiz->upper_bound; + st->buf[st->size] = 0; + if(bpc == 0) { + int ubs = (csiz->upper_bound & 0x7); + st->bits_unused = ubs ? 8 - ubs : 0; + } + RETURN(RC_OK); + } + + st->size = 0; + do { + ssize_t raw_len; + ssize_t len_bytes; + ssize_t len_bits; + void *p; + int ret; + + /* Get the PER length */ + if (csiz->upper_bound - csiz->lower_bound == 0) + /* Indefinite length case */ + raw_len = aper_get_length(pd, -1, csiz->effective_bits, &repeat); + else + raw_len = aper_get_length(pd, csiz->upper_bound - csiz->lower_bound + 1, csiz->effective_bits, &repeat); + repeat = 0; + if(raw_len < 0) RETURN(RC_WMORE); + raw_len += csiz->lower_bound; + + ASN_DEBUG("Got PER length eb %ld, len %ld, %s (%s)", + (long)csiz->effective_bits, (long)raw_len, + repeat ? "repeat" : "once", td->name); + + if (raw_len > 2) { /* X.691 #16 NOTE 1 */ + if (aper_get_align(pd) < 0) + RETURN(RC_FAIL); + } + + if(bpc) { + len_bytes = raw_len * bpc; + len_bits = len_bytes * unit_bits; + } else { + len_bits = raw_len; + len_bytes = (len_bits + 7) >> 3; + if(len_bits & 0x7) + st->bits_unused = 8 - (len_bits & 0x7); + /* len_bits be multiple of 16K if repeat is set */ + } + p = REALLOC(st->buf, st->size + len_bytes + 1); + if(!p) RETURN(RC_FAIL); + st->buf = (uint8_t *)p; + + if(bpc) { + ret = OCTET_STRING_per_get_characters(pd, + &st->buf[st->size], raw_len, bpc, unit_bits, + cval->lower_bound, cval->upper_bound, pc); + if(ret > 0) RETURN(RC_FAIL); + } else { + ret = per_get_many_bits(pd, &st->buf[st->size], + 0, len_bits); + } + if(ret < 0) RETURN(RC_WMORE); + st->size += len_bytes; + } while(repeat); + st->buf[st->size] = 0; /* nul-terminate */ + + return rval; +} + +asn_enc_rval_t +OCTET_STRING_encode_aper(const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, + const void *sptr, asn_per_outp_t *po) { + + const asn_OCTET_STRING_specifics_t *specs = td->specifics + ? (const asn_OCTET_STRING_specifics_t *)td->specifics + : &asn_SPC_OCTET_STRING_specs; + const asn_per_constraints_t *pc = constraints ? constraints + : td->encoding_constraints.per_constraints; + const asn_per_constraint_t *cval; + const asn_per_constraint_t *csiz; + const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; + asn_enc_rval_t er = { 0, 0, 0 }; + int inext = 0; /* Lies not within extension root */ + unsigned int unit_bits; + unsigned int canonical_unit_bits; + unsigned int sizeinunits; + const uint8_t *buf; + int ret; + enum { + OS__BPC_BIT = 0, + OS__BPC_CHAR = 1, + OS__BPC_U16 = 2, + OS__BPC_U32 = 4 + } bpc; /* Bytes per character */ + int ct_extensible; + + if(!st || (!st->buf && st->size)) + ASN__ENCODE_FAILED; + + if(pc) { + cval = &pc->value; + csiz = &pc->size; + } else { + cval = &asn_DEF_OCTET_STRING_constraints.value; + csiz = &asn_DEF_OCTET_STRING_constraints.size; + } + ct_extensible = csiz->flags & APC_EXTENSIBLE; + + switch(specs->subvariant) { + default: + /* case ASN_OSUBV_ANY: + ASN__ENCODE_FAILED; + */ + case ASN_OSUBV_BIT: + canonical_unit_bits = unit_bits = 1; + bpc = OS__BPC_BIT; + sizeinunits = st->size * 8 - (st->bits_unused & 0x07); + ASN_DEBUG("BIT STRING of %d bytes", + sizeinunits); + break; + case ASN_OSUBV_ANY: + case ASN_OSUBV_STR: + canonical_unit_bits = unit_bits = 8; +/* if(cval->flags & APC_CONSTRAINED) + unit_bits = 8; +*/ + bpc = OS__BPC_CHAR; + sizeinunits = st->size; + break; + case ASN_OSUBV_U16: + canonical_unit_bits = unit_bits = 16; + if(cval->flags & APC_CONSTRAINED) + unit_bits = cval->range_bits; + bpc = OS__BPC_U16; + sizeinunits = st->size / 2; + break; + case ASN_OSUBV_U32: + canonical_unit_bits = unit_bits = 32; + if(cval->flags & APC_CONSTRAINED) + unit_bits = cval->range_bits; + bpc = OS__BPC_U32; + sizeinunits = st->size / 4; + break; + } + + ASN_DEBUG("Encoding %s into %d units of %d bits" + " (%ld..%ld, effective %d)%s", + td->name, sizeinunits, unit_bits, + csiz->lower_bound, csiz->upper_bound, + csiz->effective_bits, ct_extensible ? " EXT" : ""); + + /* Figure out wheter size lies within PER visible constraint */ + + if(csiz->effective_bits >= 0) { + if((int)sizeinunits < csiz->lower_bound + || (int)sizeinunits > csiz->upper_bound) { + if(ct_extensible) { + cval = &asn_DEF_OCTET_STRING_constraints.value; + csiz = &asn_DEF_OCTET_STRING_constraints.size; + unit_bits = canonical_unit_bits; + inext = 1; + } else + ASN__ENCODE_FAILED; + } + } else { + inext = 0; + } + + + if(ct_extensible) { + /* Declare whether length is [not] within extension root */ + if(per_put_few_bits(po, inext, 1)) + ASN__ENCODE_FAILED; + } + + /* X.691, #16.5: zero-length encoding */ + /* X.691, #16.6: short fixed length encoding (up to 2 octets) */ + /* X.691, #16.7: long fixed length encoding (up to 64K octets) */ + if(csiz->effective_bits >= 0) { + ASN_DEBUG("Encoding %lu bytes (%ld), length in %d bits", + st->size, sizeinunits - csiz->lower_bound, + csiz->effective_bits); + if (csiz->effective_bits > 0) { + ret = aper_put_length(po, csiz->upper_bound - csiz->lower_bound + 1, sizeinunits - csiz->lower_bound); + if(ret) ASN__ENCODE_FAILED; + } + if (st->size > 2) { /* X.691 #16 NOTE 1 */ + if (aper_put_align(po) < 0) + ASN__ENCODE_FAILED; + } + if(bpc) { + ret = OCTET_STRING_per_put_characters(po, st->buf, + sizeinunits, bpc, unit_bits, + cval->lower_bound, cval->upper_bound, pc); + } else { + ret = per_put_many_bits(po, st->buf, + sizeinunits * unit_bits); + } + if(ret) ASN__ENCODE_FAILED; + ASN__ENCODED_OK(er); + } + + ASN_DEBUG("Encoding %lu bytes", st->size); + + if(sizeinunits == 0) { + if(aper_put_length(po, -1, 0)) + ASN__ENCODE_FAILED; + ASN__ENCODED_OK(er); + } + + buf = st->buf; + while(sizeinunits) { + ssize_t maySave = aper_put_length(po, -1, sizeinunits); + + if(maySave < 0) ASN__ENCODE_FAILED; + + ASN_DEBUG("Encoding %ld of %ld", + (long)maySave, (long)sizeinunits); + + if(bpc) { + ret = OCTET_STRING_per_put_characters(po, buf, + maySave, bpc, unit_bits, + cval->lower_bound, cval->upper_bound, pc); + } else { + ret = per_put_many_bits(po, buf, maySave * unit_bits); + } + if(ret) ASN__ENCODE_FAILED; + + if(bpc) + buf += maySave * bpc; + else + buf += maySave >> 3; + sizeinunits -= maySave; + assert(!(maySave & 0x07) || !sizeinunits); + } + + ASN__ENCODED_OK(er); +} + #endif /* ASN_DISABLE_PER_SUPPORT */ int diff --git a/skeletons/OCTET_STRING.h b/skeletons/OCTET_STRING.h index bb06dc62d..c2f8baed1 100644 --- a/skeletons/OCTET_STRING.h +++ b/skeletons/OCTET_STRING.h @@ -36,6 +36,8 @@ oer_type_decoder_f OCTET_STRING_decode_oer; oer_type_encoder_f OCTET_STRING_encode_oer; per_type_decoder_f OCTET_STRING_decode_uper; per_type_encoder_f OCTET_STRING_encode_uper; +per_type_decoder_f OCTET_STRING_decode_aper; +per_type_encoder_f OCTET_STRING_encode_aper; asn_random_fill_f OCTET_STRING_random_fill; #define OCTET_STRING_constraint asn_generic_no_constraint diff --git a/skeletons/OPEN_TYPE.c b/skeletons/OPEN_TYPE.c index c672992ca..8886f0a02 100644 --- a/skeletons/OPEN_TYPE.c +++ b/skeletons/OPEN_TYPE.c @@ -18,13 +18,15 @@ asn_TYPE_operation_t asn_OP_OPEN_TYPE = { OPEN_TYPE_encode_xer, 0, 0, /* No OER support, use "-gen-OER" to enable */ #ifdef ASN_DISABLE_PER_SUPPORT - 0, 0, + 0, 0, 0, 0, #else OPEN_TYPE_decode_uper, OPEN_TYPE_encode_uper, + OPEN_TYPE_decode_aper, + OPEN_TYPE_encode_aper, #endif 0, /* Random fill is not supported for open type */ - 0, /* Use generic outmost tag fetcher */ + 0 /* Use generic outmost tag fetcher */ }; #undef ADVANCE diff --git a/skeletons/OPEN_TYPE.h b/skeletons/OPEN_TYPE.h index d0f02fd79..4312e6023 100644 --- a/skeletons/OPEN_TYPE.h +++ b/skeletons/OPEN_TYPE.h @@ -20,6 +20,8 @@ extern "C" { #define OPEN_TYPE_decode_xer NULL #define OPEN_TYPE_encode_xer CHOICE_encode_xer #define OPEN_TYPE_decode_uper NULL +#define OPEN_TYPE_decode_aper NULL +#define OPEN_TYPE_encode_aper CHOICE_encode_aper extern asn_TYPE_operation_t asn_OP_OPEN_TYPE; diff --git a/skeletons/ObjectDescriptor.c b/skeletons/ObjectDescriptor.c index 79042c0a6..5d8bfb2d6 100644 --- a/skeletons/ObjectDescriptor.c +++ b/skeletons/ObjectDescriptor.c @@ -30,9 +30,13 @@ asn_TYPE_operation_t asn_OP_ObjectDescriptor = { #ifdef ASN_DISABLE_PER_SUPPORT 0, 0, + 0, + 0, #else OCTET_STRING_decode_uper, OCTET_STRING_encode_uper, + OCTET_STRING_decode_aper, + OCTET_STRING_encode_aper, #endif /* ASN_DISABLE_PER_SUPPORT */ 0, /* Not supported for ObjectDescriptor */ 0 /* Use generic outmost tag fetcher */ diff --git a/skeletons/ObjectDescriptor.h b/skeletons/ObjectDescriptor.h index 526511e34..fa1c1fcc0 100644 --- a/skeletons/ObjectDescriptor.h +++ b/skeletons/ObjectDescriptor.h @@ -25,6 +25,8 @@ extern asn_TYPE_operation_t asn_OP_ObjectDescriptor; #define ObjectDescriptor_encode_xer OCTET_STRING_encode_xer_utf8 #define ObjectDescriptor_decode_uper OCTET_STRING_decode_uper #define ObjectDescriptor_encode_uper OCTET_STRING_encode_uper +#define ObjectDescriptor_decode_aper OCTET_STRING_decode_aper +#define ObjectDescriptor_encode_aper OCTET_STRING_encode_aper #ifdef __cplusplus } diff --git a/skeletons/PrintableString.c b/skeletons/PrintableString.c index ffc08b7c0..8fc39399e 100644 --- a/skeletons/PrintableString.c +++ b/skeletons/PrintableString.c @@ -65,9 +65,13 @@ asn_TYPE_operation_t asn_OP_PrintableString = { #ifdef ASN_DISABLE_PER_SUPPORT 0, 0, + 0, + 0, #else OCTET_STRING_decode_uper, OCTET_STRING_encode_uper, + OCTET_STRING_decode_aper, + OCTET_STRING_encode_aper, #endif /* ASN_DISABLE_PER_SUPPORT */ OCTET_STRING_random_fill, 0 /* Use generic outmost tag fetcher */ diff --git a/skeletons/PrintableString.h b/skeletons/PrintableString.h index 6a49d16fe..8c2b61ab2 100644 --- a/skeletons/PrintableString.h +++ b/skeletons/PrintableString.h @@ -27,6 +27,8 @@ asn_constr_check_f PrintableString_constraint; #define PrintableString_encode_xer OCTET_STRING_encode_xer_utf8 #define PrintableString_decode_uper OCTET_STRING_decode_uper #define PrintableString_encode_uper OCTET_STRING_encode_uper +#define PrintableString_decode_aper OCTET_STRING_decode_aper +#define PrintableString_encode_aper OCTET_STRING_encode_aper #ifdef __cplusplus } diff --git a/skeletons/REAL.c b/skeletons/REAL.c index f1d06650e..7dfcaece4 100644 --- a/skeletons/REAL.c +++ b/skeletons/REAL.c @@ -84,9 +84,13 @@ asn_TYPE_operation_t asn_OP_REAL = { #ifdef ASN_DISABLE_PER_SUPPORT 0, 0, + 0, + 0, #else REAL_decode_uper, REAL_encode_uper, + REAL_decode_aper, + REAL_encode_aper, #endif /* ASN_DISABLE_PER_SUPPORT */ REAL_random_fill, 0 /* Use generic outmost tag fetcher */ @@ -946,6 +950,23 @@ REAL_encode_uper(const asn_TYPE_descriptor_t *td, return OCTET_STRING_encode_uper(td, 0, sptr, po); } +asn_dec_rval_t +REAL_decode_aper(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, + void **sptr, asn_per_data_t *pd) { + (void)constraints; /* No PER visible constraints */ + return OCTET_STRING_decode_aper(opt_codec_ctx, td, 0, sptr, pd); +} + +asn_enc_rval_t +REAL_encode_aper(const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, + const void *sptr, asn_per_outp_t *po) { + (void)constraints; /* No PER visible constraints */ + return OCTET_STRING_encode_aper(td, 0, sptr, po); +} + #endif /* ASN_DISABLE_PER_SUPPORT */ asn_random_fill_result_t diff --git a/skeletons/REAL.h b/skeletons/REAL.h index d71147abd..fce67140b 100644 --- a/skeletons/REAL.h +++ b/skeletons/REAL.h @@ -23,6 +23,8 @@ oer_type_decoder_f REAL_decode_oer; oer_type_encoder_f REAL_encode_oer; per_type_decoder_f REAL_decode_uper; per_type_encoder_f REAL_encode_uper; +per_type_decoder_f REAL_decode_aper; +per_type_encoder_f REAL_encode_aper; xer_type_decoder_f REAL_decode_xer; xer_type_encoder_f REAL_encode_xer; asn_random_fill_f REAL_random_fill; diff --git a/skeletons/RELATIVE-OID.c b/skeletons/RELATIVE-OID.c index 2f6295b19..81b9d7a48 100644 --- a/skeletons/RELATIVE-OID.c +++ b/skeletons/RELATIVE-OID.c @@ -34,9 +34,13 @@ asn_TYPE_operation_t asn_OP_RELATIVE_OID = { #ifdef ASN_DISABLE_PER_SUPPORT 0, 0, + 0, + 0, #else OCTET_STRING_decode_uper, OCTET_STRING_encode_uper, + OCTET_STRING_decode_aper, + OCTET_STRING_encode_aper, #endif /* ASN_DISABLE_PER_SUPPORT */ RELATIVE_OID_random_fill, 0 /* Use generic outmost tag fetcher */ diff --git a/skeletons/RELATIVE-OID.h b/skeletons/RELATIVE-OID.h index 289bbca7f..a51bf5160 100644 --- a/skeletons/RELATIVE-OID.h +++ b/skeletons/RELATIVE-OID.h @@ -31,6 +31,8 @@ asn_random_fill_f RELATIVE_OID_random_fill; #define RELATIVE_OID_encode_oer oer_encode_primitive #define RELATIVE_OID_decode_uper OCTET_STRING_decode_uper #define RELATIVE_OID_encode_uper OCTET_STRING_encode_uper +#define RELATIVE_OID_decode_aper OCTET_STRING_decode_aper +#define RELATIVE_OID_encode_aper OCTET_STRING_encode_aper /********************************** * Some handy conversion routines * diff --git a/skeletons/T61String.c b/skeletons/T61String.c index c7e5f009c..d3de88b22 100644 --- a/skeletons/T61String.c +++ b/skeletons/T61String.c @@ -30,9 +30,13 @@ asn_TYPE_operation_t asn_OP_T61String = { #ifdef ASN_DISABLE_PER_SUPPORT 0, 0, + 0, + 0, #else OCTET_STRING_decode_uper, OCTET_STRING_encode_uper, + OCTET_STRING_decode_aper, + OCTET_STRING_encode_aper, #endif /* ASN_DISABLE_PER_SUPPORT */ OCTET_STRING_random_fill, 0 /* Use generic outmost tag fetcher */ diff --git a/skeletons/T61String.h b/skeletons/T61String.h index 3f4707ac4..9e9e380e4 100644 --- a/skeletons/T61String.h +++ b/skeletons/T61String.h @@ -26,6 +26,8 @@ extern asn_TYPE_operation_t asn_OP_T61String; #define T61String_encode_xer OCTET_STRING_encode_xer #define T61String_decode_uper OCTET_STRING_decode_uper #define T61String_encode_uper OCTET_STRING_encode_uper +#define T61String_decode_aper OCTET_STRING_decode_aper +#define T61String_encode_aper OCTET_STRING_encode_aper #ifdef __cplusplus } diff --git a/skeletons/TeletexString.c b/skeletons/TeletexString.c index 6c13f7346..9756c72e7 100644 --- a/skeletons/TeletexString.c +++ b/skeletons/TeletexString.c @@ -30,9 +30,13 @@ asn_TYPE_operation_t asn_OP_TeletexString = { #ifdef ASN_DISABLE_PER_SUPPORT 0, 0, + 0, + 0, #else OCTET_STRING_decode_uper, OCTET_STRING_encode_uper, + OCTET_STRING_decode_aper, + OCTET_STRING_encode_aper, #endif /* ASN_DISABLE_PER_SUPPORT */ OCTET_STRING_random_fill, 0 /* Use generic outmost tag fetcher */ diff --git a/skeletons/TeletexString.h b/skeletons/TeletexString.h index a43f3e34e..9f04aef28 100644 --- a/skeletons/TeletexString.h +++ b/skeletons/TeletexString.h @@ -26,6 +26,8 @@ extern asn_TYPE_operation_t asn_OP_TeletexString; #define TeletexString_encode_xer OCTET_STRING_encode_xer #define TeletexString_decode_uper OCTET_STRING_decode_uper #define TeletexString_encode_uper OCTET_STRING_encode_uper +#define TeletexString_decode_aper OCTET_STRING_decode_aper +#define TeletexString_encode_aper OCTET_STRING_encode_aper #ifdef __cplusplus } diff --git a/skeletons/UTCTime.c b/skeletons/UTCTime.c index ffbed58af..07891acf7 100644 --- a/skeletons/UTCTime.c +++ b/skeletons/UTCTime.c @@ -46,9 +46,13 @@ asn_TYPE_operation_t asn_OP_UTCTime = { #ifdef ASN_DISABLE_PER_SUPPORT 0, 0, + 0, + 0, #else OCTET_STRING_decode_uper, OCTET_STRING_encode_uper, + OCTET_STRING_decode_aper, + OCTET_STRING_encode_aper, #endif /* ASN_DISABLE_PER_SUPPORT */ UTCTime_random_fill, 0 /* Use generic outmost tag fetcher */ diff --git a/skeletons/UTCTime.h b/skeletons/UTCTime.h index 3c5c0c477..295f1563b 100644 --- a/skeletons/UTCTime.h +++ b/skeletons/UTCTime.h @@ -28,6 +28,8 @@ asn_random_fill_f UTCTime_random_fill; #define UTCTime_decode_xer OCTET_STRING_decode_xer_utf8 #define UTCTime_decode_uper OCTET_STRING_decode_uper #define UTCTime_encode_uper OCTET_STRING_encode_uper +#define UTCTime_decode_aper OCTET_STRING_decode_aper +#define UTCTime_encode_aper OCTET_STRING_encode_aper /*********************** * Some handy helpers. * diff --git a/skeletons/UTF8String.c b/skeletons/UTF8String.c index a82da366d..c023ca1c6 100644 --- a/skeletons/UTF8String.c +++ b/skeletons/UTF8String.c @@ -31,9 +31,13 @@ asn_TYPE_operation_t asn_OP_UTF8String = { #ifdef ASN_DISABLE_PER_SUPPORT 0, 0, + 0, + 0, #else OCTET_STRING_decode_uper, OCTET_STRING_encode_uper, + OCTET_STRING_decode_aper, + OCTET_STRING_encode_aper, #endif /* ASN_DISABLE_PER_SUPPORT */ UTF8String_random_fill, 0 /* Use generic outmost tag fetcher */ diff --git a/skeletons/UTF8String.h b/skeletons/UTF8String.h index 030448326..7ad9c82d8 100644 --- a/skeletons/UTF8String.h +++ b/skeletons/UTF8String.h @@ -29,6 +29,8 @@ asn_random_fill_f UTF8String_random_fill; #define UTF8String_encode_xer OCTET_STRING_encode_xer_utf8 #define UTF8String_decode_uper OCTET_STRING_decode_uper #define UTF8String_encode_uper OCTET_STRING_encode_uper +#define UTF8String_decode_aper OCTET_STRING_decode_aper +#define UTF8String_encode_aper OCTET_STRING_encode_aper /* * Returns length of the given UTF-8 string in characters, diff --git a/skeletons/UniversalString.c b/skeletons/UniversalString.c index da28874a9..2a1880fea 100644 --- a/skeletons/UniversalString.c +++ b/skeletons/UniversalString.c @@ -41,9 +41,13 @@ asn_TYPE_operation_t asn_OP_UniversalString = { #ifdef ASN_DISABLE_PER_SUPPORT 0, 0, + 0, + 0, #else OCTET_STRING_decode_uper, OCTET_STRING_encode_uper, + OCTET_STRING_decode_aper, + OCTET_STRING_encode_aper, #endif /* ASN_DISABLE_PER_SUPPORT */ OCTET_STRING_random_fill, 0 /* Use generic outmost tag fetcher */ diff --git a/skeletons/UniversalString.h b/skeletons/UniversalString.h index df0c07ad6..510807a01 100644 --- a/skeletons/UniversalString.h +++ b/skeletons/UniversalString.h @@ -28,6 +28,8 @@ xer_type_encoder_f UniversalString_encode_xer; #define UniversalString_encode_der OCTET_STRING_encode_der #define UniversalString_decode_uper OCTET_STRING_decode_uper #define UniversalString_encode_uper OCTET_STRING_encode_uper +#define UniversalString_decode_aper OCTET_STRING_decode_aper +#define UniversalString_encode_aper OCTET_STRING_encode_aper #ifdef __cplusplus } diff --git a/skeletons/VideotexString.c b/skeletons/VideotexString.c index 06fe4a7f7..69417bd51 100644 --- a/skeletons/VideotexString.c +++ b/skeletons/VideotexString.c @@ -30,9 +30,13 @@ asn_TYPE_operation_t asn_OP_VideotexString = { #ifdef ASN_DISABLE_PER_SUPPORT 0, 0, + 0, + 0, #else OCTET_STRING_decode_uper, /* Implemented in terms of OCTET STRING */ OCTET_STRING_encode_uper, + OCTET_STRING_decode_aper, /* Implemented in terms of OCTET STRING */ + OCTET_STRING_encode_aper, #endif /* ASN_DISABLE_PER_SUPPORT */ OCTET_STRING_random_fill, 0 /* Use generic outmost tag fetcher */ diff --git a/skeletons/VideotexString.h b/skeletons/VideotexString.h index 37177d37d..b53538998 100644 --- a/skeletons/VideotexString.h +++ b/skeletons/VideotexString.h @@ -26,6 +26,8 @@ extern asn_TYPE_operation_t asn_OP_VideotexString; #define VideotexString_encode_xer OCTET_STRING_encode_xer #define VideotexString_decode_uper OCTET_STRING_decode_uper #define VideotexString_encode_uper OCTET_STRING_encode_uper +#define VideotexString_decode_aper OCTET_STRING_decode_aper +#define VideotexString_encode_aper OCTET_STRING_encode_aper #ifdef __cplusplus } diff --git a/skeletons/VisibleString.c b/skeletons/VisibleString.c index e163791e5..03fef8b8a 100644 --- a/skeletons/VisibleString.c +++ b/skeletons/VisibleString.c @@ -35,9 +35,13 @@ asn_TYPE_operation_t asn_OP_VisibleString = { #ifdef ASN_DISABLE_PER_SUPPORT 0, 0, + 0, + 0, #else OCTET_STRING_decode_uper, OCTET_STRING_encode_uper, + OCTET_STRING_decode_aper, + OCTET_STRING_encode_aper, #endif /* ASN_DISABLE_PER_SUPPORT */ OCTET_STRING_random_fill, 0 /* Use generic outmost tag fetcher */ diff --git a/skeletons/VisibleString.h b/skeletons/VisibleString.h index 842d56eab..ad5f713ed 100644 --- a/skeletons/VisibleString.h +++ b/skeletons/VisibleString.h @@ -28,6 +28,8 @@ asn_constr_check_f VisibleString_constraint; #define VisibleString_encode_xer OCTET_STRING_encode_xer #define VisibleString_decode_uper OCTET_STRING_decode_uper #define VisibleString_encode_uper OCTET_STRING_encode_uper +#define VisibleString_decode_aper OCTET_STRING_decode_aper +#define VisibleString_encode_aper OCTET_STRING_encode_aper #ifdef __cplusplus } diff --git a/skeletons/asn_application.h b/skeletons/asn_application.h index a125562c3..7dd52ea0e 100644 --- a/skeletons/asn_application.h +++ b/skeletons/asn_application.h @@ -51,6 +51,8 @@ enum asn_transfer_syntax { */ ATS_UNALIGNED_BASIC_PER, ATS_UNALIGNED_CANONICAL_PER, + ATS_ALIGNED_BASIC_PER, + ATS_ALIGNED_CANONICAL_PER, /* * X.693: * XER: XML Encoding Rules. diff --git a/skeletons/constr_CHOICE.c b/skeletons/constr_CHOICE.c index 628979ec2..402b6be9a 100644 --- a/skeletons/constr_CHOICE.c +++ b/skeletons/constr_CHOICE.c @@ -1010,6 +1010,171 @@ CHOICE_encode_uper(const asn_TYPE_descriptor_t *td, } } +asn_dec_rval_t +CHOICE_decode_aper(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { + const asn_CHOICE_specifics_t *specs = (const asn_CHOICE_specifics_t *)td->specifics; + asn_dec_rval_t rv; + const asn_per_constraint_t *ct; + asn_TYPE_member_t *elm; /* CHOICE's element */ + void *memb_ptr; + void **memb_ptr2; + void *st = *sptr; + int value; + + if(ASN__STACK_OVERFLOW_CHECK(opt_codec_ctx)) + ASN__DECODE_FAILED; + + /* + * Create the target structure if it is not present already. + */ + if(!st) { + st = *sptr = CALLOC(1, specs->struct_size); + if(!st) ASN__DECODE_FAILED; + } + + if(constraints) ct = &constraints->value; + else if(td->encoding_constraints.per_constraints) + ct = &td->encoding_constraints.per_constraints->value; + else ct = 0; + + if(ct && ct->flags & APC_EXTENSIBLE) { + value = per_get_few_bits(pd, 1); + if(value < 0) ASN__DECODE_STARVED; + if(value) ct = 0; /* Not restricted */ + } + + if(ct && ct->range_bits >= 0) { + value = per_get_few_bits(pd, ct->range_bits); + if(value < 0) ASN__DECODE_STARVED; + ASN_DEBUG("CHOICE %s got index %d in range %d", + td->name, value, ct->range_bits); + if(value > ct->upper_bound) + ASN__DECODE_FAILED; + } else { + if(specs->ext_start == -1) + ASN__DECODE_FAILED; + value = uper_get_nsnnwn(pd); + if(value < 0) ASN__DECODE_STARVED; + value += specs->ext_start; + if((unsigned)value >= td->elements_count) + ASN__DECODE_FAILED; + } + + /* Adjust if canonical order is different from natural order */ + if(specs->from_canonical_order) + value = specs->from_canonical_order[value]; + + /* Set presence to be able to free it later */ + _set_present_idx(st, specs->pres_offset, specs->pres_size, value + 1); + + elm = &td->elements[value]; + if(elm->flags & ATF_POINTER) { + /* Member is a pointer to another structure */ + memb_ptr2 = (void **)((char *)st + elm->memb_offset); + } else { + memb_ptr = (char *)st + elm->memb_offset; + memb_ptr2 = &memb_ptr; + } + ASN_DEBUG("Discovered CHOICE %s encodes %s", td->name, elm->name); + + if(ct && ct->range_bits >= 0) { + rv = elm->type->op->aper_decoder(opt_codec_ctx, elm->type, + elm->encoding_constraints.per_constraints, memb_ptr2, pd); + } else { + rv = uper_open_type_get(opt_codec_ctx, elm->type, + elm->encoding_constraints.per_constraints, memb_ptr2, pd); + } + + if(rv.code != RC_OK) + ASN_DEBUG("Failed to decode %s in %s (CHOICE) %d", + elm->name, td->name, rv.code); + return rv; +} + +asn_enc_rval_t +CHOICE_encode_aper(const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, + const void *sptr, asn_per_outp_t *po) { + const asn_CHOICE_specifics_t *specs = (const asn_CHOICE_specifics_t *)td->specifics; + const asn_TYPE_member_t *elm; /* CHOICE's element */ + const asn_per_constraint_t *ct; + const void *memb_ptr; + int present; + + if(!sptr) ASN__ENCODE_FAILED; + + ASN_DEBUG("Encoding %s as CHOICE using ALIGNED PER", td->name); + + if(constraints) ct = &constraints->value; + else if(td->encoding_constraints.per_constraints) + ct = &td->encoding_constraints.per_constraints->value; + else ct = 0; + + present = _fetch_present_idx(sptr, + specs->pres_offset, specs->pres_size); + + /* + * If the structure was not initialized properly, it cannot be encoded: + * can't deduce what to encode in the choice type. + */ + if(present <= 0 || (unsigned)present > td->elements_count) + ASN__ENCODE_FAILED; + else + present--; + + /* Adjust if canonical order is different from natural order */ + if(specs->to_canonical_order) + present = specs->to_canonical_order[present]; + + ASN_DEBUG("Encoding %s CHOICE element %d", td->name, present); + + if(ct && ct->range_bits >= 0) { + if(present < ct->lower_bound + || present > ct->upper_bound) { + if(ct->flags & APC_EXTENSIBLE) { + if(per_put_few_bits(po, 1, 1)) + ASN__ENCODE_FAILED; + } else { + ASN__ENCODE_FAILED; + } + ct = 0; + } + } + if(ct && ct->flags & APC_EXTENSIBLE) { + if(per_put_few_bits(po, 0, 1)) + ASN__ENCODE_FAILED; + } + + elm = &td->elements[present]; + if(elm->flags & ATF_POINTER) { + /* Member is a pointer to another structure */ + memb_ptr = *(const void *const *)((const char *)sptr + elm->memb_offset); + if(!memb_ptr) ASN__ENCODE_FAILED; + } else { + memb_ptr = (const char *)sptr + elm->memb_offset; + } + + if(ct && ct->range_bits >= 0) { + if(per_put_few_bits(po, present, ct->range_bits)) + ASN__ENCODE_FAILED; + + return elm->type->op->aper_encoder(elm->type, elm->encoding_constraints.per_constraints, + memb_ptr, po); + } else { + asn_enc_rval_t rval; + if(specs->ext_start == -1) + ASN__ENCODE_FAILED; + if(aper_put_nsnnwn(po, ct->range_bits, present - specs->ext_start)) + ASN__ENCODE_FAILED; + if(aper_open_type_put(elm->type, elm->encoding_constraints.per_constraints, + memb_ptr, po)) + ASN__ENCODE_FAILED; + rval.encoded = 0; + ASN__ENCODED_OK(rval); + } +} int CHOICE_print(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, @@ -1331,9 +1496,13 @@ asn_TYPE_operation_t asn_OP_CHOICE = { #ifdef ASN_DISABLE_PER_SUPPORT 0, 0, + 0, + 0, #else CHOICE_decode_uper, CHOICE_encode_uper, + CHOICE_decode_aper, + CHOICE_encode_aper, #endif /* ASN_DISABLE_PER_SUPPORT */ CHOICE_random_fill, CHOICE_outmost_tag diff --git a/skeletons/constr_CHOICE.h b/skeletons/constr_CHOICE.h index 764948094..a1999edc4 100644 --- a/skeletons/constr_CHOICE.h +++ b/skeletons/constr_CHOICE.h @@ -51,6 +51,8 @@ oer_type_decoder_f CHOICE_decode_oer; oer_type_encoder_f CHOICE_encode_oer; per_type_decoder_f CHOICE_decode_uper; per_type_encoder_f CHOICE_encode_uper; +per_type_decoder_f CHOICE_decode_aper; +per_type_encoder_f CHOICE_encode_aper; asn_outmost_tag_f CHOICE_outmost_tag; asn_random_fill_f CHOICE_random_fill; extern asn_TYPE_operation_t asn_OP_CHOICE; diff --git a/skeletons/constr_SEQUENCE.c b/skeletons/constr_SEQUENCE.c index 2fbf97b67..b68d1f29e 100644 --- a/skeletons/constr_SEQUENCE.c +++ b/skeletons/constr_SEQUENCE.c @@ -1484,6 +1484,428 @@ SEQUENCE_encode_uper(const asn_TYPE_descriptor_t *td, ASN__ENCODED_OK(er); } +asn_dec_rval_t +SEQUENCE_decode_aper(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { + const asn_SEQUENCE_specifics_t *specs = (const asn_SEQUENCE_specifics_t *)td->specifics; + void *st = *sptr; /* Target structure. */ + int extpresent; /* Extension additions are present */ + uint8_t *opres; /* Presence of optional root members */ + asn_per_data_t opmd; + asn_dec_rval_t rv; + size_t edx; + + (void)constraints; + + if(ASN__STACK_OVERFLOW_CHECK(opt_codec_ctx)) + ASN__DECODE_FAILED; + + if(!st) { + st = *sptr = CALLOC(1, specs->struct_size); + if(!st) ASN__DECODE_FAILED; + } + + ASN_DEBUG("Decoding %s as SEQUENCE (APER)", td->name); + + /* Handle extensions */ + if(specs->first_extension < 0) { + extpresent = 0; + } else { + extpresent = per_get_few_bits(pd, 1); + if(extpresent < 0) ASN__DECODE_STARVED; + } + + /* Prepare a place and read-in the presence bitmap */ + memset(&opmd, 0, sizeof(opmd)); + if(specs->roms_count) { + opres = (uint8_t *)MALLOC(((specs->roms_count + 7) >> 3) + 1); + if(!opres) ASN__DECODE_FAILED; + /* Get the presence map */ + if(per_get_many_bits(pd, opres, 0, specs->roms_count)) { + FREEMEM(opres); + ASN__DECODE_STARVED; + } + opmd.buffer = opres; + opmd.nbits = specs->roms_count; + ASN_DEBUG("Read in presence bitmap for %s of %d bits (%x..)", + td->name, specs->roms_count, *opres); + } else { + opres = 0; + } + + /* + * Get the sequence ROOT elements. + */ + for(edx = 0; edx < td->elements_count; edx++) { + asn_TYPE_member_t *elm = &td->elements[edx]; + void *memb_ptr; /* Pointer to the member */ + void **memb_ptr2; /* Pointer to that pointer */ + int padding; + + if(IN_EXTENSION_GROUP(specs, edx)) + continue; + + /* Fetch the pointer to this member */ + if(elm->flags & ATF_POINTER) { + memb_ptr2 = (void **)((char *)st + elm->memb_offset); + } else { + memb_ptr = (char *)st + elm->memb_offset; + memb_ptr2 = &memb_ptr; + } + + /* Get Padding */ + padding = (8 - (pd->moved % 8)) % 8; + if(padding > 0) + ASN_DEBUG("For element %s,offset= %ld Padding bits = %d", td->name, pd->moved, padding); +#if 0 /* old way of removing padding */ + per_get_few_bits(pd, padding); +#else /* Experimental fix proposed by @mhanna123 */ + if(edx != (td->elements_count-1)) + per_get_few_bits(pd, padding); + else { + if(specs->roms_count && (padding > 0)) + ASN_DEBUG(">>>>> not skipping padding of %d bits for element:%ld out of %d", padding, edx, td->elements_count); + else + per_get_few_bits(pd, padding); + } +#endif /* dealing with padding */ + + /* Deal with optionality */ + if(elm->optional) { + int present = per_get_few_bits(&opmd, 1); + ASN_DEBUG("Member %s->%s is optional, p=%d (%d->%d)", + td->name, elm->name, present, + (int)opmd.nboff, (int)opmd.nbits); + if(present == 0) { + /* This element is not present */ + if(elm->default_value_set) { + /* Fill-in DEFAULT */ + if(elm->default_value_set(memb_ptr2)) { + FREEMEM(opres); + ASN__DECODE_FAILED; + } + ASN_DEBUG("Filled-in default"); + } + /* The member is just not present */ + continue; + } + /* Fall through */ + } + + /* Fetch the member from the stream */ + ASN_DEBUG("Decoding member %s in %s", elm->name, td->name); + rv = elm->type->op->aper_decoder(opt_codec_ctx, elm->type, + elm->encoding_constraints.per_constraints, memb_ptr2, pd); + if(rv.code != RC_OK) { + ASN_DEBUG("Failed decode %s in %s", + elm->name, td->name); + FREEMEM(opres); + return rv; + } + } + + /* Optionality map is not needed anymore */ + FREEMEM(opres); + + /* + * Deal with extensions. + */ + if(extpresent) { + ssize_t bmlength; + uint8_t *epres; /* Presence of extension members */ + asn_per_data_t epmd; + + bmlength = uper_get_nslength(pd); + if(bmlength < 0) ASN__DECODE_STARVED; + + ASN_DEBUG("Extensions %ld present in %s", bmlength, td->name); + + epres = (uint8_t *)MALLOC((bmlength + 15) >> 3); + if(!epres) ASN__DECODE_STARVED; + + /* Get the extensions map */ + if(per_get_many_bits(pd, epres, 0, bmlength)) + ASN__DECODE_STARVED; + + memset(&epmd, 0, sizeof(epmd)); + epmd.buffer = epres; + epmd.nbits = bmlength; + ASN_DEBUG("Read in extensions bitmap for %s of %ld bits (%x..)", + td->name, bmlength, *epres); + + /* Go over extensions and read them in */ + for(edx = specs->first_extension; edx < td->elements_count; edx++) { + asn_TYPE_member_t *elm = &td->elements[edx]; + void *memb_ptr; /* Pointer to the member */ + void **memb_ptr2; /* Pointer to that pointer */ + int present; + + if(!IN_EXTENSION_GROUP(specs, edx)) { + ASN_DEBUG("%ld is not extension", edx); + continue; + } + + /* Fetch the pointer to this member */ + if(elm->flags & ATF_POINTER) { + memb_ptr2 = (void **)((char *)st + elm->memb_offset); + } else { + memb_ptr = (void *)((char *)st + elm->memb_offset); + memb_ptr2 = &memb_ptr; + } + + present = per_get_few_bits(&epmd, 1); + if(present <= 0) { + if(present < 0) break; /* No more extensions */ + continue; + } + + ASN_DEBUG("Decoding member %s in %s %p", elm->name, td->name, *memb_ptr2); + rv = uper_open_type_get(opt_codec_ctx, elm->type, + elm->encoding_constraints.per_constraints, memb_ptr2, pd); + if(rv.code != RC_OK) { + FREEMEM(epres); + return rv; + } + } + + /* Skip over overflow extensions which aren't present + * in this system's version of the protocol */ + for(;;) { + ASN_DEBUG("Getting overflow extensions"); + switch(per_get_few_bits(&epmd, 1)) { + case -1: + break; + case 0: + continue; + default: + if(uper_open_type_skip(opt_codec_ctx, pd)) { + FREEMEM(epres); + ASN__DECODE_STARVED; + } + } + break; + } + + FREEMEM(epres); + } + + /* Fill DEFAULT members in extensions */ + for(edx = specs->roms_count; edx < specs->roms_count + + specs->aoms_count; edx++) { + asn_TYPE_member_t *elm = &td->elements[edx]; + void **memb_ptr2; /* Pointer to member pointer */ + + if(!elm->default_value_set) continue; + + /* Fetch the pointer to this member */ + if(elm->flags & ATF_POINTER) { + memb_ptr2 = (void **)((char *)st + + elm->memb_offset); + if(*memb_ptr2) continue; + } else { + continue; /* Extensions are all optionals */ + } + + /* Set default value */ + if(elm->default_value_set(memb_ptr2)) { + ASN__DECODE_FAILED; + } + } + + rv.consumed = 0; + rv.code = RC_OK; + return rv; +} + +static int +SEQUENCE_handle_extensions_aper(const asn_TYPE_descriptor_t *td, + const void *sptr, + asn_per_outp_t *po1, asn_per_outp_t *po2) { + const asn_SEQUENCE_specifics_t *specs + = (const asn_SEQUENCE_specifics_t *)td->specifics; + int exts_present = 0; + int exts_count = 0; + size_t edx; + + if(specs->first_extension < 0) { + return 0; + } + + /* Find out which extensions are present */ + for(edx = specs->first_extension; edx < td->elements_count; edx++) { + asn_TYPE_member_t *elm = &td->elements[edx]; + const void *memb_ptr; /* Pointer to the member */ + const void * const *memb_ptr2; /* Pointer to that pointer */ + int present; + + if(!IN_EXTENSION_GROUP(specs, edx)) { + ASN_DEBUG("%s (@%ld) is not extension", elm->type->name, edx); + continue; + } + + /* Fetch the pointer to this member */ + if(elm->flags & ATF_POINTER) { + memb_ptr2 = (const void * const *)((const char *)sptr + elm->memb_offset); + present = (*memb_ptr2 != 0); + } else { + memb_ptr = (const void *)((const char *)sptr + elm->memb_offset); + memb_ptr2 = &memb_ptr; + present = 1; + } + + ASN_DEBUG("checking %s (@%ld) present => %d", + elm->type->name, edx, present); + exts_count++; + exts_present += present; + + /* Encode as presence marker */ + if(po1 && per_put_few_bits(po1, present, 1)) + return -1; + /* Encode as open type field */ + if(po2 && present && aper_open_type_put(elm->type, + elm->encoding_constraints.per_constraints, *memb_ptr2, po2)) + return -1; + + } + + return exts_present ? exts_count : 0; +} + +asn_enc_rval_t +SEQUENCE_encode_aper(const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, + const void *sptr, asn_per_outp_t *po) { + const asn_SEQUENCE_specifics_t *specs + = (const asn_SEQUENCE_specifics_t *)td->specifics; + asn_enc_rval_t er; + int n_extensions; + size_t edx; + size_t i; + + (void)constraints; + + if(!sptr) + ASN__ENCODE_FAILED; + + er.encoded = 0; + + ASN_DEBUG("Encoding %s as SEQUENCE (APER)", td->name); + + /* + * X.691#18.1 Whether structure is extensible + * and whether to encode extensions + */ + if(specs->first_extension < 0) { + n_extensions = 0; /* There are no extensions to encode */ + } else { + n_extensions = SEQUENCE_handle_extensions_aper(td, sptr, 0, 0); + if(n_extensions < 0) ASN__ENCODE_FAILED; + if(per_put_few_bits(po, n_extensions ? 1 : 0, 1)) { + ASN__ENCODE_FAILED; + } + } + + /* Encode a presence bitmap */ + for(i = 0; i < specs->roms_count; i++) { + asn_TYPE_member_t *elm; + const void *memb_ptr; /* Pointer to the member */ + const void * const *memb_ptr2; /* Pointer to that pointer */ + int present; + + edx = specs->oms[i]; + elm = &td->elements[edx]; + + /* Fetch the pointer to this member */ + if(elm->flags & ATF_POINTER) { + memb_ptr2 = (const void * const *)((const char *)sptr + elm->memb_offset); + present = (*memb_ptr2 != 0); + } else { + memb_ptr = (const void *)((const char *)sptr + elm->memb_offset); + memb_ptr2 = &memb_ptr; + present = 1; + } + + /* Eliminate default values */ + if(present && elm->default_value_cmp + && elm->default_value_cmp(memb_ptr2) == 1) + present = 0; + + ASN_DEBUG("Element %s %s %s->%s is %s", + elm->flags & ATF_POINTER ? "ptr" : "inline", + elm->default_value_cmp ? "def" : "wtv", + td->name, elm->name, present ? "present" : "absent"); + if(per_put_few_bits(po, present, 1)) + ASN__ENCODE_FAILED; + } + + /* + * Encode the sequence ROOT elements. + */ + ASN_DEBUG("first_extension = %d, elements = %d", specs->first_extension, + td->elements_count); + for(edx = 0; + edx < ((specs->first_extension < 0) ? td->elements_count + : (size_t)specs->first_extension); + edx++) { + asn_TYPE_member_t *elm = &td->elements[edx]; + const void *memb_ptr; /* Pointer to the member */ + const void * const *memb_ptr2; /* Pointer to that pointer */ + + if(IN_EXTENSION_GROUP(specs, edx)) + continue; + + ASN_DEBUG("About to encode %s", elm->type->name); + + /* Fetch the pointer to this member */ + if(elm->flags & ATF_POINTER) { + memb_ptr2 = (const void * const *)((const char *)sptr + elm->memb_offset); + if(!*memb_ptr2) { + ASN_DEBUG("Element %s %ld not present", + elm->name, edx); + if(elm->optional) + continue; + /* Mandatory element is missing */ + ASN__ENCODE_FAILED; + } + } else { + memb_ptr = (const void *)((const char *)sptr + elm->memb_offset); + memb_ptr2 = &memb_ptr; + } + + /* Eliminate default values */ + if(elm->default_value_cmp && elm->default_value_cmp(memb_ptr2) == 1) + continue; + + ASN_DEBUG("Encoding %s->%s", td->name, elm->name); + er = elm->type->op->aper_encoder(elm->type, elm->encoding_constraints.per_constraints, + *memb_ptr2, po); + if(er.encoded == -1) + return er; + } + + /* No extensions to encode */ + if(!n_extensions) ASN__ENCODED_OK(er); + + ASN_DEBUG("Length of %d bit-map", n_extensions); + /* #18.8. Write down the presence bit-map length. */ + if(aper_put_nslength(po, n_extensions)) + ASN__ENCODE_FAILED; + + ASN_DEBUG("Bit-map of %d elements", n_extensions); + /* #18.7. Encoding the extensions presence bit-map. */ + /* TODO: act upon NOTE in #18.7 for canonical PER */ + if(SEQUENCE_handle_extensions_aper(td, sptr, po, 0) != n_extensions) + ASN__ENCODE_FAILED; + + ASN_DEBUG("Writing %d extensions", n_extensions); + /* #18.9. Encode extensions as open type fields. */ + if(SEQUENCE_handle_extensions_aper(td, sptr, 0, po) != n_extensions) + ASN__ENCODE_FAILED; + + ASN__ENCODED_OK(er); +} + #endif /* ASN_DISABLE_PER_SUPPORT */ int @@ -1548,9 +1970,13 @@ asn_TYPE_operation_t asn_OP_SEQUENCE = { #ifdef ASN_DISABLE_PER_SUPPORT 0, 0, + 0, + 0, #else SEQUENCE_decode_uper, SEQUENCE_encode_uper, + SEQUENCE_decode_aper, + SEQUENCE_encode_aper, #endif /* ASN_DISABLE_PER_SUPPORT */ SEQUENCE_random_fill, 0 /* Use generic outmost tag fetcher */ diff --git a/skeletons/constr_SEQUENCE.h b/skeletons/constr_SEQUENCE.h index f9dd4e5ef..a22ed3a27 100644 --- a/skeletons/constr_SEQUENCE.h +++ b/skeletons/constr_SEQUENCE.h @@ -56,6 +56,8 @@ oer_type_decoder_f SEQUENCE_decode_oer; oer_type_encoder_f SEQUENCE_encode_oer; per_type_decoder_f SEQUENCE_decode_uper; per_type_encoder_f SEQUENCE_encode_uper; +per_type_decoder_f SEQUENCE_decode_aper; +per_type_encoder_f SEQUENCE_encode_aper; asn_random_fill_f SEQUENCE_random_fill; extern asn_TYPE_operation_t asn_OP_SEQUENCE; diff --git a/skeletons/constr_SEQUENCE_OF.c b/skeletons/constr_SEQUENCE_OF.c index f3091659c..2fe42375a 100644 --- a/skeletons/constr_SEQUENCE_OF.c +++ b/skeletons/constr_SEQUENCE_OF.c @@ -209,6 +209,76 @@ SEQUENCE_OF_encode_uper(const asn_TYPE_descriptor_t *td, ASN__ENCODED_OK(er); } +asn_enc_rval_t +SEQUENCE_OF_encode_aper(const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, + const void *sptr, asn_per_outp_t *po) { + const asn_anonymous_sequence_ *list; + const asn_per_constraint_t *ct; + asn_enc_rval_t er; + asn_TYPE_member_t *elm = td->elements; + int seq; + + if(!sptr) ASN__ENCODE_FAILED; + list = _A_CSEQUENCE_FROM_VOID(sptr); + + er.encoded = 0; + + ASN_DEBUG("Encoding %s as SEQUENCE OF size (%d) using ALIGNED PER", td->name, list->count); + + if(constraints) ct = &constraints->size; + else if(td->encoding_constraints.per_constraints) + ct = &td->encoding_constraints.per_constraints->size; + else ct = 0; + + /* If extensible constraint, check if size is in root */ + if(ct) { + int not_in_root = (list->count < ct->lower_bound + || list->count > ct->upper_bound); + ASN_DEBUG("lb %ld ub %ld %s", + ct->lower_bound, ct->upper_bound, + ct->flags & APC_EXTENSIBLE ? "ext" : "fix"); + if(ct->flags & APC_EXTENSIBLE) { + /* Declare whether size is in extension root */ + if(per_put_few_bits(po, not_in_root, 1)) + ASN__ENCODE_FAILED; + if(not_in_root) ct = 0; + } else if(not_in_root && ct->effective_bits >= 0) + ASN__ENCODE_FAILED; + } + + if(ct && ct->effective_bits >= 0) { + /* X.691, #19.5: No length determinant */ +/* if(per_put_few_bits(po, list->count - ct->lower_bound, + ct->effective_bits)) + ASN__ENCODE_FAILED; +*/ + if (aper_put_length(po, ct->upper_bound - ct->lower_bound + 1, list->count - ct->lower_bound) < 0) + ASN__ENCODE_FAILED; + } + + for(seq = -1; seq < list->count;) { + ssize_t mayEncode; + if(seq < 0) seq = 0; + if(ct && ct->effective_bits >= 0) { + mayEncode = list->count; + } else { + mayEncode = aper_put_length(po, -1, list->count - seq); + if(mayEncode < 0) ASN__ENCODE_FAILED; + } + + while(mayEncode--) { + void *memb_ptr = list->array[seq++]; + if(!memb_ptr) ASN__ENCODE_FAILED; + er = elm->type->op->aper_encoder(elm->type, + elm->encoding_constraints.per_constraints, memb_ptr, po); + if(er.encoded == -1) + ASN__ENCODE_FAILED; + } + } + + ASN__ENCODED_OK(er); +} #endif /* ASN_DISABLE_PER_SUPPORT */ asn_TYPE_operation_t asn_OP_SEQUENCE_OF = { @@ -229,9 +299,13 @@ asn_TYPE_operation_t asn_OP_SEQUENCE_OF = { #ifdef ASN_DISABLE_PER_SUPPORT 0, 0, + 0, + 0, #else SEQUENCE_OF_decode_uper, /* Same as SET OF decoder */ SEQUENCE_OF_encode_uper, + SEQUENCE_OF_decode_aper, + SEQUENCE_OF_encode_aper, #endif /* ASN_DISABLE_PER_SUPPORT */ SEQUENCE_OF_random_fill, 0 /* Use generic outmost tag fetcher */ diff --git a/skeletons/constr_SEQUENCE_OF.h b/skeletons/constr_SEQUENCE_OF.h index 45204f32b..211d6771a 100644 --- a/skeletons/constr_SEQUENCE_OF.h +++ b/skeletons/constr_SEQUENCE_OF.h @@ -22,13 +22,15 @@ extern "C" { #define SEQUENCE_OF_constraint SET_OF_constraint #define SEQUENCE_OF_decode_ber SET_OF_decode_ber #define SEQUENCE_OF_decode_xer SET_OF_decode_xer -#define SEQUENCE_OF_decode_uper SET_OF_decode_uper #define SEQUENCE_OF_decode_oer SET_OF_decode_oer #define SEQUENCE_OF_encode_oer SET_OF_encode_oer +#define SEQUENCE_OF_decode_uper SET_OF_decode_uper +#define SEQUENCE_OF_decode_aper SET_OF_decode_aper #define SEQUENCE_OF_random_fill SET_OF_random_fill der_type_encoder_f SEQUENCE_OF_encode_der; xer_type_encoder_f SEQUENCE_OF_encode_xer; per_type_encoder_f SEQUENCE_OF_encode_uper; +per_type_encoder_f SEQUENCE_OF_encode_aper; extern asn_TYPE_operation_t asn_OP_SEQUENCE_OF; #ifdef __cplusplus diff --git a/skeletons/constr_SET.c b/skeletons/constr_SET.c index 79b3fa768..554a7ddaa 100644 --- a/skeletons/constr_SET.c +++ b/skeletons/constr_SET.c @@ -1073,6 +1073,8 @@ asn_TYPE_operation_t asn_OP_SET = { 0, /* SET_encode_oer */ 0, /* SET_decode_uper */ 0, /* SET_encode_uper */ + 0, /* SET_decode_aper */ + 0, /* SET_encode_aper */ SET_random_fill, 0 /* Use generic outmost tag fetcher */ }; diff --git a/skeletons/constr_SET_OF.c b/skeletons/constr_SET_OF.c index ea0b63b32..df3c4af60 100644 --- a/skeletons/constr_SET_OF.c +++ b/skeletons/constr_SET_OF.c @@ -973,6 +973,96 @@ SET_OF_decode_uper(const asn_codec_ctx_t *opt_codec_ctx, return rv; } +asn_dec_rval_t +SET_OF_decode_aper(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { + asn_dec_rval_t rv; + const asn_SET_OF_specifics_t *specs = (const asn_SET_OF_specifics_t *)td->specifics; + const asn_TYPE_member_t *elm = td->elements; /* Single one */ + void *st = *sptr; + asn_anonymous_set_ *list; + const asn_per_constraint_t *ct; + int repeat = 0; + ssize_t nelems; + + if(ASN__STACK_OVERFLOW_CHECK(opt_codec_ctx)) + ASN__DECODE_FAILED; + + /* + * Create the target structure if it is not present already. + */ + if(!st) { + st = *sptr = CALLOC(1, specs->struct_size); + if(!st) ASN__DECODE_FAILED; + } + list = _A_SET_FROM_VOID(st); + + /* Figure out which constraints to use */ + if(constraints) ct = &constraints->size; + else if(td->encoding_constraints.per_constraints) + ct = &td->encoding_constraints.per_constraints->size; + else ct = 0; + + if(ct && ct->flags & APC_EXTENSIBLE) { + int value = per_get_few_bits(pd, 1); + if(value < 0) ASN__DECODE_STARVED; + if(value) ct = 0; /* Not restricted! */ + } + + if(ct && ct->effective_bits >= 0) { + /* X.691, #19.5: No length determinant */ + nelems = aper_get_nsnnwn(pd, ct->upper_bound - ct->lower_bound); + ASN_DEBUG("Preparing to fetch %ld+%ld elements from %s", + (long)nelems, ct->lower_bound, td->name); + if(nelems < 0) ASN__DECODE_STARVED; + nelems += ct->lower_bound; + } else { + nelems = -1; + } + + do { + int i; + if(nelems < 0) { + nelems = aper_get_length(pd, ct ? ct->upper_bound - ct->lower_bound + 1 : -1, + ct ? ct->effective_bits : -1, &repeat); + ASN_DEBUG("Got to decode %d elements (eff %d)", + (int)nelems, (int)(ct ? ct->effective_bits : -1)); + if(nelems < 0) ASN__DECODE_STARVED; + } + + for(i = 0; i < nelems; i++) { + void *ptr = 0; + ASN_DEBUG("SET OF %s decoding", elm->type->name); + rv = elm->type->op->aper_decoder(opt_codec_ctx, elm->type, + elm->encoding_constraints.per_constraints, &ptr, pd); + ASN_DEBUG("%s SET OF %s decoded %d, %p", + td->name, elm->type->name, rv.code, ptr); + if(rv.code == RC_OK) { + if(ASN_SET_ADD(list, ptr) == 0) + continue; + ASN_DEBUG("Failed to add element into %s", + td->name); + /* Fall through */ + rv.code = RC_FAIL; + } else { + ASN_DEBUG("Failed decoding %s of %s (SET OF)", + elm->type->name, td->name); + } + if(ptr) ASN_STRUCT_FREE(*elm->type, ptr); + return rv; + } + + nelems = -1; /* Allow uper_get_length() */ + } while(repeat); + + ASN_DEBUG("Decoded %s as SET OF", td->name); + + rv.code = RC_OK; + rv.consumed = 0; + return rv; +} + int SET_OF_compare(const asn_TYPE_descriptor_t *td, const void *aptr, const void *bptr) { @@ -1002,9 +1092,13 @@ asn_TYPE_operation_t asn_OP_SET_OF = { #ifdef ASN_DISABLE_PER_SUPPORT 0, 0, + 0, + 0, #else SET_OF_decode_uper, 0, /* SET_OF_encode_uper */ + SET_OF_decode_aper, + 0, /* SET_OF_encode_aper */ #endif /* ASN_DISABLE_PER_SUPPORT */ SET_OF_random_fill, 0 /* Use generic outmost tag fetcher */ diff --git a/skeletons/constr_SET_OF.h b/skeletons/constr_SET_OF.h index f32e607ba..768106271 100644 --- a/skeletons/constr_SET_OF.h +++ b/skeletons/constr_SET_OF.h @@ -37,6 +37,8 @@ oer_type_decoder_f SET_OF_decode_oer; oer_type_encoder_f SET_OF_encode_oer; per_type_decoder_f SET_OF_decode_uper; per_type_encoder_f SET_OF_encode_uper; +per_type_decoder_f SET_OF_decode_aper; +per_type_encoder_f SET_OF_encode_aper; asn_random_fill_f SET_OF_random_fill; extern asn_TYPE_operation_t asn_OP_SET_OF; diff --git a/skeletons/constr_TYPE.h b/skeletons/constr_TYPE.h index d9d55c206..98a0e0e39 100644 --- a/skeletons/constr_TYPE.h +++ b/skeletons/constr_TYPE.h @@ -153,6 +153,8 @@ typedef struct asn_TYPE_operation_s { oer_type_encoder_f *oer_encoder; /* Canonical OER encoder */ per_type_decoder_f *uper_decoder; /* Unaligned PER decoder */ per_type_encoder_f *uper_encoder; /* Unaligned PER encoder */ + per_type_decoder_f *aper_decoder; /* Aligned PER decoder */ + per_type_encoder_f *aper_encoder; /* Aligned PER encoder */ asn_random_fill_f *random_fill; /* Initialize with a random value */ asn_outmost_tag_f *outmost_tag; /* */ } asn_TYPE_operation_t; diff --git a/skeletons/converter-example.c b/skeletons/converter-example.c index 98b54cc8e..e9934ab3c 100644 --- a/skeletons/converter-example.c +++ b/skeletons/converter-example.c @@ -142,8 +142,10 @@ static syntax_selector input_encodings[] = { "Input is in BER (Basic Encoding Rules) or DER"}, {"oer", ATS_BASIC_OER, CODEC_OFFSET(oer_decoder), "Input is in OER (Octet Encoding Rules)"}, - {"per", ATS_UNALIGNED_BASIC_PER, CODEC_OFFSET(uper_decoder), + {"uper", ATS_UNALIGNED_BASIC_PER, CODEC_OFFSET(uper_decoder), "Input is in Unaligned PER (Packed Encoding Rules)"}, + {"aper", ATS_ALIGNED_BASIC_PER, CODEC_OFFSET(aper_decoder), + "Input is in Aligned PER (Packed Encoding Rules)"}, {"xer", ATS_BASIC_XER, CODEC_OFFSET(xer_decoder), "Input is in XER (XML Encoding Rules)"}, {0, ATS_INVALID, 0, 0}}; @@ -153,8 +155,10 @@ static syntax_selector output_encodings[] = { "Output as DER (Distinguished Encoding Rules)"}, {"oer", ATS_CANONICAL_OER, CODEC_OFFSET(oer_encoder), "Output as Canonical OER (Octet Encoding Rules)"}, - {"per", ATS_UNALIGNED_CANONICAL_PER, CODEC_OFFSET(uper_encoder), + {"uper", ATS_UNALIGNED_CANONICAL_PER, CODEC_OFFSET(uper_encoder), "Output as Unaligned PER (Packed Encoding Rules)"}, + {"aper", ATS_ALIGNED_CANONICAL_PER, CODEC_OFFSET(aper_encoder), + "Output as Aligned PER (Packed Encoding Rules)"}, {"xer", ATS_BASIC_XER, CODEC_OFFSET(xer_encoder), "Output as XER (XML Encoding Rules)"}, {"text", ATS_NONSTANDARD_PLAINTEXT, CODEC_OFFSET(print_struct), @@ -724,8 +728,10 @@ static void add_bytes_to_buffer(const void *data2add, size_t bytes) { static int is_syntax_PER(enum asn_transfer_syntax syntax) { - return (syntax != ATS_UNALIGNED_BASIC_PER - && syntax != ATS_UNALIGNED_CANONICAL_PER); + return (syntax == ATS_UNALIGNED_BASIC_PER + || syntax == ATS_UNALIGNED_CANONICAL_PER + || syntax == ATS_ALIGNED_BASIC_PER + || syntax == ATS_ALIGNED_CANONICAL_PER); } static int @@ -817,8 +823,12 @@ data_decode_from_file(enum asn_transfer_syntax isyntax, asn_TYPE_descriptor_t *p rval.code = RC_FAIL; rval.consumed = 0; #else - rval = uper_decode(opt_codec_ctx, pduType, (void **)&structure, - i_bptr, i_size, 0, DynamicBuffer.unbits); + if(isyntax == ATS_UNALIGNED_BASIC_PER) + rval = uper_decode(opt_codec_ctx, pduType, (void **)&structure, + i_bptr, i_size, 0, DynamicBuffer.unbits); + else + rval = aper_decode(opt_codec_ctx, pduType, (void **)&structure, + i_bptr, i_size, 0, DynamicBuffer.unbits); /* uper_decode() returns bits! */ ecbits = rval.consumed % 8; /* Bits consumed from the last byte */ rval.consumed >>= 3; /* Convert bits into bytes. */ diff --git a/skeletons/per_decoder.c b/skeletons/per_decoder.c index a9051fb79..63781b254 100644 --- a/skeletons/per_decoder.c +++ b/skeletons/per_decoder.c @@ -95,3 +95,87 @@ uper_decode(const asn_codec_ctx_t *opt_codec_ctx, return rval; } +asn_dec_rval_t +aper_decode_complete(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **sptr, const void *buffer, size_t size) { + asn_dec_rval_t rval; + + rval = aper_decode(opt_codec_ctx, td, sptr, buffer, size, 0, 0); + if(rval.consumed) { + /* + * We've always given 8-aligned data, + * so convert bits to integral bytes. + */ + rval.consumed += 7; + rval.consumed >>= 3; + } else if(rval.code == RC_OK) { + if(size) { + if(((const uint8_t *)buffer)[0] == 0) { + rval.consumed = 1; /* 1 byte */ + } else { + ASN_DEBUG("Expecting single zeroed byte"); + rval.code = RC_FAIL; + } + } else { + /* Must contain at least 8 bits. */ + rval.code = RC_WMORE; + } + } + + return rval; +} + +asn_dec_rval_t +aper_decode(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **sptr, const void *buffer, size_t size, int skip_bits, int unused_bits) { + asn_codec_ctx_t s_codec_ctx; + asn_dec_rval_t rval; + asn_per_data_t pd; + + if(skip_bits < 0 || skip_bits > 7 + || unused_bits < 0 || unused_bits > 7 + || (unused_bits > 0 && !size)) + ASN__DECODE_FAILED; + + /* + * Stack checker requires that the codec context + * must be allocated on the stack. + */ + if(opt_codec_ctx) { + if(opt_codec_ctx->max_stack_size) { + s_codec_ctx = *opt_codec_ctx; + opt_codec_ctx = &s_codec_ctx; + } + } else { + /* If context is not given, be security-conscious anyway */ + memset(&s_codec_ctx, 0, sizeof(s_codec_ctx)); + s_codec_ctx.max_stack_size = ASN__DEFAULT_STACK_MAX; + opt_codec_ctx = &s_codec_ctx; + } + + /* Fill in the position indicator */ + memset(&pd, 0, sizeof(pd)); + pd.buffer = (const uint8_t *)buffer; + pd.nboff = skip_bits; + pd.nbits = 8 * size - unused_bits; /* 8 is CHAR_BIT from */ + if(pd.nboff > pd.nbits) + ASN__DECODE_FAILED; + + /* + * Invoke type-specific decoder. + */ + if(!td->op->aper_decoder) + ASN__DECODE_FAILED; /* PER is not compiled in */ + rval = td->op->aper_decoder(opt_codec_ctx, td, 0, sptr, &pd); + if(rval.code == RC_OK) { + /* Return the number of consumed bits */ + rval.consumed = ((pd.buffer - (const uint8_t *)buffer) << 3) + + pd.nboff - skip_bits; + ASN_DEBUG("PER decoding consumed %zu, counted %zu", + rval.consumed, pd.moved); + assert(rval.consumed == pd.moved); + } else { + /* PER codec is not a restartable */ + rval.consumed = 0; + } + return rval; +} + diff --git a/skeletons/per_decoder.h b/skeletons/per_decoder.h index 24dfe9366..c28e1e2f4 100644 --- a/skeletons/per_decoder.h +++ b/skeletons/per_decoder.h @@ -40,6 +40,29 @@ asn_dec_rval_t uper_decode( int unused_bits /* Number of unused tailing bits, 0..7 */ ); +/* + * Aligned PER decoder of a "complete encoding" as per X.691#10.1. + * On success, this call always returns (.consumed >= 1), in BITS, as per X.691#10.1.3. + */ +asn_dec_rval_t aper_decode_complete(struct asn_codec_ctx_s *opt_codec_ctx, + struct asn_TYPE_descriptor_s *type_descriptor, /* Type to decode */ + void **struct_ptr, /* Pointer to a target structure's pointer */ + const void *buffer, /* Data to be decoded */ + size_t size /* Size of data buffer */ + ); + +/* + * Aligned PER decoder of any ASN.1 type. May be invoked by the application. + * WARNING: This call returns the number of BITS read from the stream. Beware. + */ +asn_dec_rval_t aper_decode(struct asn_codec_ctx_s *opt_codec_ctx, + struct asn_TYPE_descriptor_s *type_descriptor, /* Type to decode */ + void **struct_ptr, /* Pointer to a target structure's pointer */ + const void *buffer, /* Data to be decoded */ + size_t size, /* Size of data buffer */ + int skip_bits, /* Number of unused leading bits, 0..7 */ + int unused_bits /* Number of unused tailing bits, 0..7 */ + ); /* * Type of the type-specific PER decoder function. diff --git a/skeletons/per_encoder.c b/skeletons/per_encoder.c index 317897d1c..18dcb2336 100644 --- a/skeletons/per_encoder.c +++ b/skeletons/per_encoder.c @@ -159,3 +159,113 @@ uper_encode_internal(const asn_TYPE_descriptor_t *td, return er; } +static asn_enc_rval_t aper_encode_internal(const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *, + const void *sptr, asn_app_consume_bytes_f *cb, void *app_key); + +asn_enc_rval_t +aper_encode(const asn_TYPE_descriptor_t *td, + const void *sptr, asn_app_consume_bytes_f *cb, void *app_key) { + return aper_encode_internal(td, 0, sptr, cb, app_key); +} + +asn_enc_rval_t +aper_encode_to_buffer(const asn_TYPE_descriptor_t *td, + const void *sptr, void *buffer, size_t buffer_size) { + enc_to_buf_arg key; + + key.buffer = buffer; + key.left = buffer_size; + + if(td) ASN_DEBUG("Encoding \"%s\" using ALIGNED PER", td->name); + + return aper_encode_internal(td, 0, sptr, encode_to_buffer_cb, &key); +} + +ssize_t +aper_encode_to_new_buffer(const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, + const void *sptr, void **buffer_r) { + asn_enc_rval_t er; + enc_dyn_arg key; + + memset(&key, 0, sizeof(key)); + + er = aper_encode_internal(td, constraints, sptr, encode_dyn_cb, &key); + switch(er.encoded) { + case -1: + FREEMEM(key.buffer); + return -1; + case 0: + FREEMEM(key.buffer); + key.buffer = MALLOC(1); + if(key.buffer) { + *(char *)key.buffer = '\0'; + *buffer_r = key.buffer; + return 1; + } else { + return -1; + } + default: + *buffer_r = key.buffer; + ASN_DEBUG("Complete encoded in %ld bits", er.encoded); + return ((er.encoded + 7) >> 3); + } +} + +static int +_aper_encode_flush_outp(asn_per_outp_t *po) { + uint8_t *buf; + + if(po->nboff == 0 && po->buffer == po->tmpspace) + return 0; + + buf = po->buffer + (po->nboff >> 3); + /* Make sure we account for the last, partially filled */ + if(po->nboff & 0x07) { + buf[0] &= 0xff << (8 - (po->nboff & 0x07)); + buf++; + } + + if (po->output) { + return po->output(po->tmpspace, buf - po->tmpspace, po->op_key); + } + return 0; +} + +static asn_enc_rval_t +aper_encode_internal(const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, + const void *sptr, asn_app_consume_bytes_f *cb, void *app_key) { + asn_per_outp_t po; + asn_enc_rval_t er; + + /* + * Invoke type-specific encoder. + */ + if(!td || !td->op->aper_encoder) + ASN__ENCODE_FAILED; /* PER is not compiled in */ + + po.buffer = po.tmpspace; + po.nboff = 0; + po.nbits = 8 * sizeof(po.tmpspace); + po.output = cb; + po.op_key = app_key; + po.flushed_bytes = 0; + + er = td->op->aper_encoder(td, constraints, sptr, &po); + if(er.encoded != -1) { + size_t bits_to_flush; + + bits_to_flush = ((po.buffer - po.tmpspace) << 3) + po.nboff; + + /* Set number of bits encoded to a firm value */ + er.encoded = (po.flushed_bytes << 3) + bits_to_flush; + + if(_aper_encode_flush_outp(&po)) + ASN__ENCODE_FAILED; + } + + return er; +} + diff --git a/skeletons/per_encoder.h b/skeletons/per_encoder.h index 94177cf4e..46dfbf38c 100644 --- a/skeletons/per_encoder.h +++ b/skeletons/per_encoder.h @@ -27,6 +27,13 @@ asn_enc_rval_t uper_encode( void *app_key /* Arbitrary callback argument */ ); +asn_enc_rval_t aper_encode( + const struct asn_TYPE_descriptor_s *type_descriptor, + const void *struct_ptr, /* Structure to be encoded */ + asn_app_consume_bytes_f *consume_bytes_cb, /* Data collector */ + void *app_key /* Arbitrary callback argument */ +); + /* * A variant of uper_encode() which encodes data into the existing buffer * WARNING: This function returns the number of encoded bits in the .encoded @@ -39,6 +46,12 @@ asn_enc_rval_t uper_encode_to_buffer( size_t buffer_size /* Initial buffer size (max) */ ); +asn_enc_rval_t aper_encode_to_buffer( + const struct asn_TYPE_descriptor_s *type_descriptor, + const void *struct_ptr, /* Structure to be encoded */ + void *buffer, /* Pre-allocated buffer */ + size_t buffer_size /* Initial buffer size (max) */ +); /* * A variant of uper_encode_to_buffer() which allocates buffer itself. * Returns the number of bytes in the buffer or -1 in case of failure. @@ -53,6 +66,14 @@ ssize_t uper_encode_to_new_buffer( void **buffer_r /* Buffer allocated and returned */ ); +ssize_t +aper_encode_to_new_buffer( + const struct asn_TYPE_descriptor_s *td, + const asn_per_constraints_t *constraints, + const void *sptr, + void **buffer_r +); + /* * Type of the generic PER encoder function. */ diff --git a/skeletons/per_opentype.c b/skeletons/per_opentype.c index f86dad70d..6f8afe801 100644 --- a/skeletons/per_opentype.c +++ b/skeletons/per_opentype.c @@ -394,3 +394,139 @@ per_skip_bits(asn_per_data_t *pd, int skip_nbits) { } return hasNonZeroBits; } + +static asn_dec_rval_t +aper_open_type_get_simple(const asn_codec_ctx_t *ctx, + const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { + asn_dec_rval_t rv; + ssize_t chunk_bytes; + int repeat; + uint8_t *buf = 0; + size_t bufLen = 0; + size_t bufSize = 0; + asn_per_data_t spd; + size_t padding; + + ASN__STACK_OVERFLOW_CHECK(ctx); + + ASN_DEBUG("Getting open type %s...", td->name); + + do { + chunk_bytes = aper_get_length(pd, -1, -1, &repeat); + if(chunk_bytes < 0) { + FREEMEM(buf); + ASN__DECODE_STARVED; + } + if(bufLen + chunk_bytes > bufSize) { + void *ptr; + bufSize = chunk_bytes + (bufSize << 2); + ptr = REALLOC(buf, bufSize); + if(!ptr) { + FREEMEM(buf); + ASN__DECODE_FAILED; + } + buf = ptr; + } + if(per_get_many_bits(pd, buf + bufLen, 0, chunk_bytes << 3)) { + FREEMEM(buf); + ASN__DECODE_STARVED; + } + bufLen += chunk_bytes; + } while(repeat); + + ASN_DEBUG("Getting open type %s encoded in %ld bytes", td->name, + (long)bufLen); + + memset(&spd, 0, sizeof(spd)); + spd.buffer = buf; + spd.nbits = bufLen << 3; + + ASN_DEBUG_INDENT_ADD(+4); + rv = td->op->aper_decoder(ctx, td, constraints, sptr, &spd); + ASN_DEBUG_INDENT_ADD(-4); + + if(rv.code == RC_OK) { + /* Check padding validity */ + padding = spd.nbits - spd.nboff; + if ((padding < 8 || + /* X.691#10.1.3 */ + (spd.nboff == 0 && spd.nbits == 8 && spd.buffer == buf)) && + per_get_few_bits(&spd, padding) == 0) { + /* Everything is cool */ + FREEMEM(buf); + return rv; + } + FREEMEM(buf); + if(padding >= 8) { + ASN_DEBUG("Too large padding %d in open type", (int)padding); + ASN__DECODE_FAILED; + } else { + ASN_DEBUG("Non-zero padding"); + ASN__DECODE_FAILED; + } + } else { + FREEMEM(buf); + /* rv.code could be RC_WMORE, nonsense in this context */ + rv.code = RC_FAIL; /* Noone would give us more */ + } + + return rv; +} + +int +aper_open_type_put(const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, + const void *sptr, asn_per_outp_t *po) { + void *buf; + void *bptr; + ssize_t size; + size_t toGo; + + ASN_DEBUG("Open type put %s ...", td->name); + + size = aper_encode_to_new_buffer(td, constraints, sptr, &buf); + if(size <= 0) return -1; + + for(bptr = buf, toGo = size; toGo;) { + ssize_t maySave = aper_put_length(po, -1, toGo); + if(maySave < 0) break; + if(per_put_many_bits(po, bptr, maySave * 8)) break; + bptr = (char *)bptr + maySave; + toGo -= maySave; + } + + FREEMEM(buf); + if(toGo) return -1; + + ASN_DEBUG("Open type put %s of length %ld + overhead (1byte?)", + td->name, size); + + return 0; +} + +asn_dec_rval_t +aper_open_type_get(const asn_codec_ctx_t *ctx, + const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, + void **sptr, asn_per_data_t *pd) { + + return aper_open_type_get_simple(ctx, td, constraints, sptr, pd); +} + +int +aper_open_type_skip(const asn_codec_ctx_t *ctx, asn_per_data_t *pd) { + asn_TYPE_descriptor_t s_td; + asn_dec_rval_t rv; + + s_td.name = ""; + s_td.op->aper_decoder = uper_sot_suck; + + rv = aper_open_type_get(ctx, &s_td, 0, 0, pd); + if(rv.code != RC_OK) + return -1; + else + return 0; +} + + diff --git a/skeletons/per_opentype.h b/skeletons/per_opentype.h index 7e7dc6109..1493b2d8e 100644 --- a/skeletons/per_opentype.h +++ b/skeletons/per_opentype.h @@ -25,6 +25,18 @@ int uper_open_type_put(const asn_TYPE_descriptor_t *td, const asn_per_constraints_t *constraints, const void *sptr, asn_per_outp_t *po); +asn_dec_rval_t aper_open_type_get(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, + void **sptr, asn_per_data_t *pd); + + +int aper_open_type_skip(const asn_codec_ctx_t *opt_codec_ctx, asn_per_data_t *pd); + +int aper_open_type_put(const asn_TYPE_descriptor_t *td, + const asn_per_constraints_t *constraints, + const void *sptr, asn_per_outp_t *po); + #ifdef __cplusplus } #endif diff --git a/skeletons/per_support.c b/skeletons/per_support.c index a1c77023e..9c7ff2700 100644 --- a/skeletons/per_support.c +++ b/skeletons/per_support.c @@ -292,3 +292,197 @@ per_long_range_unrebase(unsigned long inp, long lb, long ub, long *outp) { return 0; } + +int32_t +aper_get_align(asn_per_data_t *pd) { + + if(pd->nboff & 0x7) { + ASN_DEBUG("Aligning %ld bits", 8 - ((unsigned long)pd->nboff & 0x7)); + return per_get_few_bits(pd, 8 - (pd->nboff & 0x7)); + } + return 0; +} + +ssize_t +aper_get_length(asn_per_data_t *pd, int range, int ebits, int *repeat) { + ssize_t value; + + *repeat = 0; + + if (range <= 65536 && range >= 0) + return aper_get_nsnnwn(pd, range); + + if (aper_get_align(pd) < 0) + return -1; + + if(ebits >= 0) return per_get_few_bits(pd, ebits); + + value = per_get_few_bits(pd, 8); + if(value < 0) return -1; + if((value & 128) == 0) /* #10.9.3.6 */ + return (value & 0x7F); + if((value & 64) == 0) { /* #10.9.3.7 */ + value = ((value & 63) << 8) | per_get_few_bits(pd, 8); + if(value < 0) return -1; + return value; + } + value &= 63; /* this is "m" from X.691, #10.9.3.8 */ + if(value < 1 || value > 4) + return -1; + *repeat = 1; + return (16384 * value); +} + +ssize_t +aper_get_nslength(asn_per_data_t *pd) { + ssize_t length; + + ASN_DEBUG("Getting normally small length"); + + if(per_get_few_bits(pd, 1) == 0) { + length = per_get_few_bits(pd, 6) + 1; + if(length <= 0) return -1; + ASN_DEBUG("l=%ld", length); + return length; + } else { + int repeat; + length = aper_get_length(pd, -1, -1, &repeat); + if(length >= 0 && !repeat) return length; + return -1; /* Error, or do not support >16K extensions */ + } +} + +ssize_t +aper_get_nsnnwn(asn_per_data_t *pd, int range) { + ssize_t value; + int bytes = 0; + + ASN_DEBUG("getting nsnnwn with range %d", range); + + if(range <= 255) { + int i; + + if (range < 0) return -1; + /* 1 -> 8 bits */ + for (i = 1; i <= 8; i++) { + int upper = 1 << i; + if (upper >= range) + break; + } + value = per_get_few_bits(pd, i); + return value; + } else if (range == 256){ + /* 1 byte */ + bytes = 1; + } else if (range <= 65536) { + /* 2 bytes */ + bytes = 2; + } else { + return -1; + } + if (aper_get_align(pd) < 0) + return -1; + value = per_get_few_bits(pd, 8 * bytes); + return value; +} + +int aper_put_align(asn_per_outp_t *po) { + + if(po->nboff & 0x7) { + ASN_DEBUG("Aligning %ld bits", 8 - ((unsigned long)po->nboff & 0x7)); + if(per_put_few_bits(po, 0x00, (8 - (po->nboff & 0x7)))) + return -1; + } + return 0; +} + +ssize_t +aper_put_length(asn_per_outp_t *po, int range, size_t length) { + + ASN_DEBUG("APER put length %zu with range %d", length, range); + + /* 10.9 X.691 Note 2 */ + if (range <= 65536 && range >= 0) + return aper_put_nsnnwn(po, range, length); + + if (aper_put_align(po) < 0) + return -1; + + if(length <= 127) /* #10.9.3.6 */{ + return per_put_few_bits(po, length, 8) + ? -1 : (ssize_t)length; + } + else if(length < 16384) /* #10.9.3.7 */ + return per_put_few_bits(po, length|0x8000, 16) + ? -1 : (ssize_t)length; + + length >>= 14; + if(length > 4) length = 4; + + return per_put_few_bits(po, 0xC0 | length, 8) + ? -1 : (ssize_t)(length << 14); +} + + +int +aper_put_nslength(asn_per_outp_t *po, size_t length) { + + if(length <= 64) { + /* #10.9.3.4 */ + if(length == 0) return -1; + return per_put_few_bits(po, length-1, 7) ? -1 : 0; + } else { + if(aper_put_length(po, -1, length) != (ssize_t)length) { + /* This might happen in case of >16K extensions */ + return -1; + } + } + + return 0; +} + +int +aper_put_nsnnwn(asn_per_outp_t *po, int range, int number) { + int bytes; + + ASN_DEBUG("aper put nsnnwn %d with range %d", number, range); + /* 10.5.7.1 X.691 */ + if(range < 0) { + int i; + for (i = 1; ; i++) { + int bits = 1 << (8 * i); + if (number <= bits) + break; + } + bytes = i; + assert(i <= 4); + } + if(range <= 255) { + int i; + for (i = 1; i <= 8; i++) { + int bits = 1 << i; + if (range <= bits) + break; + } + return per_put_few_bits(po, number, i); + } else if(range == 256) { + bytes = 1; + } else if(range <= 65536) { + bytes = 2; + } else { /* Ranges > 64K */ + int i; + for (i = 1; ; i++) { + int bits = 1 << (8 * i); + if (range <= bits) + break; + } + assert(i <= 4); + bytes = i; + } + if(aper_put_align(po) < 0) /* Aligning on octet */ + return -1; +/* if(per_put_few_bits(po, bytes, 8)) + return -1; +*/ + return per_put_few_bits(po, number, 8 * bytes); +} diff --git a/skeletons/per_support.h b/skeletons/per_support.h index 3e905a8b9..23079c94f 100644 --- a/skeletons/per_support.h +++ b/skeletons/per_support.h @@ -48,15 +48,20 @@ typedef struct asn_bit_data_s asn_per_data_t; ssize_t uper_get_length(asn_per_data_t *pd, int effective_bound_bits, size_t lower_bound, int *repeat); +ssize_t aper_get_length(asn_per_data_t *pd, int range, + int effective_bound_bits, int *repeat); + /* * Get the normally small length "n". */ ssize_t uper_get_nslength(asn_per_data_t *pd); +ssize_t aper_get_nslength(asn_per_data_t *pd); /* * Get the normally small non-negative whole number. */ ssize_t uper_get_nsnnwn(asn_per_data_t *pd); +ssize_t aper_get_nsnnwn(asn_per_data_t *pd, int range); /* X.691-2008/11, #11.5.6 */ int uper_get_constrained_whole_number(asn_per_data_t *pd, unsigned long *v, int nbits); @@ -94,17 +99,27 @@ int uper_put_constrained_whole_number_u(asn_per_outp_t *po, unsigned long v, int ssize_t uper_put_length(asn_per_outp_t *po, size_t whole_length, int *opt_need_eom); +ssize_t aper_put_length(asn_per_outp_t *po, int range, size_t length); + +/* Align the current bit position to octet bundary */ +int aper_put_align(asn_per_outp_t *po); +int32_t aper_get_align(asn_per_data_t *pd); + /* * Put the normally small length "n" to the Unaligned PER stream. * Returns 0 or -1. */ int uper_put_nslength(asn_per_outp_t *po, size_t length); +int aper_put_nslength(asn_per_outp_t *po, size_t length); + /* * Put the normally small non-negative whole number. */ int uper_put_nsnnwn(asn_per_outp_t *po, int n); +int aper_put_nsnnwn(asn_per_outp_t *po, int range, int number); + #ifdef __cplusplus } #endif diff --git a/tests/tests-asn1c-compiler/147-inherit-per-constraints-OK.asn1.-Pgen-PER b/tests/tests-asn1c-compiler/147-inherit-per-constraints-OK.asn1.-Pgen-PER index fd7c39e98..fdd07676a 100644 --- a/tests/tests-asn1c-compiler/147-inherit-per-constraints-OK.asn1.-Pgen-PER +++ b/tests/tests-asn1c-compiler/147-inherit-per-constraints-OK.asn1.-Pgen-PER @@ -20,6 +20,8 @@ xer_type_decoder_f Short_decode_xer; xer_type_encoder_f Short_encode_xer; per_type_decoder_f Short_decode_uper; per_type_encoder_f Short_encode_uper; +per_type_decoder_f Short_decode_aper; +per_type_encoder_f Short_encode_aper; /*** <<< CODE [Short] >>> ***/ @@ -103,6 +105,8 @@ xer_type_decoder_f Alias_decode_xer; xer_type_encoder_f Alias_encode_xer; per_type_decoder_f Alias_decode_uper; per_type_encoder_f Alias_encode_uper; +per_type_decoder_f Alias_decode_aper; +per_type_encoder_f Alias_encode_aper; /*** <<< CODE [Alias] >>> ***/ diff --git a/tests/tests-asn1c-compiler/154-with-REAL-components-OK.asn1.-Pgen-PER b/tests/tests-asn1c-compiler/154-with-REAL-components-OK.asn1.-Pgen-PER index 2858cc37d..082656524 100644 --- a/tests/tests-asn1c-compiler/154-with-REAL-components-OK.asn1.-Pgen-PER +++ b/tests/tests-asn1c-compiler/154-with-REAL-components-OK.asn1.-Pgen-PER @@ -19,6 +19,8 @@ xer_type_decoder_f UnconstrainedREAL_decode_xer; xer_type_encoder_f UnconstrainedREAL_encode_xer; per_type_decoder_f UnconstrainedREAL_decode_uper; per_type_encoder_f UnconstrainedREAL_encode_uper; +per_type_decoder_f UnconstrainedREAL_decode_aper; +per_type_encoder_f UnconstrainedREAL_encode_aper; /*** <<< CODE [UnconstrainedREAL] >>> ***/ @@ -68,6 +70,8 @@ xer_type_decoder_f WeirdlyConstrainedREAL_decode_xer; xer_type_encoder_f WeirdlyConstrainedREAL_encode_xer; per_type_decoder_f WeirdlyConstrainedREAL_decode_uper; per_type_encoder_f WeirdlyConstrainedREAL_encode_uper; +per_type_decoder_f WeirdlyConstrainedREAL_decode_aper; +per_type_encoder_f WeirdlyConstrainedREAL_encode_aper; /*** <<< CODE [WeirdlyConstrainedREAL] >>> ***/ @@ -152,6 +156,8 @@ xer_type_decoder_f Indirect_IEEE_binary32_decode_xer; xer_type_encoder_f Indirect_IEEE_binary32_encode_xer; per_type_decoder_f Indirect_IEEE_binary32_decode_uper; per_type_encoder_f Indirect_IEEE_binary32_encode_uper; +per_type_decoder_f Indirect_IEEE_binary32_decode_aper; +per_type_encoder_f Indirect_IEEE_binary32_encode_aper; /*** <<< CODE [Indirect-IEEE-binary32] >>> ***/ @@ -233,6 +239,8 @@ xer_type_decoder_f IEEE_binary32_w_decode_xer; xer_type_encoder_f IEEE_binary32_w_encode_xer; per_type_decoder_f IEEE_binary32_w_decode_uper; per_type_encoder_f IEEE_binary32_w_encode_uper; +per_type_decoder_f IEEE_binary32_w_decode_aper; +per_type_encoder_f IEEE_binary32_w_encode_aper; /*** <<< CODE [IEEE-binary32-w] >>> ***/ @@ -314,6 +322,8 @@ xer_type_decoder_f IEEE_binary32_0w_decode_xer; xer_type_encoder_f IEEE_binary32_0w_encode_xer; per_type_decoder_f IEEE_binary32_0w_decode_uper; per_type_encoder_f IEEE_binary32_0w_encode_uper; +per_type_decoder_f IEEE_binary32_0w_decode_aper; +per_type_encoder_f IEEE_binary32_0w_encode_aper; /*** <<< CODE [IEEE-binary32-0w] >>> ***/ @@ -395,6 +405,8 @@ xer_type_decoder_f IEEE_binary32_w0_decode_xer; xer_type_encoder_f IEEE_binary32_w0_encode_xer; per_type_decoder_f IEEE_binary32_w0_decode_uper; per_type_encoder_f IEEE_binary32_w0_encode_uper; +per_type_decoder_f IEEE_binary32_w0_decode_aper; +per_type_encoder_f IEEE_binary32_w0_encode_aper; /*** <<< CODE [IEEE-binary32-w0] >>> ***/ @@ -475,6 +487,8 @@ xer_type_decoder_f IEEE_binary64_w_decode_xer; xer_type_encoder_f IEEE_binary64_w_encode_xer; per_type_decoder_f IEEE_binary64_w_decode_uper; per_type_encoder_f IEEE_binary64_w_encode_uper; +per_type_decoder_f IEEE_binary64_w_decode_aper; +per_type_encoder_f IEEE_binary64_w_encode_aper; /*** <<< CODE [IEEE-binary64-w] >>> ***/ @@ -552,6 +566,8 @@ xer_type_decoder_f IEEE_binary64_0w_decode_xer; xer_type_encoder_f IEEE_binary64_0w_encode_xer; per_type_decoder_f IEEE_binary64_0w_decode_uper; per_type_encoder_f IEEE_binary64_0w_encode_uper; +per_type_decoder_f IEEE_binary64_0w_decode_aper; +per_type_encoder_f IEEE_binary64_0w_encode_aper; /*** <<< CODE [IEEE-binary64-0w] >>> ***/ @@ -629,6 +645,8 @@ xer_type_decoder_f IEEE_binary64_w0_decode_xer; xer_type_encoder_f IEEE_binary64_w0_encode_xer; per_type_decoder_f IEEE_binary64_w0_decode_uper; per_type_encoder_f IEEE_binary64_w0_encode_uper; +per_type_decoder_f IEEE_binary64_w0_decode_aper; +per_type_encoder_f IEEE_binary64_w0_encode_aper; /*** <<< CODE [IEEE-binary64-w0] >>> ***/ diff --git a/tests/tests-asn1c-compiler/155-parameterization-more-than-two-level-OK.asn1.-Pgen-PER b/tests/tests-asn1c-compiler/155-parameterization-more-than-two-level-OK.asn1.-Pgen-PER index 1a5121f63..6bc392cd3 100644 --- a/tests/tests-asn1c-compiler/155-parameterization-more-than-two-level-OK.asn1.-Pgen-PER +++ b/tests/tests-asn1c-compiler/155-parameterization-more-than-two-level-OK.asn1.-Pgen-PER @@ -20,6 +20,8 @@ xer_type_decoder_f PacketId_decode_xer; xer_type_encoder_f PacketId_encode_xer; per_type_decoder_f PacketId_decode_uper; per_type_encoder_f PacketId_encode_uper; +per_type_decoder_f PacketId_decode_aper; +per_type_encoder_f PacketId_encode_aper; /*** <<< CODE [PacketId] >>> ***/ @@ -112,6 +114,8 @@ xer_type_decoder_f Color_decode_xer; xer_type_encoder_f Color_encode_xer; per_type_decoder_f Color_decode_uper; per_type_encoder_f Color_encode_uper; +per_type_decoder_f Color_decode_aper; +per_type_encoder_f Color_encode_aper; /*** <<< CODE [Color] >>> ***/ @@ -197,6 +201,8 @@ xer_type_decoder_f Valid_decode_xer; xer_type_encoder_f Valid_encode_xer; per_type_decoder_f Valid_decode_uper; per_type_encoder_f Valid_encode_uper; +per_type_decoder_f Valid_decode_aper; +per_type_encoder_f Valid_encode_aper; /*** <<< CODE [Valid] >>> ***/ @@ -271,6 +277,8 @@ xer_type_decoder_f Packet_List_decode_xer; xer_type_encoder_f Packet_List_encode_xer; per_type_decoder_f Packet_List_decode_uper; per_type_encoder_f Packet_List_encode_uper; +per_type_decoder_f Packet_List_decode_aper; +per_type_encoder_f Packet_List_encode_aper; /*** <<< CODE [Packet-List] >>> ***/ @@ -356,6 +364,8 @@ xer_type_decoder_f UpperLayer_List_41P0_decode_xer; xer_type_encoder_f UpperLayer_List_41P0_encode_xer; per_type_decoder_f UpperLayer_List_41P0_decode_uper; per_type_encoder_f UpperLayer_List_41P0_encode_uper; +per_type_decoder_f UpperLayer_List_41P0_decode_aper; +per_type_encoder_f UpperLayer_List_41P0_encode_aper; /*** <<< CODE [UpperLayer-List] >>> ***/ @@ -515,6 +525,8 @@ xer_type_decoder_f SinglePacket_48P0_decode_xer; xer_type_encoder_f SinglePacket_48P0_encode_xer; per_type_decoder_f SinglePacket_48P0_decode_uper; per_type_encoder_f SinglePacket_48P0_encode_uper; +per_type_decoder_f SinglePacket_48P0_decode_aper; +per_type_encoder_f SinglePacket_48P0_encode_aper; /*** <<< CODE [SinglePacket] >>> ***/ diff --git a/tests/tests-asn1c-compiler/50-constraint-OK.asn1.-Pgen-PER b/tests/tests-asn1c-compiler/50-constraint-OK.asn1.-Pgen-PER index 50a674ee9..88ba6ca7e 100644 --- a/tests/tests-asn1c-compiler/50-constraint-OK.asn1.-Pgen-PER +++ b/tests/tests-asn1c-compiler/50-constraint-OK.asn1.-Pgen-PER @@ -19,6 +19,8 @@ xer_type_decoder_f Int1_decode_xer; xer_type_encoder_f Int1_encode_xer; per_type_decoder_f Int1_decode_uper; per_type_encoder_f Int1_encode_uper; +per_type_decoder_f Int1_decode_aper; +per_type_encoder_f Int1_encode_aper; /*** <<< CODE [Int1] >>> ***/ @@ -69,6 +71,8 @@ xer_type_decoder_f Int2_decode_xer; xer_type_encoder_f Int2_encode_xer; per_type_decoder_f Int2_decode_uper; per_type_encoder_f Int2_encode_uper; +per_type_decoder_f Int2_decode_aper; +per_type_encoder_f Int2_encode_aper; /*** <<< CODE [Int2] >>> ***/ @@ -149,6 +153,8 @@ xer_type_decoder_f Int3_decode_xer; xer_type_encoder_f Int3_encode_xer; per_type_decoder_f Int3_decode_uper; per_type_encoder_f Int3_encode_uper; +per_type_decoder_f Int3_decode_aper; +per_type_encoder_f Int3_encode_aper; /*** <<< CODE [Int3] >>> ***/ @@ -232,6 +238,8 @@ xer_type_decoder_f Int4_decode_xer; xer_type_encoder_f Int4_encode_xer; per_type_decoder_f Int4_decode_uper; per_type_encoder_f Int4_encode_uper; +per_type_decoder_f Int4_decode_aper; +per_type_encoder_f Int4_encode_aper; /*** <<< CODE [Int4] >>> ***/ @@ -315,6 +323,8 @@ xer_type_decoder_f Int5_decode_xer; xer_type_encoder_f Int5_encode_xer; per_type_decoder_f Int5_decode_uper; per_type_encoder_f Int5_encode_uper; +per_type_decoder_f Int5_decode_aper; +per_type_encoder_f Int5_encode_aper; /*** <<< CODE [Int5] >>> ***/ @@ -397,6 +407,8 @@ xer_type_decoder_f ExtensibleExtensions_decode_xer; xer_type_encoder_f ExtensibleExtensions_encode_xer; per_type_decoder_f ExtensibleExtensions_decode_uper; per_type_encoder_f ExtensibleExtensions_encode_uper; +per_type_decoder_f ExtensibleExtensions_decode_aper; +per_type_encoder_f ExtensibleExtensions_encode_aper; /*** <<< CODE [ExtensibleExtensions] >>> ***/ @@ -480,6 +492,8 @@ xer_type_decoder_f Str1_decode_xer; xer_type_encoder_f Str1_encode_xer; per_type_decoder_f Str1_decode_uper; per_type_encoder_f Str1_encode_uper; +per_type_decoder_f Str1_decode_aper; +per_type_encoder_f Str1_encode_aper; /*** <<< CODE [Str1] >>> ***/ @@ -538,6 +552,8 @@ xer_type_decoder_f Str2_decode_xer; xer_type_encoder_f Str2_encode_xer; per_type_decoder_f Str2_decode_uper; per_type_encoder_f Str2_encode_uper; +per_type_decoder_f Str2_decode_aper; +per_type_encoder_f Str2_encode_aper; /*** <<< CTABLES [Str2] >>> ***/ @@ -638,6 +654,8 @@ xer_type_decoder_f Str3_decode_xer; xer_type_encoder_f Str3_encode_xer; per_type_decoder_f Str3_decode_uper; per_type_encoder_f Str3_encode_uper; +per_type_decoder_f Str3_decode_aper; +per_type_encoder_f Str3_encode_aper; /*** <<< CTABLES [Str3] >>> ***/ @@ -763,6 +781,8 @@ xer_type_decoder_f Str4_decode_xer; xer_type_encoder_f Str4_encode_xer; per_type_decoder_f Str4_decode_uper; per_type_encoder_f Str4_encode_uper; +per_type_decoder_f Str4_decode_aper; +per_type_encoder_f Str4_encode_aper; /*** <<< CTABLES [Str4] >>> ***/ @@ -861,6 +881,8 @@ xer_type_decoder_f PER_Visible_decode_xer; xer_type_encoder_f PER_Visible_encode_xer; per_type_decoder_f PER_Visible_decode_uper; per_type_encoder_f PER_Visible_encode_uper; +per_type_decoder_f PER_Visible_decode_aper; +per_type_encoder_f PER_Visible_encode_aper; /*** <<< CTABLES [PER-Visible] >>> ***/ @@ -958,6 +980,8 @@ xer_type_decoder_f PER_Visible_2_decode_xer; xer_type_encoder_f PER_Visible_2_encode_xer; per_type_decoder_f PER_Visible_2_decode_uper; per_type_encoder_f PER_Visible_2_encode_uper; +per_type_decoder_f PER_Visible_2_decode_aper; +per_type_encoder_f PER_Visible_2_encode_aper; /*** <<< CTABLES [PER-Visible-2] >>> ***/ @@ -1055,6 +1079,8 @@ xer_type_decoder_f Not_PER_Visible_1_decode_xer; xer_type_encoder_f Not_PER_Visible_1_encode_xer; per_type_decoder_f Not_PER_Visible_1_decode_uper; per_type_encoder_f Not_PER_Visible_1_encode_uper; +per_type_decoder_f Not_PER_Visible_1_decode_aper; +per_type_encoder_f Not_PER_Visible_1_encode_aper; /*** <<< CTABLES [Not-PER-Visible-1] >>> ***/ @@ -1152,6 +1178,8 @@ xer_type_decoder_f Not_PER_Visible_2_decode_xer; xer_type_encoder_f Not_PER_Visible_2_encode_xer; per_type_decoder_f Not_PER_Visible_2_decode_uper; per_type_encoder_f Not_PER_Visible_2_encode_uper; +per_type_decoder_f Not_PER_Visible_2_decode_aper; +per_type_encoder_f Not_PER_Visible_2_encode_aper; /*** <<< CTABLES [Not-PER-Visible-2] >>> ***/ @@ -1249,6 +1277,8 @@ xer_type_decoder_f Not_PER_Visible_3_decode_xer; xer_type_encoder_f Not_PER_Visible_3_encode_xer; per_type_decoder_f Not_PER_Visible_3_decode_uper; per_type_encoder_f Not_PER_Visible_3_encode_uper; +per_type_decoder_f Not_PER_Visible_3_decode_aper; +per_type_encoder_f Not_PER_Visible_3_encode_aper; /*** <<< CTABLES [Not-PER-Visible-3] >>> ***/ @@ -1346,6 +1376,8 @@ xer_type_decoder_f SIZE_but_not_FROM_decode_xer; xer_type_encoder_f SIZE_but_not_FROM_encode_xer; per_type_decoder_f SIZE_but_not_FROM_decode_uper; per_type_encoder_f SIZE_but_not_FROM_encode_uper; +per_type_decoder_f SIZE_but_not_FROM_decode_aper; +per_type_encoder_f SIZE_but_not_FROM_encode_aper; /*** <<< CTABLES [SIZE-but-not-FROM] >>> ***/ @@ -1446,6 +1478,8 @@ xer_type_decoder_f SIZE_and_FROM_decode_xer; xer_type_encoder_f SIZE_and_FROM_encode_xer; per_type_decoder_f SIZE_and_FROM_decode_uper; per_type_encoder_f SIZE_and_FROM_encode_uper; +per_type_decoder_f SIZE_and_FROM_decode_aper; +per_type_encoder_f SIZE_and_FROM_encode_aper; /*** <<< CTABLES [SIZE-and-FROM] >>> ***/ @@ -1546,6 +1580,8 @@ xer_type_decoder_f Neither_SIZE_nor_FROM_decode_xer; xer_type_encoder_f Neither_SIZE_nor_FROM_encode_xer; per_type_decoder_f Neither_SIZE_nor_FROM_decode_uper; per_type_encoder_f Neither_SIZE_nor_FROM_encode_uper; +per_type_decoder_f Neither_SIZE_nor_FROM_decode_aper; +per_type_encoder_f Neither_SIZE_nor_FROM_encode_aper; /*** <<< CTABLES [Neither-SIZE-nor-FROM] >>> ***/ @@ -1643,6 +1679,8 @@ xer_type_decoder_f Utf8_4_decode_xer; xer_type_encoder_f Utf8_4_encode_xer; per_type_decoder_f Utf8_4_decode_uper; per_type_encoder_f Utf8_4_encode_uper; +per_type_decoder_f Utf8_4_decode_aper; +per_type_encoder_f Utf8_4_encode_aper; /*** <<< CTABLES [Utf8-4] >>> ***/ @@ -1734,6 +1772,8 @@ xer_type_decoder_f Utf8_3_decode_xer; xer_type_encoder_f Utf8_3_encode_xer; per_type_decoder_f Utf8_3_decode_uper; per_type_encoder_f Utf8_3_encode_uper; +per_type_decoder_f Utf8_3_decode_aper; +per_type_encoder_f Utf8_3_encode_aper; /*** <<< CTABLES [Utf8-3] >>> ***/ @@ -1854,6 +1894,8 @@ xer_type_decoder_f Utf8_2_decode_xer; xer_type_encoder_f Utf8_2_encode_xer; per_type_decoder_f Utf8_2_decode_uper; per_type_encoder_f Utf8_2_encode_uper; +per_type_decoder_f Utf8_2_decode_aper; +per_type_encoder_f Utf8_2_encode_aper; /*** <<< CODE [Utf8-2] >>> ***/ @@ -1943,6 +1985,8 @@ xer_type_decoder_f Utf8_1_decode_xer; xer_type_encoder_f Utf8_1_encode_xer; per_type_decoder_f Utf8_1_decode_uper; per_type_encoder_f Utf8_1_encode_uper; +per_type_decoder_f Utf8_1_decode_aper; +per_type_encoder_f Utf8_1_encode_aper; /*** <<< CODE [Utf8-1] >>> ***/ @@ -1992,6 +2036,8 @@ xer_type_decoder_f VisibleIdentifier_decode_xer; xer_type_encoder_f VisibleIdentifier_encode_xer; per_type_decoder_f VisibleIdentifier_decode_uper; per_type_encoder_f VisibleIdentifier_encode_uper; +per_type_decoder_f VisibleIdentifier_decode_aper; +per_type_encoder_f VisibleIdentifier_encode_aper; /*** <<< CTABLES [VisibleIdentifier] >>> ***/ @@ -2545,6 +2591,8 @@ xer_type_decoder_f Enum0_decode_xer; xer_type_encoder_f Enum0_encode_xer; per_type_decoder_f Enum0_decode_uper; per_type_encoder_f Enum0_encode_uper; +per_type_decoder_f Enum0_decode_aper; +per_type_encoder_f Enum0_encode_aper; /*** <<< CODE [Enum0] >>> ***/ @@ -2626,6 +2674,8 @@ xer_type_decoder_f Enum1_decode_xer; xer_type_encoder_f Enum1_encode_xer; per_type_decoder_f Enum1_decode_uper; per_type_encoder_f Enum1_encode_uper; +per_type_decoder_f Enum1_decode_aper; +per_type_encoder_f Enum1_encode_aper; /*** <<< CODE [Enum1] >>> ***/ @@ -2726,6 +2776,8 @@ xer_type_decoder_f Identifier_decode_xer; xer_type_encoder_f Identifier_encode_xer; per_type_decoder_f Identifier_decode_uper; per_type_encoder_f Identifier_encode_uper; +per_type_decoder_f Identifier_decode_aper; +per_type_encoder_f Identifier_encode_aper; /*** <<< CTABLES [Identifier] >>> ***/ diff --git a/tests/tests-asn1c-compiler/90-cond-int-type-OK.asn1.-Pgen-PER b/tests/tests-asn1c-compiler/90-cond-int-type-OK.asn1.-Pgen-PER index ee2e421df..2a5fb36e7 100644 --- a/tests/tests-asn1c-compiler/90-cond-int-type-OK.asn1.-Pgen-PER +++ b/tests/tests-asn1c-compiler/90-cond-int-type-OK.asn1.-Pgen-PER @@ -19,6 +19,8 @@ xer_type_decoder_f CN_IntegerUnlimited_decode_xer; xer_type_encoder_f CN_IntegerUnlimited_encode_xer; per_type_decoder_f CN_IntegerUnlimited_decode_uper; per_type_encoder_f CN_IntegerUnlimited_encode_uper; +per_type_decoder_f CN_IntegerUnlimited_decode_aper; +per_type_encoder_f CN_IntegerUnlimited_encode_aper; /*** <<< CODE [CN-IntegerUnlimited] >>> ***/ @@ -68,6 +70,8 @@ xer_type_decoder_f CN_IntegerMinMax_decode_xer; xer_type_encoder_f CN_IntegerMinMax_encode_xer; per_type_decoder_f CN_IntegerMinMax_decode_uper; per_type_encoder_f CN_IntegerMinMax_encode_uper; +per_type_decoder_f CN_IntegerMinMax_decode_aper; +per_type_encoder_f CN_IntegerMinMax_encode_aper; /*** <<< CODE [CN-IntegerMinMax] >>> ***/ @@ -144,6 +148,8 @@ xer_type_decoder_f CN_IntegerMinLow_decode_xer; xer_type_encoder_f CN_IntegerMinLow_encode_xer; per_type_decoder_f CN_IntegerMinLow_decode_uper; per_type_encoder_f CN_IntegerMinLow_encode_uper; +per_type_decoder_f CN_IntegerMinLow_decode_aper; +per_type_encoder_f CN_IntegerMinLow_encode_aper; /*** <<< CODE [CN-IntegerMinLow] >>> ***/ @@ -226,6 +232,8 @@ xer_type_decoder_f NO_IntegerMinHigh_decode_xer; xer_type_encoder_f NO_IntegerMinHigh_encode_xer; per_type_decoder_f NO_IntegerMinHigh_decode_uper; per_type_encoder_f NO_IntegerMinHigh_encode_uper; +per_type_decoder_f NO_IntegerMinHigh_decode_aper; +per_type_encoder_f NO_IntegerMinHigh_encode_aper; /*** <<< CODE [NO-IntegerMinHigh] >>> ***/ @@ -314,6 +322,8 @@ xer_type_decoder_f NO_IntegerLowHigh_decode_xer; xer_type_encoder_f NO_IntegerLowHigh_encode_xer; per_type_decoder_f NO_IntegerLowHigh_decode_uper; per_type_encoder_f NO_IntegerLowHigh_encode_uper; +per_type_decoder_f NO_IntegerLowHigh_decode_aper; +per_type_encoder_f NO_IntegerLowHigh_encode_aper; /*** <<< CODE [NO-IntegerLowHigh] >>> ***/ @@ -401,6 +411,8 @@ xer_type_decoder_f CN_IntegerLowMax_decode_xer; xer_type_encoder_f CN_IntegerLowMax_encode_xer; per_type_decoder_f CN_IntegerLowMax_decode_uper; per_type_encoder_f CN_IntegerLowMax_encode_uper; +per_type_decoder_f CN_IntegerLowMax_decode_aper; +per_type_encoder_f CN_IntegerLowMax_encode_aper; /*** <<< CODE [CN-IntegerLowMax] >>> ***/ @@ -488,6 +500,8 @@ xer_type_decoder_f NO_IntegerHighMax_decode_xer; xer_type_encoder_f NO_IntegerHighMax_encode_xer; per_type_decoder_f NO_IntegerHighMax_decode_uper; per_type_encoder_f NO_IntegerHighMax_encode_uper; +per_type_decoder_f NO_IntegerHighMax_decode_aper; +per_type_encoder_f NO_IntegerHighMax_encode_aper; /*** <<< CODE [NO-IntegerHighMax] >>> ***/ @@ -576,6 +590,8 @@ xer_type_decoder_f NO_IntegerLowestMax_decode_xer; xer_type_encoder_f NO_IntegerLowestMax_encode_xer; per_type_decoder_f NO_IntegerLowestMax_decode_uper; per_type_encoder_f NO_IntegerLowestMax_encode_uper; +per_type_decoder_f NO_IntegerLowestMax_decode_aper; +per_type_encoder_f NO_IntegerLowestMax_encode_aper; /*** <<< CODE [NO-IntegerLowestMax] >>> ***/ @@ -664,6 +680,8 @@ xer_type_decoder_f NO_IntegerOutRange_decode_xer; xer_type_encoder_f NO_IntegerOutRange_encode_xer; per_type_decoder_f NO_IntegerOutRange_decode_uper; per_type_encoder_f NO_IntegerOutRange_encode_uper; +per_type_decoder_f NO_IntegerOutRange_decode_aper; +per_type_encoder_f NO_IntegerOutRange_encode_aper; /*** <<< CODE [NO-IntegerOutRange] >>> ***/ @@ -751,6 +769,8 @@ xer_type_decoder_f NO_IntegerOutValue_decode_xer; xer_type_encoder_f NO_IntegerOutValue_encode_xer; per_type_decoder_f NO_IntegerOutValue_decode_uper; per_type_encoder_f NO_IntegerOutValue_encode_uper; +per_type_decoder_f NO_IntegerOutValue_decode_aper; +per_type_encoder_f NO_IntegerOutValue_encode_aper; /*** <<< CODE [NO-IntegerOutValue] >>> ***/ @@ -838,6 +858,8 @@ xer_type_decoder_f OK_IntegerInRange1_decode_xer; xer_type_encoder_f OK_IntegerInRange1_encode_xer; per_type_decoder_f OK_IntegerInRange1_decode_uper; per_type_encoder_f OK_IntegerInRange1_encode_uper; +per_type_decoder_f OK_IntegerInRange1_decode_aper; +per_type_encoder_f OK_IntegerInRange1_encode_aper; /*** <<< CODE [OK-IntegerInRange1] >>> ***/ @@ -920,6 +942,8 @@ xer_type_decoder_f OK_IntegerInRange2_decode_xer; xer_type_encoder_f OK_IntegerInRange2_encode_xer; per_type_decoder_f OK_IntegerInRange2_decode_uper; per_type_encoder_f OK_IntegerInRange2_encode_uper; +per_type_decoder_f OK_IntegerInRange2_decode_aper; +per_type_encoder_f OK_IntegerInRange2_encode_aper; /*** <<< CODE [OK-IntegerInRange2] >>> ***/ @@ -1002,6 +1026,8 @@ xer_type_decoder_f OK_IntegerInRange3_decode_xer; xer_type_encoder_f OK_IntegerInRange3_encode_xer; per_type_decoder_f OK_IntegerInRange3_decode_uper; per_type_encoder_f OK_IntegerInRange3_encode_uper; +per_type_decoder_f OK_IntegerInRange3_decode_aper; +per_type_encoder_f OK_IntegerInRange3_encode_aper; /*** <<< CODE [OK-IntegerInRange3] >>> ***/ @@ -1084,6 +1110,8 @@ xer_type_decoder_f OK_IntegerInRange4_decode_xer; xer_type_encoder_f OK_IntegerInRange4_encode_xer; per_type_decoder_f OK_IntegerInRange4_decode_uper; per_type_encoder_f OK_IntegerInRange4_encode_uper; +per_type_decoder_f OK_IntegerInRange4_decode_aper; +per_type_encoder_f OK_IntegerInRange4_encode_aper; /*** <<< CODE [OK-IntegerInRange4] >>> ***/ @@ -1166,6 +1194,8 @@ xer_type_decoder_f OK_IntegerInRange5_decode_xer; xer_type_encoder_f OK_IntegerInRange5_encode_xer; per_type_decoder_f OK_IntegerInRange5_decode_uper; per_type_encoder_f OK_IntegerInRange5_encode_uper; +per_type_decoder_f OK_IntegerInRange5_decode_aper; +per_type_encoder_f OK_IntegerInRange5_encode_aper; /*** <<< CODE [OK-IntegerInRange5] >>> ***/ @@ -1248,6 +1278,8 @@ xer_type_decoder_f NO_IntegerInRange6_decode_xer; xer_type_encoder_f NO_IntegerInRange6_encode_xer; per_type_decoder_f NO_IntegerInRange6_decode_uper; per_type_encoder_f NO_IntegerInRange6_encode_uper; +per_type_decoder_f NO_IntegerInRange6_decode_aper; +per_type_encoder_f NO_IntegerInRange6_encode_aper; /*** <<< CODE [NO-IntegerInRange6] >>> ***/ @@ -1333,6 +1365,8 @@ xer_type_decoder_f CN_IntegerEnumerated1_decode_xer; xer_type_encoder_f CN_IntegerEnumerated1_encode_xer; per_type_decoder_f CN_IntegerEnumerated1_decode_uper; per_type_encoder_f CN_IntegerEnumerated1_encode_uper; +per_type_decoder_f CN_IntegerEnumerated1_decode_aper; +per_type_encoder_f CN_IntegerEnumerated1_encode_aper; /*** <<< CODE [CN-IntegerEnumerated1] >>> ***/ @@ -1389,6 +1423,8 @@ xer_type_decoder_f NO_IntegerEnumerated2_decode_xer; xer_type_encoder_f NO_IntegerEnumerated2_encode_xer; per_type_decoder_f NO_IntegerEnumerated2_decode_uper; per_type_encoder_f NO_IntegerEnumerated2_encode_uper; +per_type_decoder_f NO_IntegerEnumerated2_decode_aper; +per_type_encoder_f NO_IntegerEnumerated2_encode_aper; /*** <<< CODE [NO-IntegerEnumerated2] >>> ***/