From 7ef7bc9226dc36f373164c119046526bc9c5f397 Mon Sep 17 00:00:00 2001 From: Navid Nikaein Date: Sat, 16 Nov 2013 21:17:22 +0000 Subject: [PATCH] update the patch file with the latest modifications git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4421 818b1a75-f10b-46b9-bf7c-635c3b92a50f --- openair-cn/S1AP/MESSAGES/ASN1/README | 5 +- openair-cn/S1AP/MESSAGES/ASN1/asn1cpatch.p0 | 6068 +++++++++++-------- 2 files changed, 3458 insertions(+), 2615 deletions(-) diff --git a/openair-cn/S1AP/MESSAGES/ASN1/README b/openair-cn/S1AP/MESSAGES/ASN1/README index c1d981ee5f..7a4220be67 100644 --- a/openair-cn/S1AP/MESSAGES/ASN1/README +++ b/openair-cn/S1AP/MESSAGES/ASN1/README @@ -2,9 +2,10 @@ ASN1 message from S1AP TS 36.413-8a0 To successfully parse messages, the asn1c util should be patched with the patch provided (asn1cpatch.p0). To do so: -1) Get the last revision of asn1c: svn co https://asn1c.svn.sourceforge.net/svnroot/asn1c/trunk asn1c +1) Get the last revision of asn1c: svn co https://github.com/vlm/asn1c/trunk -r 1516 + 2) Go to asn1c directory -3) patch -p0 asn1cpatch.p0 +3) patch -p0 < ../asn1cpatch.p0 4) ./configure 5) make 6) make install diff --git a/openair-cn/S1AP/MESSAGES/ASN1/asn1cpatch.p0 b/openair-cn/S1AP/MESSAGES/ASN1/asn1cpatch.p0 index 17c13dfb53..cbd54d1329 100644 --- a/openair-cn/S1AP/MESSAGES/ASN1/asn1cpatch.p0 +++ b/openair-cn/S1AP/MESSAGES/ASN1/asn1cpatch.p0 @@ -1,604 +1,66 @@ -Index: skeletons/GeneralString.c +Index: asn1c/unber.c =================================================================== ---- skeletons/GeneralString.c (revision 1410) -+++ skeletons/GeneralString.c (working copy) -@@ -24,6 +24,8 @@ - OCTET_STRING_encode_xer, - OCTET_STRING_decode_uper, /* Implemented in terms of OCTET STRING */ - OCTET_STRING_encode_uper, -+ OCTET_STRING_decode_aper, -+ OCTET_STRING_encode_aper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_GeneralString_tags, - sizeof(asn_DEF_GeneralString_tags) -Index: skeletons/OCTET_STRING.c +--- asn1c/unber.c (revision 1516) ++++ asn1c/unber.c (working copy) +@@ -775,4 +775,8 @@ + + asn_enc_rval_t OCTET_STRING_encode_uper(asn_TYPE_descriptor_t *td, asn_per_constraints_t *cts, void *sptr, asn_per_outp_t *po) { asn_enc_rval_t er = { 0, 0, 0 }; (void)td; (void)cts; (void)sptr; (void)po; return er; } + ++asn_dec_rval_t OCTET_STRING_decode_aper(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td, asn_per_constraints_t *cts, void **sptr, asn_per_data_t *pd) { asn_dec_rval_t rv = { 0, 0 }; (void)ctx; (void)td; (void)cts; (void)sptr; (void)pd; return rv; } ++ ++asn_enc_rval_t OCTET_STRING_encode_aper(asn_TYPE_descriptor_t *td, asn_per_constraints_t *cts, void *sptr, asn_per_outp_t *po) { asn_enc_rval_t er = { 0, 0, 0 }; (void)td; (void)cts; (void)sptr; (void)po; return er; } ++ + size_t xer_whitespace_span(const void *chunk_buf, size_t chunk_size) { (void)chunk_buf; (void)chunk_size; return 0; } +Index: asn1c/asn1c.c =================================================================== ---- skeletons/OCTET_STRING.c (revision 1410) -+++ skeletons/OCTET_STRING.c (working copy) -@@ -36,6 +36,8 @@ - OCTET_STRING_encode_xer, - 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 */ - 0, /* Use generic outmost tag fetcher */ - asn_DEF_OCTET_STRING_tags, - sizeof(asn_DEF_OCTET_STRING_tags) -@@ -86,7 +88,7 @@ - void *ptr; \ - /* Be nice and round to the memory allocator */ \ - do { _ns = _ns ? _ns << 1 : 16; } \ -- while(_ns <= _es); \ -+ while(_ns <= _es); \ - /* int is really a typeof(st->size): */ \ - if((int)_ns < 0) RETURN(RC_FAIL); \ - ptr = REALLOC(st->buf, _ns); \ -@@ -416,7 +418,7 @@ - ASN_DEBUG("Phase 2: Need %ld bytes, size=%ld, alrg=%ld, wn=%d", - (long)sel->left, (long)size, (long)sel->got, - sel->want_nulls); -- { -+ { - ber_tlv_len_t len; - - assert(sel->left >= 0); -@@ -446,7 +448,7 @@ - - PREV_PHASE(ctx); - goto phase1; -- } -+ } - break; - case 3: - phase3: -@@ -1194,14 +1196,14 @@ - static int - OCTET_STRING_per_get_characters(asn_per_data_t *po, uint8_t *buf, - size_t units, unsigned int bpc, unsigned int unit_bits, -- long lb, long ub, asn_per_constraints_t *pc) { -+ int64_t lb, int64_t ub, asn_per_constraints_t *pc) { - uint8_t *end = buf + units * bpc; - -- ASN_DEBUG("Expanding %d characters into (%ld..%ld):%d", -+ ASN_DEBUG("Expanding %d characters into (%lld..%lld):%d", - (int)units, lb, ub, unit_bits); - - /* X.691: 27.5.4 */ -- if((unsigned long)ub <= ((unsigned long)2 << (unit_bits - 1))) { -+ if((uint64_t)ub <= ((uint64_t)2 << (unit_bits - 1))) { - /* Decode without translation */ - lb = 0; - } else if(pc && pc->code2value) { -@@ -1216,7 +1218,7 @@ - value = pc->code2value(code); - if(value < 0) { - ASN_DEBUG("Code %d (0x%02x) is" -- " not in map (%ld..%ld)", -+ " not in map (%lld..%lld)", - code, code, lb, ub); - return 1; /* FATAL */ - } -@@ -1240,7 +1242,7 @@ - int ch = code + lb; - if(code < 0) return -1; /* WMORE */ - if(ch > ub) { -- ASN_DEBUG("Code %d is out of range (%ld..%ld)", -+ ASN_DEBUG("Code %d is out of range (%lld..%lld)", - ch, lb, ub); - return 1; /* FATAL */ - } -@@ -1258,14 +1260,14 @@ - static int - OCTET_STRING_per_put_characters(asn_per_outp_t *po, const uint8_t *buf, - size_t units, unsigned int bpc, unsigned int unit_bits, -- long lb, long ub, asn_per_constraints_t *pc) { -+ int64_t lb, int64_t ub, asn_per_constraints_t *pc) { - const uint8_t *end = buf + units * bpc; - -- ASN_DEBUG("Squeezing %d characters into (%ld..%ld):%d (%d bpc)", -+ ASN_DEBUG("Squeezing %d characters into (%lld..%lld):%d (%d bpc)", - (int)units, lb, ub, unit_bits, bpc); - - /* X.691: 27.5.4 */ -- if((unsigned long)ub <= ((unsigned long)2 << (unit_bits - 1))) { -+ if((uint64_t)ub <= ((uint64_t)2 << (unit_bits - 1))) { - /* Encode as is */ - lb = 0; - } else if(pc && pc->value2code) { -@@ -1282,7 +1284,7 @@ - code = pc->value2code(value); - if(code < 0) { - ASN_DEBUG("Character %d (0x%02x) is" -- " not in map (%ld..%ld)", -+ " not in map (%lld..%lld)", - *buf, *buf, lb, ub); - return -1; - } -@@ -1309,7 +1311,7 @@ - ch = value - lb; - if(ch < 0 || ch > ub) { - ASN_DEBUG("Character %d (0x%02x)" -- " is out of range (%ld..%ld)", -+ " is out of range (%lld..%lld)", - *buf, *buf, lb, ub + lb); - return -1; - } -@@ -1392,7 +1394,7 @@ - if(!st) RETURN(RC_FAIL); - } - -- ASN_DEBUG("PER Decoding %s size %ld .. %ld bits %d", -+ ASN_DEBUG("PER Decoding %s size %lld .. %lld bits %d", - csiz->flags & APC_EXTENSIBLE ? "extensible" : "non-extensible", - csiz->lower_bound, csiz->upper_bound, csiz->effective_bits); - -@@ -1423,17 +1425,17 @@ - if(csiz->effective_bits == 0) { - int ret; - if(bpc) { -- ASN_DEBUG("Encoding OCTET STRING size %ld", -+ ASN_DEBUG("Encoding OCTET STRING size %lld", - 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); +--- asn1c/asn1c.c (revision 1516) ++++ asn1c/asn1c.c (working copy) +@@ -111,6 +111,8 @@ + asn1_compiler_flags &= ~A1C_LINK_SKELETONS; + } else if(strcmp(optarg, "link-skeletons") == 0) { + asn1_compiler_flags |= A1C_LINK_SKELETONS; ++ } else if(strcmp(optarg, "have_native64") == 0) { ++ asn1_compiler_flags |= A1C_HAVE_NATIVE_64; } else { -- ASN_DEBUG("Encoding BIT STRING size %ld", -+ ASN_DEBUG("Encoding BIT STRING size %lld", - csiz->upper_bound); - ret = per_get_many_bits(pd, st->buf, 0, -- unit_bits * csiz->upper_bound); -+ unit_bits * csiz->upper_bound); - } - if(ret < 0) RETURN(RC_WMORE); - consumed_myself += unit_bits * csiz->upper_bound; -@@ -1492,9 +1494,197 @@ - return rval; - } + fprintf(stderr, "-f%s: Invalid argument\n", optarg); + exit(EX_USAGE); +@@ -471,6 +473,7 @@ + " -fno-include-deps Do not generate courtesy #includes for dependencies\n" + " -funnamed-unions Enable unnamed unions in structures\n" + " -fwide-types Use INTEGER_t instead of \"long\" by default, etc.\n" ++" -fhave_native64 Use int64_t/uint64_t for target platform\n" + "\n" -+asn_dec_rval_t -+OCTET_STRING_decode_aper(asn_codec_ctx_t *opt_codec_ctx, -+ asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, -+ void **sptr, asn_per_data_t *pd) { -+ -+ asn_OCTET_STRING_specifics_t *specs = td->specifics -+ ? (asn_OCTET_STRING_specifics_t *)td->specifics -+ : &asn_DEF_OCTET_STRING_specs; -+ asn_per_constraints_t *pc = constraints ? constraints -+ : td->per_constraints; -+ asn_per_constraint_t *cval; -+ 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 %lld .. %lld 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 %lld", -+ 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 %lld", -+ 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_uper(asn_TYPE_descriptor_t *td, -- asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { -+ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { - - asn_OCTET_STRING_specifics_t *specs = td->specifics - ? (asn_OCTET_STRING_specifics_t *)td->specifics -@@ -1566,7 +1756,7 @@ - } - - ASN_DEBUG("Encoding %s into %d units of %d bits" -- " (%ld..%ld, effective %d)%s", -+ " (%lld..%lld, effective %d)%s", - td->name, sizeinunits, unit_bits, - csiz->lower_bound, csiz->upper_bound, - csiz->effective_bits, ct_extensible ? " EXT" : ""); -@@ -1598,7 +1788,7 @@ - /* 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 %d bytes (%ld), length in %d bits", -+ ASN_DEBUG("Encoding %d bytes (%lld), length in %d bits", - st->size, sizeinunits - csiz->lower_bound, - csiz->effective_bits); - ret = per_put_few_bits(po, sizeinunits - csiz->lower_bound, -@@ -1652,6 +1842,173 @@ - _ASN_ENCODED_OK(er); - } - -+asn_enc_rval_t -+OCTET_STRING_encode_aper(asn_TYPE_descriptor_t *td, -+ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { -+ -+ asn_OCTET_STRING_specifics_t *specs = td->specifics -+ ? (asn_OCTET_STRING_specifics_t *)td->specifics -+ : &asn_DEF_OCTET_STRING_specs; -+ asn_per_constraints_t *pc = constraints ? constraints -+ : td->per_constraints; -+ asn_per_constraint_t *cval; -+ 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 bits", -+ 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" -+ " (%lld..%lld, 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 %d bytes (%lld), length in %d bits", -+ st->size, sizeinunits - csiz->lower_bound, -+ csiz->effective_bits); -+ ret = per_put_few_bits(po, sizeinunits - csiz->lower_bound, -+ csiz->effective_bits); -+ 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 %d 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); -+} -+ - int - OCTET_STRING_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, - asn_app_consume_bytes_f *cb, void *app_key) { -Index: skeletons/IA5String.c + " -gen-PER Generate PER support code\n" +Index: examples/README =================================================================== ---- skeletons/IA5String.c (revision 1410) -+++ skeletons/IA5String.c (working copy) -@@ -29,6 +29,8 @@ +--- examples/README (revision 1516) ++++ examples/README (working copy) +@@ -25,6 +25,8 @@ + UserPlane Location Protocol decoder. Before trying to compile, read the + README file in that directory. + ++The clyx2asn1.pl script can be used to extract ASN.1 data from LyX editor files. ++ + The crfc2asn1.pl script can be used to extract ASN.1 data from RFC texts. + For instance, it is used to extract X.509, MEGACO, and LDAPv3 ASN.1 modules + from the corresponding RFC texts (rfc3280.txt, rfc3525.txt, rfc4211.txt). +Index: skeletons/UTF8String.c +=================================================================== +--- skeletons/UTF8String.c (revision 1516) ++++ skeletons/UTF8String.c (working copy) +@@ -25,6 +25,8 @@ OCTET_STRING_encode_xer_utf8, OCTET_STRING_decode_uper, OCTET_STRING_encode_uper, + OCTET_STRING_decode_aper, + OCTET_STRING_encode_aper, 0, /* Use generic outmost tag fetcher */ - asn_DEF_IA5String_tags, - sizeof(asn_DEF_IA5String_tags) -Index: skeletons/OBJECT_IDENTIFIER.c -=================================================================== ---- skeletons/OBJECT_IDENTIFIER.c (revision 1410) -+++ skeletons/OBJECT_IDENTIFIER.c (working copy) -@@ -26,6 +26,8 @@ - OBJECT_IDENTIFIER_encode_xer, - OCTET_STRING_decode_uper, - OCTET_STRING_encode_uper, -+ OCTET_STRING_decode_aper, -+ OCTET_STRING_encode_aper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_OBJECT_IDENTIFIER_tags, - sizeof(asn_DEF_OBJECT_IDENTIFIER_tags) -Index: skeletons/GeneralizedTime.c -=================================================================== ---- skeletons/GeneralizedTime.c (revision 1410) -+++ skeletons/GeneralizedTime.c (working copy) -@@ -167,6 +167,8 @@ - GeneralizedTime_encode_xer, - OCTET_STRING_decode_uper, - OCTET_STRING_encode_uper, -+ OCTET_STRING_decode_aper, -+ OCTET_STRING_encode_aper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_GeneralizedTime_tags, - sizeof(asn_DEF_GeneralizedTime_tags) -Index: skeletons/OCTET_STRING.h -=================================================================== ---- skeletons/OCTET_STRING.h (revision 1410) -+++ skeletons/OCTET_STRING.h (working copy) -@@ -32,6 +32,8 @@ - xer_type_encoder_f OCTET_STRING_encode_xer_utf8; - 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; - - /****************************** - * Handy conversion routines. * + asn_DEF_UTF8String_tags, + sizeof(asn_DEF_UTF8String_tags) Index: skeletons/constr_TYPE.h =================================================================== ---- skeletons/constr_TYPE.h (revision 1410) +--- skeletons/constr_TYPE.h (revision 1516) +++ skeletons/constr_TYPE.h (working copy) @@ -99,6 +99,8 @@ xer_type_encoder_f *xer_encoder; /* [Canonical] XER encoder */ @@ -609,27 +71,346 @@ Index: skeletons/constr_TYPE.h /*********************************************************************** * Internally useful members. Not to be used by applications directly. * -Index: skeletons/constr_CHOICE.c +Index: skeletons/RELATIVE-OID.c =================================================================== ---- skeletons/constr_CHOICE.c (revision 1410) -+++ skeletons/constr_CHOICE.c (working copy) -@@ -904,7 +904,88 @@ - elm->name, td->name, rv.code); +--- skeletons/RELATIVE-OID.c (revision 1516) ++++ skeletons/RELATIVE-OID.c (working copy) +@@ -28,6 +28,8 @@ + RELATIVE_OID_encode_xer, + OCTET_STRING_decode_uper, + OCTET_STRING_encode_uper, ++ OCTET_STRING_decode_aper, ++ OCTET_STRING_encode_aper, + 0, /* Use generic outmost tag fetcher */ + asn_DEF_RELATIVE_OID_tags, + sizeof(asn_DEF_RELATIVE_OID_tags) +Index: skeletons/per_encoder.c +=================================================================== +--- skeletons/per_encoder.c (revision 1516) ++++ skeletons/per_encoder.c (working copy) +@@ -4,6 +4,7 @@ + + static asn_enc_rval_t uper_encode_internal(asn_TYPE_descriptor_t *td, asn_per_constraints_t *, void *sptr, asn_app_consume_bytes_f *cb, void *app_key); + ++static asn_enc_rval_t aper_encode_internal(asn_TYPE_descriptor_t *td, asn_per_constraints_t *, void *sptr, asn_app_consume_bytes_f *cb, void *app_key); + asn_enc_rval_t + uper_encode(asn_TYPE_descriptor_t *td, void *sptr, asn_app_consume_bytes_f *cb, void *app_key) { + return uper_encode_internal(td, 0, sptr, cb, app_key); +@@ -41,6 +42,18 @@ + return uper_encode_internal(td, 0, sptr, encode_to_buffer_cb, &key); + } + ++asn_enc_rval_t ++aper_encode_to_buffer(asn_TYPE_descriptor_t *td, 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); ++} ++ + typedef struct enc_dyn_arg { + void *buffer; + size_t length; +@@ -93,6 +106,35 @@ + } + } + ++ssize_t ++aper_encode_to_new_buffer(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, 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", (long)er.encoded); ++ return ((er.encoded + 7) >> 3); ++ } ++} ++ + /* + * Internally useful functions. + */ +@@ -115,6 +157,23 @@ + return po->outper(po->tmpspace, buf - po->tmpspace, po->op_key); + } + ++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++; ++ } ++ ++ return po->outper(po->tmpspace, buf - po->tmpspace, po->op_key); ++} ++ + static asn_enc_rval_t + uper_encode_internal(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_app_consume_bytes_f *cb, void *app_key) { + asn_per_outp_t po; +@@ -149,3 +208,37 @@ + return er; + } + ++static asn_enc_rval_t ++aper_encode_internal(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, 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->aper_encoder) ++ _ASN_ENCODE_FAILED; /* PER is not compiled in */ ++ ++ po.buffer = po.tmpspace; ++ po.nboff = 0; ++ po.nbits = 8 * sizeof(po.tmpspace); ++ po.outper = cb; ++ po.op_key = app_key; ++ po.flushed_bytes = 0; ++ ++ er = td->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; ++} ++ +Index: skeletons/NumericString.c +=================================================================== +--- skeletons/NumericString.c (revision 1516) ++++ skeletons/NumericString.c (working copy) +@@ -49,6 +49,8 @@ + OCTET_STRING_encode_xer_utf8, + OCTET_STRING_decode_uper, + OCTET_STRING_encode_uper, ++ OCTET_STRING_decode_aper, ++ OCTET_STRING_encode_aper, + 0, /* Use generic outmost tag fetcher */ + asn_DEF_NumericString_tags, + sizeof(asn_DEF_NumericString_tags) +Index: skeletons/per_encoder.h +=================================================================== +--- skeletons/per_encoder.h (revision 1516) ++++ skeletons/per_encoder.h (working copy) +@@ -38,6 +38,12 @@ + size_t buffer_size /* Initial buffer size (max) */ + ); + ++asn_enc_rval_t aper_encode_to_buffer( ++ struct asn_TYPE_descriptor_s *type_descriptor, ++ 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. +@@ -52,6 +58,11 @@ + void **buffer_r /* Buffer allocated and returned */ + ); + ++ssize_t ++aper_encode_to_new_buffer(struct asn_TYPE_descriptor_s *td, ++ asn_per_constraints_t *constraints, ++ void *sptr, ++ void **buffer_r); + /* + * Type of the generic PER encoder function. + */ +Index: skeletons/T61String.c +=================================================================== +--- skeletons/T61String.c (revision 1516) ++++ skeletons/T61String.c (working copy) +@@ -24,6 +24,8 @@ + OCTET_STRING_encode_xer, + OCTET_STRING_decode_uper, + OCTET_STRING_encode_uper, ++ OCTET_STRING_decode_aper, ++ OCTET_STRING_encode_aper, + 0, /* Use generic outmost tag fetcher */ + asn_DEF_T61String_tags, + sizeof(asn_DEF_T61String_tags) +Index: skeletons/TeletexString.c +=================================================================== +--- skeletons/TeletexString.c (revision 1516) ++++ skeletons/TeletexString.c (working copy) +@@ -24,6 +24,8 @@ + OCTET_STRING_encode_xer, + OCTET_STRING_decode_uper, + OCTET_STRING_encode_uper, ++ OCTET_STRING_decode_aper, ++ OCTET_STRING_encode_aper, + 0, /* Use generic outmost tag fetcher */ + asn_DEF_TeletexString_tags, + sizeof(asn_DEF_TeletexString_tags) +Index: skeletons/BMPString.c +=================================================================== +--- skeletons/BMPString.c (revision 1516) ++++ skeletons/BMPString.c (working copy) +@@ -35,6 +35,8 @@ + BMPString_encode_xer, /* Convert to UTF-8 */ + OCTET_STRING_decode_uper, + OCTET_STRING_encode_uper, ++ OCTET_STRING_decode_aper, /* Aligned PER decoder */ ++ OCTET_STRING_encode_aper, /* Aligned PER encoder */ + 0, /* Use generic outmost tag fetcher */ + asn_DEF_BMPString_tags, + sizeof(asn_DEF_BMPString_tags) +Index: skeletons/ObjectDescriptor.c +=================================================================== +--- skeletons/ObjectDescriptor.c (revision 1516) ++++ skeletons/ObjectDescriptor.c (working copy) +@@ -24,6 +24,8 @@ + OCTET_STRING_encode_xer_utf8, + OCTET_STRING_decode_uper, + OCTET_STRING_encode_uper, ++ OCTET_STRING_decode_aper, ++ OCTET_STRING_encode_aper, + 0, /* Use generic outmost tag fetcher */ + asn_DEF_ObjectDescriptor_tags, + sizeof(asn_DEF_ObjectDescriptor_tags) +Index: skeletons/PrintableString.c +=================================================================== +--- skeletons/PrintableString.c (revision 1516) ++++ skeletons/PrintableString.c (working copy) +@@ -59,6 +59,8 @@ + OCTET_STRING_encode_xer_utf8, + OCTET_STRING_decode_uper, + OCTET_STRING_encode_uper, ++ OCTET_STRING_decode_aper, ++ OCTET_STRING_encode_aper, + 0, /* Use generic outmost tag fetcher */ + asn_DEF_PrintableString_tags, + sizeof(asn_DEF_PrintableString_tags) +Index: skeletons/constr_SET_OF.c +=================================================================== +--- skeletons/constr_SET_OF.c (revision 1516) ++++ skeletons/constr_SET_OF.c (working copy) +@@ -34,7 +34,7 @@ + #undef ADVANCE + #define ADVANCE(num_bytes) do { \ + size_t num = num_bytes; \ +- ptr = ((const void *)ptr) + num;\ ++ ptr = ((const char *)ptr) + num;\ + size -= num; \ + if(ctx->left >= 0) \ + ctx->left -= num; \ +@@ -100,7 +100,7 @@ + /* + * Restore parsing context. + */ +- ctx = (asn_struct_ctx_t *)((void *)st + specs->ctx_offset); ++ ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset); + + /* + * Start to parse where left previously +@@ -457,7 +457,7 @@ + #undef XER_ADVANCE + #define XER_ADVANCE(num_bytes) do { \ + size_t num = num_bytes; \ +- buf_ptr = ((const void *)buf_ptr) + num;\ ++ buf_ptr = ((const char *)buf_ptr) + num;\ + size -= num; \ + consumed_myself += num; \ + } while(0) +@@ -505,7 +505,7 @@ + /* + * Restore parsing context. + */ +- ctx = (asn_struct_ctx_t *)((void *)st + specs->ctx_offset); ++ ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset); + + /* + * Phases of XER/XML processing: +@@ -627,7 +627,7 @@ + t->buffer = p; + t->size = newsize; + } +- memcpy((void *)t->buffer + t->offset, buffer, size); ++ memcpy((char *)t->buffer + t->offset, buffer, size); + t->offset += size; + return 0; + } +@@ -809,7 +809,7 @@ + asn_set_empty(list); /* Remove (list->array) */ + + specs = (asn_SET_OF_specifics_t *)td->specifics; +- ctx = (asn_struct_ctx_t *)((void *)ptr + specs->ctx_offset); ++ ctx = (asn_struct_ctx_t *)((char *)ptr + specs->ctx_offset); + if(ctx->ptr) { + ASN_STRUCT_FREE(*elm->type, ctx->ptr); + ctx->ptr = 0; +@@ -884,7 +884,7 @@ + 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 */ +@@ -901,7 +901,7 @@ + if(ct && ct->effective_bits >= 0) { + /* X.691, #19.5: No length determinant */ + nelems = per_get_few_bits(pd, ct->effective_bits); +- ASN_DEBUG("Preparing to fetch %ld+%ld elements from %s", ++ ASN_DEBUG("Preparing to fetch %ld+%"PRIdMAX" elements from %s", + (long)nelems, ct->lower_bound, td->name); + if(nelems < 0) _ASN_DECODE_STARVED; + nelems += ct->lower_bound; +@@ -951,3 +951,91 @@ return rv; } -- -+ + +asn_dec_rval_t -+CHOICE_decode_aper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, -+ asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { -+ asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics; ++SET_OF_decode_aper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, ++ asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { + asn_dec_rval_t rv; -+ asn_per_constraint_t *ct; -+ asn_TYPE_member_t *elm; /* CHOICE's element */ -+ void *memb_ptr; -+ void **memb_ptr2; ++ asn_SET_OF_specifics_t *specs = (asn_SET_OF_specifics_t *)td->specifics; ++ asn_TYPE_member_t *elm = td->elements; /* Single one */ + void *st = *sptr; -+ int value; ++ asn_anonymous_set_ *list; ++ asn_per_constraint_t *ct; ++ int repeat = 0; ++ ssize_t nelems; + + if(_ASN_STACK_OVERFLOW_CHECK(opt_codec_ctx)) + _ASN_DECODE_FAILED; @@ -641,207 +422,661 @@ Index: skeletons/constr_CHOICE.c + st = *sptr = CALLOC(1, specs->struct_size); + if(!st) _ASN_DECODE_FAILED; + } ++ list = _A_SET_FROM_VOID(st); + -+ if(constraints) ct = &constraints->value; -+ else if(td->per_constraints) ct = &td->per_constraints->value; ++ /* Figure out which constraints to use */ ++ if(constraints) ct = &constraints->size; ++ else if(td->per_constraints) ct = &td->per_constraints->size; + else ct = 0; + + if(ct && ct->flags & APC_EXTENSIBLE) { -+ value = per_get_few_bits(pd, 1); ++ int value = per_get_few_bits(pd, 1); + if(value < 0) _ASN_DECODE_STARVED; -+ if(value) ct = 0; /* Not restricted */ ++ 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; ++ if(ct && ct->effective_bits >= 0) { ++ /* X.691, #19.5: No length determinant */ ++// nelems = per_get_few_bits(pd, ct->effective_bits); ++ nelems = aper_get_nsnnwn(pd, ct->upper_bound - ct->lower_bound); ++ ASN_DEBUG("Preparing to fetch %ld+%"PRIdMAX" elements from %s", ++ (long)nelems, ct->lower_bound, td->name); ++ if(nelems < 0) _ASN_DECODE_STARVED; ++ nelems += ct->lower_bound; + } 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(value >= td->elements_count) ++ 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->aper_decoder(opt_codec_ctx, elm->type, ++ elm->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; ++} +Index: skeletons/NULL.c +=================================================================== +--- skeletons/NULL.c (revision 1516) ++++ skeletons/NULL.c (working copy) +@@ -25,6 +25,8 @@ + NULL_encode_xer, + NULL_decode_uper, /* Unaligned PER decoder */ + NULL_encode_uper, /* Unaligned PER encoder */ ++ NULL_decode_aper, /* Aligned PER decoder */ ++ NULL_encode_aper, /* Aligned PER encoder */ + 0, /* Use generic outmost tag fetcher */ + asn_DEF_NULL_tags, + sizeof(asn_DEF_NULL_tags) / sizeof(asn_DEF_NULL_tags[0]), +@@ -135,6 +137,34 @@ + return rv; + } + ++asn_dec_rval_t ++NULL_decode_aper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, ++ 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; ++ } + } + -+ /* Adjust if canonical order is different from natural order */ -+ if(specs->canonical_order) -+ value = specs->canonical_order[value]; ++ /* ++ * NULL type does not have content octets. ++ */ + -+ /* 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->aper_decoder(opt_codec_ctx, elm->type, -+ elm->per_constraints, memb_ptr2, pd); -+ } else { -+ rv = uper_open_type_get(opt_codec_ctx, elm->type, -+ elm->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); ++ rv.code = RC_OK; ++ rv.consumed = 0; + return rv; +} + asn_enc_rval_t - CHOICE_encode_uper(asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { -@@ -916,7 +997,7 @@ - - if(!sptr) _ASN_ENCODE_FAILED; - -- ASN_DEBUG("Encoding %s as CHOICE", td->name); -+ ASN_DEBUG("Encoding %s as CHOICE using UPER", td->name); - - if(constraints) ct = &constraints->value; - else if(td->per_constraints) ct = &td->per_constraints->value; -@@ -984,8 +1065,88 @@ - _ASN_ENCODED_OK(rval); - } + NULL_encode_uper(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, + void *sptr, asn_per_outp_t *po) { +@@ -148,3 +178,17 @@ + er.encoded = 0; + _ASN_ENCODED_OK(er); } -- - ++ +asn_enc_rval_t -+CHOICE_encode_aper(asn_TYPE_descriptor_t *td, -+ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { -+ asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics; -+ asn_TYPE_member_t *elm; /* CHOICE's element */ -+ asn_per_constraint_t *ct; -+ void *memb_ptr; -+ int present; ++NULL_encode_aper(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, ++ void *sptr, asn_per_outp_t *po) { ++ asn_enc_rval_t er; + -+ if(!sptr) _ASN_ENCODE_FAILED; -+ -+ ASN_DEBUG("Encoding %s as CHOICE using ALIGNED PER", td->name); -+ -+ if(constraints) ct = &constraints->value; -+ else if(td->per_constraints) ct = &td->per_constraints->value; -+ else ct = 0; ++ (void)td; ++ (void)constraints; ++ (void)sptr; ++ (void)po; + -+ 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 || present > td->elements_count) -+ _ASN_ENCODE_FAILED; -+ else -+ present--; -+ -+ /* Adjust if canonical order is different from natural order */ -+ if(specs->canonical_order) -+ present = specs->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; ++ er.encoded = 0; ++ _ASN_ENCODED_OK(er); ++} +Index: skeletons/per_decoder.c +=================================================================== +--- skeletons/per_decoder.c (revision 1516) ++++ skeletons/per_decoder.c (working copy) +@@ -37,6 +37,35 @@ + } + + 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_ENCODE_FAILED; -+ } -+ ct = 0; ++ ASN_DEBUG("Expecting single zeroed byte"); ++ rval.code = RC_FAIL; + } ++ } else { ++ /* Must contain at least 8 bits. */ ++ rval.code = RC_WMORE; ++ } + } -+ 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 = *(void **)((char *)sptr + elm->memb_offset); -+ if(!memb_ptr) _ASN_ENCODE_FAILED; -+ } else { -+ memb_ptr = (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->aper_encoder(elm->type, elm->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->per_constraints, -+ memb_ptr, po)) -+ _ASN_ENCODE_FAILED; -+ rval.encoded = 0; -+ _ASN_ENCODED_OK(rval); -+ } ++ ++ return rval; +} + - int - CHOICE_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, - asn_app_consume_bytes_f *cb, void *app_key) { -Index: skeletons/REAL.c -=================================================================== ---- skeletons/REAL.c (revision 1410) -+++ skeletons/REAL.c (working copy) -@@ -45,6 +45,8 @@ - REAL_encode_xer, - REAL_decode_uper, - REAL_encode_uper, -+ REAL_decode_aper, -+ REAL_encode_aper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_REAL_tags, - sizeof(asn_DEF_REAL_tags) / sizeof(asn_DEF_REAL_tags[0]), -@@ -358,6 +360,21 @@ - return OCTET_STRING_encode_uper(td, 0, sptr, po); ++asn_dec_rval_t + uper_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; +@@ -91,3 +120,57 @@ + return rval; } +asn_dec_rval_t -+REAL_decode_aper(asn_codec_ctx_t *opt_codec_ctx, -+ asn_TYPE_descriptor_t *td, 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); ++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->aper_decoder) ++ _ASN_DECODE_FAILED; /* PER is not compiled in */ ++ rval = td->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 %d, counted %d", ++ rval.consumed, pd.moved); ++ assert(rval.consumed == pd.moved); ++ } else { ++ /* PER codec is not a restartable */ ++ rval.consumed = 0; ++ } ++ return rval; ++} +Index: skeletons/constr_SET_OF.h +=================================================================== +--- skeletons/constr_SET_OF.h (revision 1516) ++++ skeletons/constr_SET_OF.h (working copy) +@@ -34,6 +34,8 @@ + xer_type_encoder_f SET_OF_encode_xer; + 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; + + #ifdef __cplusplus + } +Index: skeletons/NULL.h +=================================================================== +--- skeletons/NULL.h (revision 1516) ++++ skeletons/NULL.h (working copy) +@@ -25,6 +25,8 @@ + xer_type_encoder_f NULL_encode_xer; + 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; + + #ifdef __cplusplus + } +Index: skeletons/per_decoder.h +=================================================================== +--- skeletons/per_decoder.h (revision 1516) ++++ skeletons/per_decoder.h (working copy) +@@ -38,8 +38,30 @@ + 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), 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. + */ + typedef asn_dec_rval_t (per_type_decoder_f)(asn_codec_ctx_t *opt_codec_ctx, +Index: skeletons/per_support.c +=================================================================== +--- skeletons/per_support.c (revision 1516) ++++ skeletons/per_support.c (working copy) +@@ -31,6 +31,16 @@ + } + } + ++int32_t ++aper_get_align(asn_per_data_t *pd) { ++ ++ if(pd->nboff & 0x7) { ++ ASN_DEBUG("Aligning %d bits", 8 - (pd->nboff & 0x7)); ++ return per_get_few_bits(pd, 8 - (pd->nboff & 0x7)); ++ } ++ return 0; +} + -+asn_enc_rval_t -+REAL_encode_aper(asn_TYPE_descriptor_t *td, -+ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { -+ (void)constraints; /* No PER visible constraints */ -+ return OCTET_STRING_encode_aper(td, 0, sptr, po); + /* + * Extract a small number of bits (<= 31) from the specified PER data pointer. + */ +@@ -187,6 +197,36 @@ + return (16384 * value); + } + ++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); +} + - int - asn_REAL2double(const REAL_t *st, double *dbl_value) { - unsigned int octv; + /* + * Get the normally small length "n". + * This procedure used to decode length of extensions bit-maps +@@ -211,6 +251,25 @@ + } + } + ++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=%d", 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 */ ++ } ++} ++ + /* + * Get the normally small non-negative whole number. + * X.691, #10.6 +@@ -237,6 +296,40 @@ + return value; + } + ++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) { ++ if (range < 0) return -1; ++ /* 1 -> 8 bits */ ++ int i; ++ 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; ++ return -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; ++} ++ + /* + * Put the normally small non-negative whole number. + * X.691, #10.6 +@@ -263,7 +356,59 @@ + return per_put_few_bits(po, n, 8 * bytes); + } + ++int ++aper_put_nsnnwn(asn_per_outp_t *po, int range, int number) { ++ int bytes; + ++ /* 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; ++ ++ return per_put_few_bits(po, number, 8 * bytes); ++} ++ ++int aper_put_align(asn_per_outp_t *po) { ++ ++ if(po->nboff & 0x7) { ++ ASN_DEBUG("Aligning %d bits", 8 - (po->nboff & 0x7)); ++ if(per_put_few_bits(po, 0x00, (8 - (po->nboff & 0x7)))) ++ return -1; ++ } ++ return 0; ++} ++ + /* + * Put a small number of bits (<= 31). + */ +@@ -392,6 +537,8 @@ + ssize_t + uper_put_length(asn_per_outp_t *po, size_t length) { + ++ ASN_DEBUG("UPER put length %d", length); ++ + if(length <= 127) /* #10.9.3.6 */ + return per_put_few_bits(po, length, 8) + ? -1 : (ssize_t)length; +@@ -406,7 +553,34 @@ + ? -1 : (ssize_t)(length << 14); + } + ++ssize_t ++aper_put_length(asn_per_outp_t *po, int range, size_t length) { + ++ ASN_DEBUG("APER put length %d 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); ++} ++ ++ + /* + * Put the normally small length "n" into the stream. + * This procedure used to encode length of extensions bit-maps +@@ -429,3 +603,19 @@ + return 0; + } + ++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; ++} Index: skeletons/constr_SET.c =================================================================== ---- skeletons/constr_SET.c (revision 1410) +--- skeletons/constr_SET.c (revision 1516) +++ skeletons/constr_SET.c (working copy) -@@ -570,6 +570,181 @@ +@@ -36,7 +36,7 @@ + #undef ADVANCE + #define ADVANCE(num_bytes) do { \ + size_t num = num_bytes; \ +- ptr = ((const void *)ptr) + num;\ ++ ptr = ((const char *)ptr) + num;\ + size -= num; \ + if(ctx->left >= 0) \ + ctx->left -= num; \ +@@ -132,7 +132,7 @@ + /* + * Restore parsing context. + */ +- ctx = (asn_struct_ctx_t *)((void *)st + specs->ctx_offset); ++ ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset); + + /* + * Start to parse where left previously +@@ -250,7 +250,7 @@ + + skip = ber_skip_length(opt_codec_ctx, + BER_TLV_CONSTRUCTED(ptr), +- (const void *)ptr + tag_len, LEFT - tag_len); ++ (const char *)ptr + tag_len, LEFT - tag_len); + + switch(skip) { + case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE); +@@ -271,7 +271,7 @@ + * Check for duplications: must not overwrite + * already decoded elements. + */ +- if(ASN_SET_ISPRESENT2((void *)st + specs->pres_offset, edx)) { ++ if(ASN_SET_ISPRESENT2((char *)st + specs->pres_offset, edx)) { + ASN_DEBUG("SET %s: Duplicate element %s (%d)", + td->name, elements[edx].name, edx); + RETURN(RC_FAIL); +@@ -284,13 +284,13 @@ + */ + if(elements[edx].flags & ATF_POINTER) { + /* Member is a pointer to another structure */ +- memb_ptr2 = (void **)((void *)st + elements[edx].memb_offset); ++ memb_ptr2 = (void **)((char *)st + elements[edx].memb_offset); + } else { + /* + * A pointer to a pointer + * holding the start of the structure + */ +- memb_ptr = (void *)st + elements[edx].memb_offset; ++ memb_ptr = (char *)st + elements[edx].memb_offset; + memb_ptr2 = &memb_ptr; + } + /* +@@ -302,7 +302,7 @@ + elements[edx].tag_mode); + switch(rval.code) { + case RC_OK: +- ASN_SET_MKPRESENT((void *)st + specs->pres_offset, edx); ++ ASN_SET_MKPRESENT((char *)st + specs->pres_offset, edx); + break; + case RC_WMORE: /* More data expected */ + if(!SIZE_VIOLATION) { +@@ -369,7 +369,7 @@ + + ll = ber_skip_length(opt_codec_ctx, + BER_TLV_CONSTRUCTED(ptr), +- (const void *)ptr + tl, LEFT - tl); ++ (const char *)ptr + tl, LEFT - tl); + switch(ll) { + case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE); + /* Fall through */ +@@ -404,7 +404,7 @@ + unsigned int midx, pres, must; + + midx = edx/(8 * sizeof(specs->_mandatory_elements[0])); +- pres = ((unsigned int *)((void *)st+specs->pres_offset))[midx]; ++ pres = ((unsigned int *)((char *)st+specs->pres_offset))[midx]; + must = sys_ntohl(specs->_mandatory_elements[midx]); + + if((pres & must) == must) { +@@ -473,7 +473,7 @@ + * Compute the length of the encoding of this member. + */ + if(elm->flags & ATF_POINTER) { +- memb_ptr = *(void **)((void *)sptr + elm->memb_offset); ++ memb_ptr = *(void **)((char *)sptr + elm->memb_offset); + if(!memb_ptr) { + if(!elm->optional) + /* Mandatory elements missing */ +@@ -486,7 +486,7 @@ + continue; + } + } else { +- memb_ptr = (void *)((void *)sptr + elm->memb_offset); ++ memb_ptr = (void *)((char *)sptr + elm->memb_offset); + } + tmper = elm->type->der_encoder(elm->type, memb_ptr, + elm->tag_mode, elm->tag, +@@ -547,10 +547,10 @@ + elm = &td->elements[t2m[edx].el_no]; + + if(elm->flags & ATF_POINTER) { +- memb_ptr = *(void **)((void *)sptr + elm->memb_offset); ++ memb_ptr = *(void **)((char *)sptr + elm->memb_offset); + if(!memb_ptr) continue; + } else { +- memb_ptr = (void *)((void *)sptr + elm->memb_offset); ++ memb_ptr = (void *)((char *)sptr + elm->memb_offset); + } + tmper = elm->type->der_encoder(elm->type, memb_ptr, + elm->tag_mode, elm->tag, +@@ -570,10 +570,185 @@ _ASN_ENCODED_OK(er); } @@ -1023,16 +1258,128 @@ Index: skeletons/constr_SET.c #undef XER_ADVANCE #define XER_ADVANCE(num_bytes) do { \ size_t num = num_bytes; \ +- buf_ptr = ((const void *)buf_ptr) + num;\ ++ buf_ptr = ((const char *)buf_ptr) + num;\ + size -= num; \ + consumed_myself += num; \ + } while(0) +@@ -613,7 +788,7 @@ + /* + * Restore parsing context. + */ +- ctx = (asn_struct_ctx_t *)((void *)st + specs->ctx_offset); ++ ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset); + + /* + * Phases of XER/XML processing: +@@ -637,7 +812,7 @@ + void *memb_ptr; /* Pointer to the member */ + void **memb_ptr2; /* Pointer to that pointer */ + +- if(ASN_SET_ISPRESENT2((void *)st + specs->pres_offset, ++ if(ASN_SET_ISPRESENT2((char *)st + specs->pres_offset, + edx)) { + ASN_DEBUG("SET %s: Duplicate element %s (%d)", + td->name, elements[edx].name, edx); +@@ -648,10 +823,10 @@ + + if(elm->flags & ATF_POINTER) { + /* Member is a pointer to another structure */ +- memb_ptr2 = (void **)((void *)st ++ memb_ptr2 = (void **)((char *)st + + elm->memb_offset); + } else { +- memb_ptr = (void *)st + elm->memb_offset; ++ memb_ptr = (char *)st + elm->memb_offset; + memb_ptr2 = &memb_ptr; + } + +@@ -663,7 +838,7 @@ + if(tmprval.code != RC_OK) + RETURN(tmprval.code); + ctx->phase = 1; /* Back to body processing */ +- ASN_SET_MKPRESENT((void *)st + specs->pres_offset, edx); ++ ASN_SET_MKPRESENT((char *)st + specs->pres_offset, edx); + ASN_DEBUG("XER/SET phase => %d", ctx->phase); + /* Fall through */ + } +@@ -827,7 +1002,7 @@ + mlen = strlen(elm->name); + + if(elm->flags & ATF_POINTER) { +- memb_ptr = *(void **)((void *)sptr + elm->memb_offset); ++ memb_ptr = *(void **)((char *)sptr + elm->memb_offset); + if(!memb_ptr) { + if(elm->optional) + continue; +@@ -835,7 +1010,7 @@ + _ASN_ENCODE_FAILED; + } + } else { +- memb_ptr = (void *)((void *)sptr + elm->memb_offset); ++ memb_ptr = (void *)((char *)sptr + elm->memb_offset); + } + + if(!xcan) +@@ -877,14 +1052,14 @@ + const void *memb_ptr; + + if(elm->flags & ATF_POINTER) { +- memb_ptr = *(const void * const *)((const void *)sptr + elm->memb_offset); ++ memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset); + if(!memb_ptr) { + if(elm->optional) continue; + /* Print line */ + /* Fall through */ + } + } else { +- memb_ptr = (const void *)((const void *)sptr + elm->memb_offset); ++ memb_ptr = (const void *)((const char *)sptr + elm->memb_offset); + } + + _i_INDENT(1); +@@ -919,11 +1094,11 @@ + asn_TYPE_member_t *elm = &td->elements[edx]; + void *memb_ptr; + if(elm->flags & ATF_POINTER) { +- memb_ptr = *(void **)((void *)ptr + elm->memb_offset); ++ memb_ptr = *(void **)((char *)ptr + elm->memb_offset); + if(memb_ptr) + ASN_STRUCT_FREE(*elm->type, memb_ptr); + } else { +- memb_ptr = (void *)((void *)ptr + elm->memb_offset); ++ memb_ptr = (void *)((char *)ptr + elm->memb_offset); + ASN_STRUCT_FREE_CONTENTS_ONLY(*elm->type, memb_ptr); + } + } +@@ -953,7 +1128,7 @@ + const void *memb_ptr; + + if(elm->flags & ATF_POINTER) { +- memb_ptr = *(const void * const *)((const void *)sptr + elm->memb_offset); ++ memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset); + if(!memb_ptr) { + if(elm->optional) + continue; +@@ -963,7 +1138,7 @@ + return -1; + } + } else { +- memb_ptr = (const void *)((const void *)sptr + elm->memb_offset); ++ memb_ptr = (const void *)((const char *)sptr + elm->memb_offset); + } + + if(elm->memb_constraints) { Index: skeletons/constr_SEQUENCE_OF.c =================================================================== ---- skeletons/constr_SEQUENCE_OF.c (revision 1410) +--- skeletons/constr_SEQUENCE_OF.c (revision 1516) +++ skeletons/constr_SEQUENCE_OF.c (working copy) @@ -164,7 +164,7 @@ if(ct) { int not_in_root = (list->count < ct->lower_bound || list->count > ct->upper_bound); - ASN_DEBUG("lb %ld ub %ld %s", -+ ASN_DEBUG("lb %lld ub %lld %s", ++ ASN_DEBUG("lb %"PRIdMAX" ub %"PRIdMAX" %s", ct->lower_bound, ct->upper_bound, ct->flags & APC_EXTENSIBLE ? "ext" : "fix"); if(ct->flags & APC_EXTENSIBLE) { @@ -1064,7 +1411,7 @@ Index: skeletons/constr_SEQUENCE_OF.c + if(ct) { + int not_in_root = (list->count < ct->lower_bound + || list->count > ct->upper_bound); -+ ASN_DEBUG("lb %lld ub %lld %s", ++ ASN_DEBUG("lb %"PRIdMAX" ub %"PRIdMAX" %s", + ct->lower_bound, ct->upper_bound, + ct->flags & APC_EXTENSIBLE ? "ext" : "fix"); + if(ct->flags & APC_EXTENSIBLE) { @@ -1107,884 +1454,9 @@ Index: skeletons/constr_SEQUENCE_OF.c + + _ASN_ENCODED_OK(er); +} -Index: skeletons/per_encoder.c -=================================================================== ---- skeletons/per_encoder.c (revision 1410) -+++ skeletons/per_encoder.c (working copy) -@@ -4,6 +4,7 @@ - - static asn_enc_rval_t uper_encode_internal(asn_TYPE_descriptor_t *td, asn_per_constraints_t *, void *sptr, asn_app_consume_bytes_f *cb, void *app_key); - -+static asn_enc_rval_t aper_encode_internal(asn_TYPE_descriptor_t *td, asn_per_constraints_t *, void *sptr, asn_app_consume_bytes_f *cb, void *app_key); - asn_enc_rval_t - uper_encode(asn_TYPE_descriptor_t *td, void *sptr, asn_app_consume_bytes_f *cb, void *app_key) { - return uper_encode_internal(td, 0, sptr, cb, app_key); -@@ -41,6 +42,18 @@ - return uper_encode_internal(td, 0, sptr, encode_to_buffer_cb, &key); - } - -+asn_enc_rval_t -+aper_encode_to_buffer(asn_TYPE_descriptor_t *td, 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); -+} -+ - typedef struct enc_dyn_arg { - void *buffer; - size_t length; -@@ -93,6 +106,35 @@ - } - } - -+ssize_t -+aper_encode_to_new_buffer(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, 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 %d bits", er.encoded); -+ return ((er.encoded + 7) >> 3); -+ } -+} -+ - /* - * Internally useful functions. - */ -@@ -115,6 +157,23 @@ - return po->outper(po->tmpspace, buf - po->tmpspace, po->op_key); - } - -+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++; -+ } -+ -+ return po->outper(po->tmpspace, buf - po->tmpspace, po->op_key); -+} -+ - static asn_enc_rval_t - uper_encode_internal(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_app_consume_bytes_f *cb, void *app_key) { - asn_per_outp_t po; -@@ -149,3 +208,37 @@ - return er; - } - -+static asn_enc_rval_t -+aper_encode_internal(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, 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->aper_encoder) -+ _ASN_ENCODE_FAILED; /* PER is not compiled in */ -+ -+ po.buffer = po.tmpspace; -+ po.nboff = 0; -+ po.nbits = 8 * sizeof(po.tmpspace); -+ po.outper = cb; -+ po.op_key = app_key; -+ po.flushed_bytes = 0; -+ -+ er = td->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; -+} -+ -Index: skeletons/constr_CHOICE.h -=================================================================== ---- skeletons/constr_CHOICE.h (revision 1410) -+++ skeletons/constr_CHOICE.h (working copy) -@@ -48,6 +48,8 @@ - xer_type_encoder_f CHOICE_encode_xer; - 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; - - #ifdef __cplusplus -Index: skeletons/constr_SET.h -=================================================================== ---- skeletons/constr_SET.h (revision 1410) -+++ skeletons/constr_SET.h (working copy) -@@ -53,7 +53,9 @@ - xer_type_decoder_f SET_decode_xer; - xer_type_encoder_f SET_encode_xer; - per_type_decoder_f SET_decode_uper; -+per_type_decoder_f SET_decode_aper; - per_type_encoder_f SET_encode_uper; -+per_type_encoder_f SET_encode_aper; - - /*********************** - * Some handy helpers. * -Index: skeletons/REAL.h -=================================================================== ---- skeletons/REAL.h (revision 1410) -+++ skeletons/REAL.h (working copy) -@@ -21,6 +21,8 @@ - xer_type_encoder_f REAL_encode_xer; - 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; - - /*********************************** - * Some handy conversion routines. * -Index: skeletons/ENUMERATED.c -=================================================================== ---- skeletons/ENUMERATED.c (revision 1410) -+++ skeletons/ENUMERATED.c (working copy) -@@ -26,6 +26,8 @@ - INTEGER_encode_xer, - ENUMERATED_decode_uper, /* Unaligned PER decoder */ - ENUMERATED_encode_uper, /* Unaligned PER encoder */ -+ ENUMERATED_decode_aper, /* Aligned PER decoder */ -+ ENUMERATED_encode_aper, /* Aligned PER encoder */ - 0, /* Use generic outmost tag fetcher */ - asn_DEF_ENUMERATED_tags, - sizeof(asn_DEF_ENUMERATED_tags) / sizeof(asn_DEF_ENUMERATED_tags[0]), -@@ -57,6 +59,27 @@ - return rval; - } - -+asn_dec_rval_t -+ENUMERATED_decode_aper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, -+ 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_uper(asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { -@@ -69,3 +92,14 @@ - return NativeEnumerated_encode_uper(td, constraints, &value, po); - } - -+asn_enc_rval_t -+ENUMERATED_encode_aper(asn_TYPE_descriptor_t *td, -+ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { -+ ENUMERATED_t *st = (ENUMERATED_t *)sptr; -+ long value; -+ -+ if(asn_INTEGER2long(st, &value)) -+ _ASN_ENCODE_FAILED; -+ -+ return NativeEnumerated_encode_aper(td, constraints, &value, po); -+} -Index: skeletons/constr_SEQUENCE_OF.h -=================================================================== ---- skeletons/constr_SEQUENCE_OF.h (revision 1410) -+++ skeletons/constr_SEQUENCE_OF.h (working copy) -@@ -22,9 +22,11 @@ - #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_aper SET_OF_decode_aper - 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; - - #ifdef __cplusplus - } -Index: skeletons/per_encoder.h -=================================================================== ---- skeletons/per_encoder.h (revision 1410) -+++ skeletons/per_encoder.h (working copy) -@@ -38,6 +38,12 @@ - size_t buffer_size /* Initial buffer size (max) */ - ); - -+asn_enc_rval_t aper_encode_to_buffer( -+ struct asn_TYPE_descriptor_s *type_descriptor, -+ 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. -@@ -52,6 +58,11 @@ - void **buffer_r /* Buffer allocated and returned */ - ); - -+ssize_t -+aper_encode_to_new_buffer(struct asn_TYPE_descriptor_s *td, -+ asn_per_constraints_t *constraints, -+ void *sptr, -+ void **buffer_r); - /* - * Type of the generic PER encoder function. - */ -Index: skeletons/ENUMERATED.h -=================================================================== ---- skeletons/ENUMERATED.h (revision 1410) -+++ skeletons/ENUMERATED.h (working copy) -@@ -17,6 +17,8 @@ - - 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; - - #ifdef __cplusplus - } -Index: skeletons/NativeInteger.c -=================================================================== ---- skeletons/NativeInteger.c (revision 1410) -+++ skeletons/NativeInteger.c (working copy) -@@ -31,6 +31,8 @@ - NativeInteger_encode_xer, - NativeInteger_decode_uper, /* Unaligned PER decoder */ - NativeInteger_encode_uper, /* Unaligned PER encoder */ -+ NativeInteger_decode_aper, /* Aligned PER decoder */ -+ NativeInteger_encode_aper, /* Aligned PER encoder */ - 0, /* Use generic outmost tag fetcher */ - asn_DEF_NativeInteger_tags, - sizeof(asn_DEF_NativeInteger_tags) / sizeof(asn_DEF_NativeInteger_tags[0]), -@@ -107,7 +109,7 @@ - tmp.size = length; - - if((specs&&specs->field_unsigned) -- ? asn_INTEGER2ulong(&tmp, &l) -+ ? asn_INTEGER2ulong(&tmp, (unsigned long *)&l) - : asn_INTEGER2long(&tmp, &l)) { - rval.code = RC_FAIL; - rval.consumed = 0; -@@ -187,7 +189,7 @@ - if(rval.code == RC_OK) { - long l; - if((specs&&specs->field_unsigned) -- ? asn_INTEGER2ulong(&st, &l) -+ ? asn_INTEGER2ulong(&st, (unsigned long *)&l) - : asn_INTEGER2long(&st, &l)) { - rval.code = RC_FAIL; - rval.consumed = 0; -@@ -255,7 +257,7 @@ - &tmpintptr, pd); - if(rval.code == RC_OK) { - if((specs&&specs->field_unsigned) -- ? asn_INTEGER2ulong(&tmpint, native) -+ ? asn_INTEGER2ulong(&tmpint, (unsigned long *)native) - : asn_INTEGER2long(&tmpint, native)) - rval.code = RC_FAIL; - else -@@ -267,6 +269,42 @@ - return rval; - } - -+asn_dec_rval_t -+NativeInteger_decode_aper(asn_codec_ctx_t *opt_codec_ctx, -+ asn_TYPE_descriptor_t *td, -+ asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { -+ -+ asn_INTEGER_specifics_t *specs=(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_uper(asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { -@@ -291,6 +329,32 @@ - return er; - } - -+asn_enc_rval_t -+NativeInteger_encode_aper( -+ asn_TYPE_descriptor_t *td, -+ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { -+ -+ asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics; -+ asn_enc_rval_t er; -+ long native; -+ INTEGER_t tmpint; -+ -+ if(!sptr) _ASN_ENCODE_FAILED; -+ -+ native = *(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, 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; -+} -+ - /* - * INTEGER specific human-readable output. - */ -Index: skeletons/PrintableString.c -=================================================================== ---- skeletons/PrintableString.c (revision 1410) -+++ skeletons/PrintableString.c (working copy) -@@ -59,6 +59,8 @@ - OCTET_STRING_encode_xer_utf8, - OCTET_STRING_decode_uper, - OCTET_STRING_encode_uper, -+ OCTET_STRING_decode_aper, -+ OCTET_STRING_encode_aper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_PrintableString_tags, - sizeof(asn_DEF_PrintableString_tags) -Index: skeletons/NativeInteger.h -=================================================================== ---- skeletons/NativeInteger.h (revision 1410) -+++ skeletons/NativeInteger.h (working copy) -@@ -29,6 +29,8 @@ - xer_type_encoder_f NativeInteger_encode_xer; - 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; - - #ifdef __cplusplus - } -Index: skeletons/per_decoder.c -=================================================================== ---- skeletons/per_decoder.c (revision 1410) -+++ skeletons/per_decoder.c (working copy) -@@ -37,6 +37,35 @@ - } - - 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(((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 - uper_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; -@@ -91,3 +120,57 @@ - 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->aper_decoder) -+ _ASN_DECODE_FAILED; /* PER is not compiled in */ -+ rval = td->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 %d, counted %d", -+ rval.consumed, pd.moved); -+ assert(rval.consumed == pd.moved); -+ } else { -+ /* PER codec is not a restartable */ -+ rval.consumed = 0; -+ } -+ return rval; -+} -Index: skeletons/VideotexString.c -=================================================================== ---- skeletons/VideotexString.c (revision 1410) -+++ skeletons/VideotexString.c (working copy) -@@ -24,6 +24,8 @@ - OCTET_STRING_encode_xer, - OCTET_STRING_decode_uper, /* Implemented in terms of OCTET STRING */ - OCTET_STRING_encode_uper, -+ OCTET_STRING_decode_aper, -+ OCTET_STRING_encode_aper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_VideotexString_tags, - sizeof(asn_DEF_VideotexString_tags) -Index: skeletons/per_decoder.h -=================================================================== ---- skeletons/per_decoder.h (revision 1410) -+++ skeletons/per_decoder.h (working copy) -@@ -38,8 +38,30 @@ - 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), 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. - */ - typedef asn_dec_rval_t (per_type_decoder_f)(asn_codec_ctx_t *opt_codec_ctx, -Index: skeletons/per_support.c -=================================================================== ---- skeletons/per_support.c (revision 1410) -+++ skeletons/per_support.c (working copy) -@@ -31,6 +31,16 @@ - } - } - -+int32_t -+aper_get_align(asn_per_data_t *pd) { -+ -+ if(pd->nboff & 0x7) { -+ ASN_DEBUG("Aligning %d bits", 8 - (pd->nboff & 0x7)); -+ return per_get_few_bits(pd, 8 - (pd->nboff & 0x7)); -+ } -+ return 0; -+} -+ - /* - * Extract a small number of bits (<= 31) from the specified PER data pointer. - */ -@@ -103,7 +113,7 @@ - - accum &= (((uint32_t)1 << nbits) - 1); - -- ASN_DEBUG(" [PER got %2d<=%2d bits => span %d %+d[%d..%d]:%02x (%d) => 0x%x]", -+ ASN_DEBUG(" [PER got %2d<=%2d bits => span %d %+d[%d..%d]:%02x (%d) => 0x%02x]", - nbits, nleft, - pd->moved, - (((int)pd->buffer) & 0xf), -@@ -122,6 +132,8 @@ - per_get_many_bits(asn_per_data_t *pd, uint8_t *dst, int alright, int nbits) { - int32_t value; - -+ ASN_DEBUG("align: %s, nbits %d", alright ? "YES":"NO", nbits); -+ - if(alright && (nbits & 7)) { - /* Perform right alignment of a first few bits */ - value = per_get_few_bits(pd, nbits & 0x07); -@@ -186,6 +198,36 @@ - return (16384 * value); - } - -+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); -+} -+ - /* - * Get the normally small length "n". - * This procedure used to decode length of extensions bit-maps -@@ -210,6 +252,25 @@ - } - } - -+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=%d", 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 */ -+ } -+} -+ - /* - * Get the normally small non-negative whole number. - * X.691, #10.6 -@@ -236,6 +297,40 @@ - return value; - } - -+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) { -+ if (range < 0) return -1; -+ /* 1 -> 8 bits */ -+ int i; -+ 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; -+ return -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; -+} -+ - /* - * Put the normally small non-negative whole number. - * X.691, #10.6 -@@ -244,6 +339,7 @@ - uper_put_nsnnwn(asn_per_outp_t *po, int n) { - int bytes; - -+ ASN_DEBUG("uper put nsnnwn n %d", n); - if(n <= 63) { - if(n < 0) return -1; - return per_put_few_bits(po, n, 7); -@@ -262,7 +358,62 @@ - return per_put_few_bits(po, n, 8 * bytes); - } - -+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); -+} -+ -+int aper_put_align(asn_per_outp_t *po) { -+ -+ if(po->nboff & 0x7) { -+ ASN_DEBUG("Aligning %d bits", 8 - (po->nboff & 0x7)); -+ if(per_put_few_bits(po, 0x00, (8 - (po->nboff & 0x7)))) -+ return -1; -+ } -+ return 0; -+} -+ - /* - * Put a small number of bits (<= 31). - */ -@@ -386,6 +537,8 @@ - ssize_t - uper_put_length(asn_per_outp_t *po, size_t length) { - -+ ASN_DEBUG("UPER put length %d", length); -+ - if(length <= 127) /* #10.9.3.6 */ - return per_put_few_bits(po, length, 8) - ? -1 : (ssize_t)length; -@@ -400,7 +553,34 @@ - ? -1 : (ssize_t)(length << 14); - } - -+ssize_t -+aper_put_length(asn_per_outp_t *po, int range, size_t length) { - -+ ASN_DEBUG("APER put length %d 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); -+} -+ -+ - /* - * Put the normally small length "n" into the stream. - * This procedure used to encode length of extensions bit-maps -@@ -423,3 +603,19 @@ - return 0; - } - -+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; -+} -Index: skeletons/RELATIVE-OID.c -=================================================================== ---- skeletons/RELATIVE-OID.c (revision 1410) -+++ skeletons/RELATIVE-OID.c (working copy) -@@ -28,6 +28,8 @@ - RELATIVE_OID_encode_xer, - OCTET_STRING_decode_uper, - OCTET_STRING_encode_uper, -+ OCTET_STRING_decode_aper, -+ OCTET_STRING_encode_aper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_RELATIVE_OID_tags, - sizeof(asn_DEF_RELATIVE_OID_tags) -Index: skeletons/VisibleString.c -=================================================================== ---- skeletons/VisibleString.c (revision 1410) -+++ skeletons/VisibleString.c (working copy) -@@ -29,6 +29,8 @@ - OCTET_STRING_encode_xer_utf8, - OCTET_STRING_decode_uper, - OCTET_STRING_encode_uper, -+ OCTET_STRING_decode_aper, -+ OCTET_STRING_encode_aper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_VisibleString_tags, - sizeof(asn_DEF_VisibleString_tags) Index: skeletons/per_support.h =================================================================== ---- skeletons/per_support.h (revision 1410) +--- skeletons/per_support.h (revision 1516) +++ skeletons/per_support.h (working copy) @@ -24,8 +24,8 @@ } flags; @@ -2068,114 +1540,403 @@ Index: skeletons/per_support.h #ifdef __cplusplus } #endif -Index: skeletons/BIT_STRING.c +Index: skeletons/constr_SET.h =================================================================== ---- skeletons/BIT_STRING.c (revision 1410) -+++ skeletons/BIT_STRING.c (working copy) -@@ -29,6 +29,8 @@ - BIT_STRING_encode_xer, - 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 */ +--- skeletons/constr_SET.h (revision 1516) ++++ skeletons/constr_SET.h (working copy) +@@ -53,7 +53,9 @@ + xer_type_decoder_f SET_decode_xer; + xer_type_encoder_f SET_encode_xer; + per_type_decoder_f SET_decode_uper; ++per_type_decoder_f SET_decode_aper; + per_type_encoder_f SET_encode_uper; ++per_type_encoder_f SET_encode_aper; + + /*********************** + * Some handy helpers. * +Index: skeletons/constr_SEQUENCE_OF.h +=================================================================== +--- skeletons/constr_SEQUENCE_OF.h (revision 1516) ++++ skeletons/constr_SEQUENCE_OF.h (working copy) +@@ -22,9 +22,11 @@ + #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_aper SET_OF_decode_aper + 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; + + #ifdef __cplusplus + } +Index: skeletons/ENUMERATED.c +=================================================================== +--- skeletons/ENUMERATED.c (revision 1516) ++++ skeletons/ENUMERATED.c (working copy) +@@ -26,6 +26,8 @@ + INTEGER_encode_xer, + ENUMERATED_decode_uper, /* Unaligned PER decoder */ + ENUMERATED_encode_uper, /* Unaligned PER encoder */ ++ ENUMERATED_decode_aper, /* Aligned PER decoder */ ++ ENUMERATED_encode_aper, /* Aligned PER encoder */ 0, /* Use generic outmost tag fetcher */ - asn_DEF_BIT_STRING_tags, - sizeof(asn_DEF_BIT_STRING_tags) -Index: skeletons/GraphicString.c + asn_DEF_ENUMERATED_tags, + sizeof(asn_DEF_ENUMERATED_tags) / sizeof(asn_DEF_ENUMERATED_tags[0]), +@@ -57,6 +59,27 @@ + return rval; + } + ++asn_dec_rval_t ++ENUMERATED_decode_aper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, ++ 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_uper(asn_TYPE_descriptor_t *td, + asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { +@@ -69,3 +92,14 @@ + return NativeEnumerated_encode_uper(td, constraints, &value, po); + } + ++asn_enc_rval_t ++ENUMERATED_encode_aper(asn_TYPE_descriptor_t *td, ++ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { ++ ENUMERATED_t *st = (ENUMERATED_t *)sptr; ++ long value; ++ ++ if(asn_INTEGER2long(st, &value)) ++ _ASN_ENCODE_FAILED; ++ ++ return NativeEnumerated_encode_aper(td, constraints, &value, po); ++} +Index: skeletons/ENUMERATED.h =================================================================== ---- skeletons/GraphicString.c (revision 1410) -+++ skeletons/GraphicString.c (working copy) +--- skeletons/ENUMERATED.h (revision 1516) ++++ skeletons/ENUMERATED.h (working copy) +@@ -17,6 +17,8 @@ + + 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; + + #ifdef __cplusplus + } +Index: skeletons/NativeEnumerated.c +=================================================================== +--- skeletons/NativeEnumerated.c (revision 1516) ++++ skeletons/NativeEnumerated.c (working copy) +@@ -30,6 +30,8 @@ + NativeEnumerated_encode_xer, + NativeEnumerated_decode_uper, + NativeEnumerated_encode_uper, ++ NativeEnumerated_decode_aper, ++ NativeEnumerated_encode_aper, + 0, /* Use generic outmost tag fetcher */ + asn_DEF_NativeEnumerated_tags, + sizeof(asn_DEF_NativeEnumerated_tags) / sizeof(asn_DEF_NativeEnumerated_tags[0]), +@@ -42,17 +44,17 @@ + + asn_enc_rval_t + NativeEnumerated_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, +- int ilevel, enum xer_encoder_flags_e flags, +- asn_app_consume_bytes_f *cb, void *app_key) { ++ int ilevel, enum xer_encoder_flags_e flags, ++ asn_app_consume_bytes_f *cb, void *app_key) { + asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics; +- asn_enc_rval_t er; +- const long *native = (const long *)sptr; ++ asn_enc_rval_t er; ++ const long *native = (const long *)sptr; + const asn_INTEGER_enum_map_t *el; + +- (void)ilevel; +- (void)flags; ++ (void)ilevel; ++ (void)flags; + +- if(!native) _ASN_ENCODE_FAILED; ++ if(!native) _ASN_ENCODE_FAILED; + + el = INTEGER_map_value2enum(specs, *native); + if(el) { +@@ -125,6 +127,66 @@ + return rval; + } + ++asn_dec_rval_t ++NativeEnumerated_decode_aper(asn_codec_ctx_t *opt_codec_ctx, ++ asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, ++ void **sptr, asn_per_data_t *pd) { ++ asn_INTEGER_specifics_t *specs = (asn_INTEGER_specifics_t *)td->specifics; ++ asn_dec_rval_t rval = { RC_OK, 0 }; ++ long *native = (long *)*sptr; ++ asn_per_constraint_t *ct; ++ long value; ++ int freeme = 0; ++ ++ (void)opt_codec_ctx; ++ ++ if(constraints) ct = &constraints->value; ++ else if(td->per_constraints) ct = &td->per_constraints->value; ++ else _ASN_DECODE_FAILED; /* Mandatory! */ ++ if(!specs) _ASN_DECODE_FAILED; ++ ++ if(!native) { ++ native = (long *)(*sptr = CALLOC(1, sizeof(*native))); ++ freeme = 1; ++ 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; ++ } ++ ++ 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); ++ ++ if (freeme) ++ free(native); ++ ++ return rval; ++} ++ + static int + NativeEnumerated__compar_value2enum(const void *ap, const void *bp) { + const asn_INTEGER_enum_map_t *a = ap; +@@ -205,3 +267,71 @@ + _ASN_ENCODED_OK(er); + } + ++asn_enc_rval_t ++NativeEnumerated_encode_aper(asn_TYPE_descriptor_t *td, ++ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { ++ asn_INTEGER_specifics_t *specs = (asn_INTEGER_specifics_t *)td->specifics; ++ asn_enc_rval_t er; ++ long native, value; ++ 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->per_constraints) ct = &td->per_constraints->value; ++ else _ASN_ENCODE_FAILED; /* Mandatory! */ ++ ++ ASN_DEBUG("Encoding %s as NativeEnumerated", td->name); ++ ++ er.encoded = 0; ++ ++ native = *(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); ++} +Index: skeletons/GeneralString.c +=================================================================== +--- skeletons/GeneralString.c (revision 1516) ++++ skeletons/GeneralString.c (working copy) @@ -24,6 +24,8 @@ - OCTET_STRING_encode_xer, /* Can't expect it to be ASCII/UTF8 */ + OCTET_STRING_encode_xer, OCTET_STRING_decode_uper, /* Implemented in terms of OCTET STRING */ OCTET_STRING_encode_uper, + OCTET_STRING_decode_aper, + OCTET_STRING_encode_aper, 0, /* Use generic outmost tag fetcher */ - asn_DEF_GraphicString_tags, - sizeof(asn_DEF_GraphicString_tags) -Index: skeletons/ObjectDescriptor.c + asn_DEF_GeneralString_tags, + sizeof(asn_DEF_GeneralString_tags) +Index: skeletons/IA5String.c =================================================================== ---- skeletons/ObjectDescriptor.c (revision 1410) -+++ skeletons/ObjectDescriptor.c (working copy) -@@ -24,6 +24,8 @@ +--- skeletons/IA5String.c (revision 1516) ++++ skeletons/IA5String.c (working copy) +@@ -29,6 +29,8 @@ OCTET_STRING_encode_xer_utf8, OCTET_STRING_decode_uper, OCTET_STRING_encode_uper, + OCTET_STRING_decode_aper, + OCTET_STRING_encode_aper, 0, /* Use generic outmost tag fetcher */ - asn_DEF_ObjectDescriptor_tags, - sizeof(asn_DEF_ObjectDescriptor_tags) -Index: skeletons/NULL.c + asn_DEF_IA5String_tags, + sizeof(asn_DEF_IA5String_tags) +Index: skeletons/NativeEnumerated.h =================================================================== ---- skeletons/NULL.c (revision 1410) -+++ skeletons/NULL.c (working copy) -@@ -25,6 +25,8 @@ - NULL_encode_xer, - NULL_decode_uper, /* Unaligned PER decoder */ - NULL_encode_uper, /* Unaligned PER encoder */ -+ NULL_decode_aper, /* Aligned PER decoder */ -+ NULL_encode_aper, /* Aligned PER encoder */ +--- skeletons/NativeEnumerated.h (revision 1516) ++++ skeletons/NativeEnumerated.h (working copy) +@@ -24,6 +24,8 @@ + xer_type_encoder_f NativeEnumerated_encode_xer; + 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; + + #ifdef __cplusplus + } +Index: skeletons/OBJECT_IDENTIFIER.c +=================================================================== +--- skeletons/OBJECT_IDENTIFIER.c (revision 1516) ++++ skeletons/OBJECT_IDENTIFIER.c (working copy) +@@ -27,6 +27,8 @@ + OBJECT_IDENTIFIER_encode_xer, + OCTET_STRING_decode_uper, + OCTET_STRING_encode_uper, ++ OCTET_STRING_decode_aper, ++ OCTET_STRING_encode_aper, 0, /* Use generic outmost tag fetcher */ - asn_DEF_NULL_tags, - sizeof(asn_DEF_NULL_tags) / sizeof(asn_DEF_NULL_tags[0]), -@@ -132,6 +134,34 @@ - return rv; + asn_DEF_OBJECT_IDENTIFIER_tags, + sizeof(asn_DEF_OBJECT_IDENTIFIER_tags) +Index: skeletons/per_opentype.c +=================================================================== +--- skeletons/per_opentype.c (revision 1516) ++++ skeletons/per_opentype.c (working copy) +@@ -53,6 +53,35 @@ + return 0; } -+asn_dec_rval_t -+NULL_decode_aper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, -+ 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_uper(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, - void *sptr, asn_per_outp_t *po) { -@@ -145,3 +175,17 @@ - er.encoded = 0; - _ASN_ENCODED_OK(er); - } -+ -+asn_enc_rval_t -+NULL_encode_aper(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, -+ void *sptr, asn_per_outp_t *po) { -+ asn_enc_rval_t er; -+ -+ (void)td; -+ (void)constraints; -+ (void)sptr; -+ (void)po; ++int ++aper_open_type_put(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { ++ void *buf; ++ void *bptr; ++ ssize_t size; ++ size_t toGo; + -+ er.encoded = 0; -+ _ASN_ENCODED_OK(er); ++ 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, (long)size); ++ ++ return 0; +} ++ + static asn_dec_rval_t + uper_open_type_get_simple(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td, + asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { +Index: skeletons/VideotexString.c +=================================================================== +--- skeletons/VideotexString.c (revision 1516) ++++ skeletons/VideotexString.c (working copy) +@@ -24,6 +24,8 @@ + OCTET_STRING_encode_xer, + OCTET_STRING_decode_uper, /* Implemented in terms of OCTET STRING */ + OCTET_STRING_encode_uper, ++ OCTET_STRING_decode_aper, ++ OCTET_STRING_encode_aper, + 0, /* Use generic outmost tag fetcher */ + asn_DEF_VideotexString_tags, + sizeof(asn_DEF_VideotexString_tags) +Index: skeletons/per_opentype.h +=================================================================== +--- skeletons/per_opentype.h (revision 1516) ++++ skeletons/per_opentype.h (working copy) +@@ -15,6 +15,8 @@ + + int uper_open_type_put(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po); + ++int aper_open_type_put(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po); ++ + #ifdef __cplusplus + } + #endif Index: skeletons/BOOLEAN.c =================================================================== ---- skeletons/BOOLEAN.c (revision 1410) +--- skeletons/BOOLEAN.c (revision 1516) +++ skeletons/BOOLEAN.c (working copy) @@ -24,6 +24,8 @@ BOOLEAN_encode_xer, @@ -2186,7 +1947,7 @@ Index: skeletons/BOOLEAN.c 0, /* Use generic outmost tag fetcher */ asn_DEF_BOOLEAN_tags, sizeof(asn_DEF_BOOLEAN_tags) / sizeof(asn_DEF_BOOLEAN_tags[0]), -@@ -267,7 +269,36 @@ +@@ -264,7 +266,36 @@ return rv; } @@ -2223,7 +1984,7 @@ Index: skeletons/BOOLEAN.c asn_enc_rval_t BOOLEAN_encode_uper(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { -@@ -282,3 +313,18 @@ +@@ -280,3 +311,18 @@ _ASN_ENCODED_OK(er); } @@ -2242,22 +2003,445 @@ Index: skeletons/BOOLEAN.c + + _ASN_ENCODED_OK(er); +} -Index: skeletons/NULL.h +Index: skeletons/ISO646String.c =================================================================== ---- skeletons/NULL.h (revision 1410) -+++ skeletons/NULL.h (working copy) -@@ -25,6 +25,8 @@ - xer_type_encoder_f NULL_encode_xer; - 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; +--- skeletons/ISO646String.c (revision 1516) ++++ skeletons/ISO646String.c (working copy) +@@ -29,6 +29,8 @@ + OCTET_STRING_encode_xer_utf8, + OCTET_STRING_decode_uper, + OCTET_STRING_encode_uper, ++ OCTET_STRING_decode_aper, ++ OCTET_STRING_encode_aper, + 0, /* Use generic outmost tag fetcher */ + asn_DEF_ISO646String_tags, + sizeof(asn_DEF_ISO646String_tags) +Index: skeletons/constr_CHOICE.c +=================================================================== +--- skeletons/constr_CHOICE.c (revision 1516) ++++ skeletons/constr_CHOICE.c (working copy) +@@ -34,7 +34,7 @@ + #undef ADVANCE + #define ADVANCE(num_bytes) do { \ + size_t num = num_bytes; \ +- ptr = ((const void *)ptr) + num;\ ++ ptr = ((const char *)ptr) + num;\ + size -= num; \ + if(ctx->left >= 0) \ + ctx->left -= num; \ +@@ -133,7 +133,7 @@ + /* + * Restore parsing context. + */ +- ctx = (asn_struct_ctx_t *)((void *)st + specs->ctx_offset); ++ ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset); + + /* + * Start to parse where left previously +@@ -211,7 +211,7 @@ - #ifdef __cplusplus + skip = ber_skip_length(opt_codec_ctx, + BER_TLV_CONSTRUCTED(ptr), +- (const void *)ptr + tag_len, ++ (const char *)ptr + tag_len, + LEFT - tag_len); + + switch(skip) { +@@ -244,7 +244,7 @@ + */ + if(elm->flags & ATF_POINTER) { + /* Member is a pointer to another structure */ +- memb_ptr2 = (void **)((void *)st + elm->memb_offset); ++ memb_ptr2 = (void **)((char *)st + elm->memb_offset); + } else { + /* + * A pointer to a pointer +@@ -390,7 +390,7 @@ + */ + elm = &td->elements[present-1]; + if(elm->flags & ATF_POINTER) { +- memb_ptr = *(void **)((void *)sptr + elm->memb_offset); ++ memb_ptr = *(void **)((char *)sptr + elm->memb_offset); + if(memb_ptr == 0) { + if(elm->optional) { + erval.encoded = 0; +@@ -400,7 +400,7 @@ + _ASN_ENCODE_FAILED; + } + } else { +- memb_ptr = (void *)((void *)sptr + elm->memb_offset); ++ memb_ptr = (void *)((char *)sptr + elm->memb_offset); + } + + /* +@@ -463,10 +463,10 @@ + + if(elm->flags & ATF_POINTER) { + memb_ptr = *(const void * const *) +- ((const void *)ptr + elm->memb_offset); ++ ((const char *)ptr + elm->memb_offset); + } else { + memb_ptr = (const void *) +- ((const void *)ptr + elm->memb_offset); ++ ((const char *)ptr + elm->memb_offset); + } + + return asn_TYPE_outmost_tag(elm->type, memb_ptr, +@@ -498,7 +498,7 @@ + const void *memb_ptr; + + if(elm->flags & ATF_POINTER) { +- memb_ptr = *(const void * const *)((const void *)sptr + elm->memb_offset); ++ memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset); + if(!memb_ptr) { + if(elm->optional) + return 0; +@@ -508,7 +508,7 @@ + return -1; + } + } else { +- memb_ptr = (const void *)((const void *)sptr + elm->memb_offset); ++ memb_ptr = (const void *)((const char *)sptr + elm->memb_offset); + } + + if(elm->memb_constraints) { +@@ -535,7 +535,7 @@ + #undef XER_ADVANCE + #define XER_ADVANCE(num_bytes) do { \ + size_t num = num_bytes; \ +- buf_ptr = ((const void *)buf_ptr) + num;\ ++ buf_ptr = ((const char *)buf_ptr) + num;\ + size -= num; \ + consumed_myself += num; \ + } while(0) +@@ -574,7 +574,7 @@ + /* + * Restore parsing context. + */ +- ctx = (asn_struct_ctx_t *)((void *)st + specs->ctx_offset); ++ ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset); + if(ctx->phase == 0 && !*xml_tag) + ctx->phase = 1; /* Skip the outer tag checking phase */ + +@@ -605,7 +605,7 @@ + + if(elm->flags & ATF_POINTER) { + /* Member is a pointer to another structure */ +- memb_ptr2 = (void **)((void *)st ++ memb_ptr2 = (void **)((char *)st + + elm->memb_offset); + } else { + memb_ptr = (char *)st + elm->memb_offset; +@@ -797,10 +797,10 @@ + unsigned int mlen = strlen(mname); + + if(elm->flags & ATF_POINTER) { +- memb_ptr = *(void **)((void *)sptr + elm->memb_offset); ++ memb_ptr = *(void **)((char *)sptr + elm->memb_offset); + if(!memb_ptr) _ASN_ENCODE_FAILED; + } else { +- memb_ptr = (void *)((void *)sptr + elm->memb_offset); ++ memb_ptr = (void *)((char *)sptr + elm->memb_offset); + } + + er.encoded = 0; +@@ -884,7 +884,7 @@ + elm = &td->elements[value]; + if(elm->flags & ATF_POINTER) { + /* Member is a pointer to another structure */ +- memb_ptr2 = (void **)((void *)st + elm->memb_offset); ++ memb_ptr2 = (void **)((char *)st + elm->memb_offset); + } else { + memb_ptr = (char *)st + elm->memb_offset; + memb_ptr2 = &memb_ptr; +@@ -904,7 +904,88 @@ + elm->name, td->name, rv.code); + return rv; } +- ++ ++asn_dec_rval_t ++CHOICE_decode_aper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, ++ asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { ++ asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics; ++ asn_dec_rval_t rv; ++ 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->per_constraints) ct = &td->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(value >= td->elements_count) ++ _ASN_DECODE_FAILED; ++ } ++ ++ /* Adjust if canonical order is different from natural order */ ++ if(specs->canonical_order) ++ value = specs->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->aper_decoder(opt_codec_ctx, elm->type, ++ elm->per_constraints, memb_ptr2, pd); ++ } else { ++ rv = uper_open_type_get(opt_codec_ctx, elm->type, ++ elm->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_uper(asn_TYPE_descriptor_t *td, + asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { +@@ -917,7 +998,7 @@ + + if(!sptr) _ASN_ENCODE_FAILED; + +- ASN_DEBUG("Encoding %s as CHOICE", td->name); ++ ASN_DEBUG("Encoding %s as CHOICE using UPER", td->name); + + if(constraints) ct = &constraints->value; + else if(td->per_constraints) ct = &td->per_constraints->value; +@@ -962,7 +1043,7 @@ + elm = &td->elements[present]; + if(elm->flags & ATF_POINTER) { + /* Member is a pointer to another structure */ +- memb_ptr = *(void **)((void *)sptr + elm->memb_offset); ++ memb_ptr = *(void **)((char *)sptr + elm->memb_offset); + if(!memb_ptr) _ASN_ENCODE_FAILED; + } else { + memb_ptr = (char *)sptr + elm->memb_offset; +@@ -987,8 +1068,88 @@ + _ASN_ENCODED_OK(rval); + } + } +- + ++asn_enc_rval_t ++CHOICE_encode_aper(asn_TYPE_descriptor_t *td, ++ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { ++ asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics; ++ asn_TYPE_member_t *elm; /* CHOICE's element */ ++ asn_per_constraint_t *ct; ++ 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->per_constraints) ct = &td->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 || present > td->elements_count) ++ _ASN_ENCODE_FAILED; ++ else ++ present--; ++ ++ /* Adjust if canonical order is different from natural order */ ++ if(specs->canonical_order) ++ present = specs->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 = *(void **)((char *)sptr + elm->memb_offset); ++ if(!memb_ptr) _ASN_ENCODE_FAILED; ++ } else { ++ memb_ptr = (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->aper_encoder(elm->type, elm->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->per_constraints, ++ memb_ptr, po)) ++ _ASN_ENCODE_FAILED; ++ rval.encoded = 0; ++ _ASN_ENCODED_OK(rval); ++ } ++} ++ + int + CHOICE_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, + asn_app_consume_bytes_f *cb, void *app_key) { +@@ -1010,10 +1171,10 @@ + const void *memb_ptr; + + if(elm->flags & ATF_POINTER) { +- memb_ptr = *(const void * const *)((const void *)sptr + elm->memb_offset); ++ memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset); + if(!memb_ptr) return (cb("", 8, app_key) < 0) ? -1 : 0; + } else { +- memb_ptr = (const void *)((const void *)sptr + elm->memb_offset); ++ memb_ptr = (const void *)((const char *)sptr + elm->memb_offset); + } + + /* Print member's name and stuff */ +@@ -1053,11 +1214,11 @@ + void *memb_ptr; + + if(elm->flags & ATF_POINTER) { +- memb_ptr = *(void **)((void *)ptr + elm->memb_offset); ++ memb_ptr = *(void **)((char *)ptr + elm->memb_offset); + if(memb_ptr) + ASN_STRUCT_FREE(*elm->type, memb_ptr); + } else { +- memb_ptr = (void *)((void *)ptr + elm->memb_offset); ++ memb_ptr = (void *)((char *)ptr + elm->memb_offset); + ASN_STRUCT_FREE_CONTENTS_ONLY(*elm->type, memb_ptr); + } + } +@@ -1082,7 +1243,7 @@ + const void *present_ptr; + int present; + +- present_ptr = ((const void *)struct_ptr) + pres_offset; ++ present_ptr = ((const char *)struct_ptr) + pres_offset; + + switch(pres_size) { + case sizeof(int): present = *(const int *)present_ptr; break; +@@ -1100,7 +1261,7 @@ + static void + _set_present_idx(void *struct_ptr, int pres_offset, int pres_size, int present) { + void *present_ptr; +- present_ptr = ((void *)struct_ptr) + pres_offset; ++ present_ptr = ((char *)struct_ptr) + pres_offset; + + switch(pres_size) { + case sizeof(int): *(int *)present_ptr = present; break; +Index: skeletons/asn_internal.h +=================================================================== +--- skeletons/asn_internal.h (revision 1516) ++++ skeletons/asn_internal.h (working copy) +@@ -20,7 +20,7 @@ + #endif + + /* Environment version might be used to avoid running with the old library */ +-#define ASN1C_ENVIRONMENT_VERSION 923 /* Compile-time version */ ++#define ASN1C_ENVIRONMENT_VERSION 924 /* Compile-time version */ + int get_asn1c_environment_version(void); /* Run-time version */ + + #define CALLOC(nmemb, size) calloc(nmemb, size) +@@ -48,18 +48,22 @@ + #define ASN_DEBUG_INDENT_ADD(i) do { asn_debug_indent += i; } while(0) + #endif /* ASN_THREAD_SAFE */ + #define ASN_DEBUG(fmt, args...) do { \ +- int adi = asn_debug_indent; \ +- while(adi--) fprintf(stderr, " "); \ +- fprintf(stderr, fmt, ##args); \ +- fprintf(stderr, " (%s:%d)\n", \ +- __FILE__, __LINE__); \ +- } while(0) ++ int adi = asn_debug_indent; \ ++ while(adi--) fprintf(stderr, " "); \ ++ fprintf(stderr, fmt, ##args); \ ++ fprintf(stderr, " (%s:%d)\n", \ ++ __FILE__, __LINE__); \ ++} while(0) + #else /* !__GNUC__ */ + void ASN_DEBUG_f(const char *fmt, ...); + #define ASN_DEBUG ASN_DEBUG_f + #endif /* __GNUC__ */ + #else /* EMIT_ASN_DEBUG != 1 */ ++# ifdef EMIT_ASN_DEBUG_EXTERN ++extern inline void ASN_DEBUG(const char *fmt, ...); ++# else + static inline void ASN_DEBUG(const char *fmt, ...) { (void)fmt; } ++# endif + #endif /* EMIT_ASN_DEBUG */ + #endif /* ASN_DEBUG */ + Index: skeletons/BOOLEAN.h =================================================================== ---- skeletons/BOOLEAN.h (revision 1410) +--- skeletons/BOOLEAN.h (revision 1516) +++ skeletons/BOOLEAN.h (working copy) @@ -28,6 +28,8 @@ xer_type_encoder_f BOOLEAN_encode_xer; @@ -2268,159 +2452,47 @@ Index: skeletons/BOOLEAN.h #ifdef __cplusplus } -Index: skeletons/NumericString.c +Index: skeletons/constr_CHOICE.h =================================================================== ---- skeletons/NumericString.c (revision 1410) -+++ skeletons/NumericString.c (working copy) -@@ -49,6 +49,8 @@ - OCTET_STRING_encode_xer_utf8, - OCTET_STRING_decode_uper, - OCTET_STRING_encode_uper, -+ OCTET_STRING_decode_aper, -+ OCTET_STRING_encode_aper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_NumericString_tags, - sizeof(asn_DEF_NumericString_tags) -Index: skeletons/NativeReal.c -=================================================================== ---- skeletons/NativeReal.c (revision 1410) -+++ skeletons/NativeReal.c (working copy) -@@ -32,6 +32,8 @@ - NativeReal_encode_xer, - NativeReal_decode_uper, - NativeReal_encode_uper, -+ NativeReal_decode_aper, -+ NativeReal_encode_aper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_NativeReal_tags, - sizeof(asn_DEF_NativeReal_tags) / sizeof(asn_DEF_NativeReal_tags[0]), -@@ -199,6 +201,43 @@ - return rval; - } +--- skeletons/constr_CHOICE.h (revision 1516) ++++ skeletons/constr_CHOICE.h (working copy) +@@ -48,6 +48,8 @@ + xer_type_encoder_f CHOICE_encode_xer; + 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_dec_rval_t -+NativeReal_decode_aper(asn_codec_ctx_t *opt_codec_ctx, -+ asn_TYPE_descriptor_t *td, 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; -+} -+ - /* - * Encode the NativeReal using the OCTET STRING PER encoder. - */ -@@ -228,6 +267,32 @@ - return erval; - } - -+asn_enc_rval_t -+NativeReal_encode_aper(asn_TYPE_descriptor_t *td, -+ asn_per_constraints_t *constraints, 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; -+} -+ - /* - * Decode the chunk of XML text encoding REAL. - */ + #ifdef __cplusplus Index: skeletons/INTEGER.c =================================================================== ---- skeletons/INTEGER.c (revision 1410) +--- skeletons/INTEGER.c (revision 1516) +++ skeletons/INTEGER.c (working copy) -@@ -26,6 +26,8 @@ - INTEGER_encode_xer, +@@ -27,9 +27,13 @@ + #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, + INTEGER_encode_aper, + #endif /* ASN_DISABLE_PER_SUPPORT */ 0, /* Use generic outmost tag fetcher */ asn_DEF_INTEGER_tags, - sizeof(asn_DEF_INTEGER_tags) / sizeof(asn_DEF_INTEGER_tags[0]), -@@ -395,7 +397,7 @@ - break; - } - -- { -+ { - long new_value = value * 10; - - if(new_value / 10 != value) -@@ -415,7 +417,7 @@ - return XPBD_DECODER_LIMIT; - } - } -- } -+ } - continue; - case 0x3c: /* '<' */ - if(state == ST_SKIPSPACE) { -@@ -424,7 +426,7 @@ - (asn_INTEGER_specifics_t *) - td->specifics, lstart, lstop); - if(el) { -- ASN_DEBUG("Found \"%s\" => %ld", -+ ASN_DEBUG("Found \"%s\" => %lld", - el->enum_name, el->nat_value); - state = ST_DIGITS; - value = el->nat_value; -@@ -611,7 +613,7 @@ +@@ -612,7 +616,7 @@ value = per_get_few_bits(pd, ct->range_bits); if(value < 0) _ASN_DECODE_STARVED; } - ASN_DEBUG("Got value %ld + low %ld", -+ ASN_DEBUG("Got value %ld + low %lld", ++ ASN_DEBUG("Got value %ld + low %"PRIdMAX, value, ct->lower_bound); value += ct->lower_bound; if((specs && specs->field_unsigned) -@@ -659,6 +661,158 @@ +@@ -660,6 +664,158 @@ return rval; } @@ -2579,34 +2651,34 @@ Index: skeletons/INTEGER.c asn_enc_rval_t INTEGER_encode_uper(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { -@@ -692,7 +846,7 @@ +@@ -693,7 +849,7 @@ || uval > (unsigned long)ct->upper_bound) inext = 1; } - ASN_DEBUG("Value %lu (%02x/%d) lb %lu ub %lu %s", -+ ASN_DEBUG("Value %lu (%02x/%d) lb %llu ub %llu %s", ++ ASN_DEBUG("Value %lu (%02x/%d) lb %"PRIuMAX" ub %"PRIuMAX" %s", uval, st->buf[0], st->size, ct->lower_bound, ct->upper_bound, inext ? "ext" : "fix"); -@@ -709,7 +863,7 @@ +@@ -710,7 +866,7 @@ || value > ct->upper_bound) inext = 1; } - ASN_DEBUG("Value %ld (%02x/%d) lb %ld ub %ld %s", -+ ASN_DEBUG("Value %ld (%02x/%d) lb %lld ub %lld %s", ++ ASN_DEBUG("Value %ld (%02x/%d) lb %"PRIdMAX" ub %"PRIdMAX" %s", value, st->buf[0], st->size, ct->lower_bound, ct->upper_bound, inext ? "ext" : "fix"); -@@ -744,7 +898,7 @@ +@@ -745,7 +901,7 @@ } if(ct && ct->lower_bound) { - ASN_DEBUG("Adjust lower bound to %ld", ct->lower_bound); -+ ASN_DEBUG("Adjust lower bound to %lld", ct->lower_bound); ++ ASN_DEBUG("Adjust lower bound to %"PRIdMAX"\n", ct->lower_bound); /* TODO: adjust lower bound */ _ASN_ENCODE_FAILED; } -@@ -761,6 +915,145 @@ +@@ -762,6 +918,153 @@ _ASN_ENCODED_OK(er); } @@ -2636,11 +2708,11 @@ Index: skeletons/INTEGER.c + _ASN_ENCODE_FAILED; + /* Check proper range */ + if(ct->flags & APC_SEMI_CONSTRAINED) { -+ if(uval < (unsigned long long)ct->lower_bound) ++ if(uval < ct->lower_bound) + inext = 1; + } else if(ct->range_bits >= 0) { -+ if(uval < (unsigned long long)ct->lower_bound -+ || uval > (unsigned long long)ct->upper_bound) ++ if(uval < ct->lower_bound ++ || uval > ct->upper_bound) + inext = 1; + } + ASN_DEBUG("Value %llu (%02x/%d) lb %llu ub %llu %s", @@ -2711,11 +2783,19 @@ Index: skeletons/INTEGER.c + break; + } + -+ ASN_DEBUG("Putting n - lb (%lld) with range %d bytes (real size - lb (1)) %d in %d bits", -+ v, max_range_bytes, st->size - 1, i); ++ for(j = sizeof(int64_t) - 1; j != 0; j--) { ++ uint8_t val; ++ val = v >> (j * 8); ++ if (val != 0) { ++ break; ++ } ++ } ++ ++ ASN_DEBUG("Putting n - lb (%"PRIdMAX") with range %d bytes (real size - lb (1)) %d in %d bits", ++ v, max_range_bytes, j, i); + + /* Putting length in the minimum number of bits ex: 5 = 3bits */ -+ if (per_put_few_bits(po, st->size - 1, i)) ++ if (per_put_few_bits(po, j, i)) + _ASN_ENCODE_FAILED; + + // Consume the bits to align on octet @@ -2723,8 +2803,8 @@ Index: skeletons/INTEGER.c + _ASN_ENCODE_FAILED; + + /* Put the value */ -+ for (i = 0; i < st->size; i++) { -+ if(per_put_few_bits(po, (v >> (8 * (st->size - i - 1))) & 0xff, 8)) ++ for (i = 0; i <= j; i++) { ++ if(per_put_few_bits(po, (v >> (8 * (j - i))) & 0xff, 8)) + _ASN_ENCODE_FAILED; + } + } @@ -2732,7 +2812,7 @@ Index: skeletons/INTEGER.c + } + + if(ct && ct->lower_bound) { -+ ASN_DEBUG("Adjust lower bound to %lld", ct->lower_bound); ++ ASN_DEBUG("Adjust lower bound to %"PRIdMAX, ct->lower_bound); + /* TODO: adjust lower bound */ + _ASN_ENCODE_FAILED; + } @@ -2749,10 +2829,10 @@ Index: skeletons/INTEGER.c + _ASN_ENCODED_OK(er); +} + + #endif /* ASN_DISABLE_PER_SUPPORT */ + int - asn_INTEGER2long(const INTEGER_t *iptr, long *lptr) { - uint8_t *b, *end; -@@ -822,6 +1115,66 @@ +@@ -825,6 +1128,66 @@ } int @@ -2819,7 +2899,7 @@ Index: skeletons/INTEGER.c asn_INTEGER2ulong(const INTEGER_t *iptr, unsigned long *lptr) { uint8_t *b, *end; unsigned long l; -@@ -854,6 +1207,38 @@ +@@ -857,6 +1220,38 @@ } int @@ -2858,7 +2938,16 @@ Index: skeletons/INTEGER.c asn_ulong2INTEGER(INTEGER_t *st, unsigned long value) { uint8_t *buf; uint8_t *end; -@@ -879,6 +1264,31 @@ +@@ -871,7 +1266,7 @@ + + end = buf + (sizeof(value) + 1); + buf[0] = 0; +- for(b = buf + 1, shr = (sizeof(long)-1)*8; b < end; shr -= 8, b++) ++ for(b = buf + 1, shr = (sizeof(unsigned long)-1)*8; b < end; shr -= 8, b++) + *b = (uint8_t)(value >> shr); + + if(st->buf) FREEMEM(st->buf); +@@ -882,6 +1277,31 @@ } int @@ -2890,10 +2979,10 @@ Index: skeletons/INTEGER.c asn_long2INTEGER(INTEGER_t *st, long value) { uint8_t *buf, *bp; uint8_t *p; -@@ -932,3 +1342,58 @@ - - return 0; +@@ -1024,3 +1444,60 @@ + return ASN_STRTOL_OK; } + + +int +asn_int642INTEGER(INTEGER_t *st, int64_t value) { @@ -2949,24 +3038,126 @@ Index: skeletons/INTEGER.c + + return 0; +} -Index: skeletons/NativeReal.h -=================================================================== ---- skeletons/NativeReal.h (revision 1410) -+++ skeletons/NativeReal.h (working copy) -@@ -27,6 +27,8 @@ - xer_type_encoder_f NativeReal_encode_xer; - 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; - - #ifdef __cplusplus - } ++ ++ Index: skeletons/constr_SEQUENCE.c =================================================================== ---- skeletons/constr_SEQUENCE.c (revision 1410) +--- skeletons/constr_SEQUENCE.c (revision 1516) +++ skeletons/constr_SEQUENCE.c (working copy) -@@ -740,7 +740,7 @@ +@@ -34,7 +34,7 @@ + #undef ADVANCE + #define ADVANCE(num_bytes) do { \ + size_t num = num_bytes; \ +- ptr = ((const void *)ptr) + num;\ ++ ptr = ((const char *)ptr) + num;\ + size -= num; \ + if(ctx->left >= 0) \ + ctx->left -= num; \ +@@ -144,7 +144,7 @@ + /* + * Restore parsing context. + */ +- ctx = (asn_struct_ctx_t *)((void *)st + specs->ctx_offset); ++ ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset); + + /* + * Start to parse where left previously +@@ -366,7 +366,7 @@ + ber_tlv_tag_string(tlv_tag), edx); + skip = ber_skip_length(opt_codec_ctx, + BER_TLV_CONSTRUCTED(ptr), +- (const void *)ptr + tag_len, ++ (const char *)ptr + tag_len, + LEFT - tag_len); + ASN_DEBUG("Skip length %d in %s", + (int)skip, td->name); +@@ -397,13 +397,13 @@ + */ + if(elements[edx].flags & ATF_POINTER) { + /* Member is a pointer to another structure */ +- memb_ptr2 = (void **)((void *)st + elements[edx].memb_offset); ++ memb_ptr2 = (void **)((char *)st + elements[edx].memb_offset); + } else { + /* + * A pointer to a pointer + * holding the start of the structure + */ +- memb_ptr = (void *)st + elements[edx].memb_offset; ++ memb_ptr = (char *)st + elements[edx].memb_offset; + memb_ptr2 = &memb_ptr; + } + /* +@@ -489,7 +489,7 @@ + + ll = ber_skip_length(opt_codec_ctx, + BER_TLV_CONSTRUCTED(ptr), +- (const void *)ptr + tl, LEFT - tl); ++ (const char *)ptr + tl, LEFT - tl); + switch(ll) { + case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE); + /* Fall through */ +@@ -528,14 +528,14 @@ + asn_TYPE_member_t *elm = &td->elements[edx]; + void *memb_ptr; + if(elm->flags & ATF_POINTER) { +- memb_ptr = *(void **)((void *)sptr + elm->memb_offset); ++ memb_ptr = *(void **)((char *)sptr + elm->memb_offset); + if(!memb_ptr) { + if(elm->optional) continue; + /* Mandatory element is missing */ + _ASN_ENCODE_FAILED; + } + } else { +- memb_ptr = (void *)((void *)sptr + elm->memb_offset); ++ memb_ptr = (void *)((char *)sptr + elm->memb_offset); + } + erval = elm->type->der_encoder(elm->type, memb_ptr, + elm->tag_mode, elm->tag, +@@ -567,10 +567,10 @@ + void *memb_ptr; + + if(elm->flags & ATF_POINTER) { +- memb_ptr = *(void **)((void *)sptr + elm->memb_offset); ++ memb_ptr = *(void **)((char *)sptr + elm->memb_offset); + if(!memb_ptr) continue; + } else { +- memb_ptr = (void *)((void *)sptr + elm->memb_offset); ++ memb_ptr = (void *)((char *)sptr + elm->memb_offset); + } + tmperval = elm->type->der_encoder(elm->type, memb_ptr, + elm->tag_mode, elm->tag, +@@ -595,7 +595,7 @@ + #undef XER_ADVANCE + #define XER_ADVANCE(num_bytes) do { \ + size_t num = num_bytes; \ +- buf_ptr = ((const void *)buf_ptr) + num;\ ++ buf_ptr = ((const char *)buf_ptr) + num;\ + size -= num; \ + consumed_myself += num; \ + } while(0) +@@ -637,7 +637,7 @@ + /* + * Restore parsing context. + */ +- ctx = (asn_struct_ctx_t *)((void *)st + specs->ctx_offset); ++ ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset); + + + /* +@@ -667,9 +667,10 @@ + + if(elm->flags & ATF_POINTER) { + /* Member is a pointer to another structure */ +- memb_ptr2 = (void **)((void *)st + elm->memb_offset); ++ memb_ptr2 = (void **)((char *)st ++ + elm->memb_offset); + } else { +- memb_ptr = (void *)st + elm->memb_offset; ++ memb_ptr = (char *)st + elm->memb_offset; + memb_ptr2 = &memb_ptr; + } + +@@ -739,7 +740,7 @@ if(edx >= td->elements_count || /* Explicit OPTIONAL specs reaches the end */ @@ -2975,30 +3166,174 @@ Index: skeletons/constr_SEQUENCE.c == td->elements_count) || /* All extensions are optional */ -@@ -1158,8 +1158,8 @@ - ASN_DEBUG("Read in extensions bitmap for %s of %d bits (%x..)", - td->name, bmlength, *epres); +@@ -869,7 +870,7 @@ + unsigned int mlen = strlen(mname); -- /* Go over extensions and read them in */ -- for(edx = specs->ext_after + 1; edx < td->elements_count; edx++) { + if(elm->flags & ATF_POINTER) { +- memb_ptr = *(void **)((void *)sptr + elm->memb_offset); ++ memb_ptr = *(void **)((char *)sptr + elm->memb_offset); + if(!memb_ptr) { + if(elm->optional) + continue; +@@ -877,7 +878,7 @@ + _ASN_ENCODE_FAILED; + } + } else { +- memb_ptr = (void *)((void *)sptr + elm->memb_offset); ++ memb_ptr = (void *)((char *)sptr + elm->memb_offset); + } + + if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel); +@@ -917,14 +918,14 @@ + const void *memb_ptr; + + if(elm->flags & ATF_POINTER) { +- memb_ptr = *(const void * const *)((const void *)sptr + elm->memb_offset); ++ memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset); + if(!memb_ptr) { + if(elm->optional) continue; + /* Print line */ + /* Fall through */ + } + } else { +- memb_ptr = (const void *)((const void *)sptr + elm->memb_offset); ++ memb_ptr = (const void *)((const char *)sptr + elm->memb_offset); + } + + /* Indentation */ +@@ -960,11 +961,11 @@ + asn_TYPE_member_t *elm = &td->elements[edx]; + void *memb_ptr; + if(elm->flags & ATF_POINTER) { +- memb_ptr = *(void **)((void *)sptr + elm->memb_offset); ++ memb_ptr = *(void **)((char *)sptr + elm->memb_offset); + if(memb_ptr) + ASN_STRUCT_FREE(*elm->type, memb_ptr); + } else { +- memb_ptr = (void *)((void *)sptr + elm->memb_offset); ++ memb_ptr = (void *)((char *)sptr + elm->memb_offset); + ASN_STRUCT_FREE_CONTENTS_ONLY(*elm->type, memb_ptr); + } + } +@@ -994,7 +995,7 @@ + const void *memb_ptr; + + if(elm->flags & ATF_POINTER) { +- memb_ptr = *(const void * const *)((const void *)sptr + elm->memb_offset); ++ memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset); + if(!memb_ptr) { + if(elm->optional) + continue; +@@ -1004,7 +1005,7 @@ + return -1; + } + } else { +- memb_ptr = (const void *)((const void *)sptr + elm->memb_offset); ++ memb_ptr = (const void *)((const char *)sptr + elm->memb_offset); + } + + if(elm->memb_constraints) { +@@ -1088,9 +1089,9 @@ + + /* Fetch the pointer to this member */ + if(elm->flags & ATF_POINTER) { +- memb_ptr2 = (void **)((void *)st + elm->memb_offset); ++ memb_ptr2 = (void **)((char *)st + elm->memb_offset); + } else { +- memb_ptr = (void *)st + elm->memb_offset; ++ memb_ptr = (char *)st + elm->memb_offset; + memb_ptr2 = &memb_ptr; + } + +@@ -1154,11 +1155,224 @@ + memset(&epmd, 0, sizeof(epmd)); + epmd.buffer = epres; + epmd.nbits = bmlength; ++ ASN_DEBUG("Read in extensions bitmap for %s of %d bits (%x..)", ++ td->name, bmlength, *epres); ++ + /* Go over extensions and read them in */ + for(edx = specs->ext_after + 1; 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 */ -@@ -1191,7 +1191,7 @@ - FREEMEM(epres); - return rv; - } -- } ++ 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("%d is not extension", edx); ++ continue; + } - - /* Skip over overflow extensions which aren't present - * in this system's version of the protocol */ -@@ -1240,6 +1240,219 @@ - return rv; - } - ++ ++ /* 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->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) 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(1, memb_ptr2)) { ++ _ASN_DECODE_FAILED; ++ } ++ } ++ ++ rv.consumed = 0; ++ rv.code = RC_OK; ++ return rv; ++} ++ +asn_dec_rval_t +SEQUENCE_decode_aper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, + asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { @@ -3127,104 +3462,91 @@ Index: skeletons/constr_SEQUENCE.c + memset(&epmd, 0, sizeof(epmd)); + epmd.buffer = epres; + epmd.nbits = bmlength; -+ ASN_DEBUG("Read in extensions bitmap for %s of %d bits (%x..)", -+ td->name, bmlength, *epres); -+ + ASN_DEBUG("Read in extensions bitmap for %s of %ld bits (%x..)", + td->name, (long)bmlength, *epres); + +- /* Go over extensions and read them in */ +- for(edx = specs->ext_after + 1; edx < td->elements_count; edx++) { + /* Go over extensions and read them in */ + for(edx = specs->ext_after + 1; 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("%d 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->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) 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(1, memb_ptr2)) { -+ _ASN_DECODE_FAILED; -+ } -+ } -+ -+ rv.consumed = 0; -+ rv.code = RC_OK; -+ return rv; -+} -+ - static int - SEQUENCE_handle_extensions(asn_TYPE_descriptor_t *td, void *sptr, - asn_per_outp_t *po1, asn_per_outp_t *po2) { -@@ -1283,7 +1496,7 @@ - if(po1 && per_put_few_bits(po1, present, 1)) - return -1; - /* Encode as open type field */ -- if(po2 && present && uper_open_type_put(elm->type, -+ if(po2 && present && aper_open_type_put(elm->type, - elm->per_constraints, *memb_ptr2, po2)) - return -1; + asn_TYPE_member_t *elm = &td->elements[edx]; + void *memb_ptr; /* Pointer to the member */ + void **memb_ptr2; /* Pointer to that pointer */ +@@ -1171,9 +1385,9 @@ -@@ -1421,3 +1634,130 @@ + /* Fetch the pointer to this member */ + if(elm->flags & ATF_POINTER) { +- memb_ptr2 = (void **)((void *)st + elm->memb_offset); ++ memb_ptr2 = (void **)((char *)st + elm->memb_offset); + } else { +- memb_ptr = (void *)((void *)st + elm->memb_offset); ++ memb_ptr = (void *)((char *)st + elm->memb_offset); + memb_ptr2 = &memb_ptr; + } + +@@ -1190,7 +1404,7 @@ + FREEMEM(epres); + return rv; + } +- } ++ } + + /* Skip over overflow extensions which aren't present + * in this system's version of the protocol */ +@@ -1221,7 +1435,7 @@ + + /* Fetch the pointer to this member */ + if(elm->flags & ATF_POINTER) { +- memb_ptr2 = (void **)((void *)st ++ memb_ptr2 = (void **)((char *)st + + elm->memb_offset); + if(*memb_ptr2) continue; + } else { +@@ -1265,10 +1479,10 @@ + + /* Fetch the pointer to this member */ + if(elm->flags & ATF_POINTER) { +- memb_ptr2 = (void **)((void *)sptr + elm->memb_offset); ++ memb_ptr2 = (void **)((char *)sptr + elm->memb_offset); + present = (*memb_ptr2 != 0); + } else { +- memb_ptr = (void *)((void *)sptr + elm->memb_offset); ++ memb_ptr = (void *)((char *)sptr + elm->memb_offset); + memb_ptr2 = &memb_ptr; + present = 1; + } +@@ -1334,10 +1548,10 @@ + + /* Fetch the pointer to this member */ + if(elm->flags & ATF_POINTER) { +- memb_ptr2 = (void **)((void *)sptr + elm->memb_offset); ++ memb_ptr2 = (void **)((char *)sptr + elm->memb_offset); + present = (*memb_ptr2 != 0); + } else { +- memb_ptr = (void *)((void *)sptr + elm->memb_offset); ++ memb_ptr = (void *)((char *)sptr + elm->memb_offset); + memb_ptr2 = &memb_ptr; + present = 1; + } +@@ -1373,7 +1587,7 @@ + + /* Fetch the pointer to this member */ + if(elm->flags & ATF_POINTER) { +- memb_ptr2 = (void **)((void *)sptr + elm->memb_offset); ++ memb_ptr2 = (void **)((char *)sptr + elm->memb_offset); + if(!*memb_ptr2) { + ASN_DEBUG("Element %s %d not present", + elm->name, edx); +@@ -1383,7 +1597,7 @@ + _ASN_ENCODE_FAILED; + } + } else { +- memb_ptr = (void *)((void *)sptr + elm->memb_offset); ++ memb_ptr = (void *)((char *)sptr + elm->memb_offset); + memb_ptr2 = &memb_ptr; + } + +@@ -1420,3 +1634,130 @@ _ASN_ENCODED_OK(er); } @@ -3355,217 +3677,10 @@ Index: skeletons/constr_SEQUENCE.c + + _ASN_ENCODED_OK(er); +} -Index: skeletons/NativeEnumerated.c -=================================================================== ---- skeletons/NativeEnumerated.c (revision 1410) -+++ skeletons/NativeEnumerated.c (working copy) -@@ -30,6 +30,8 @@ - NativeEnumerated_encode_xer, - NativeEnumerated_decode_uper, - NativeEnumerated_encode_uper, -+ NativeEnumerated_decode_aper, -+ NativeEnumerated_encode_aper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_NativeEnumerated_tags, - sizeof(asn_DEF_NativeEnumerated_tags) / sizeof(asn_DEF_NativeEnumerated_tags[0]), -@@ -42,17 +44,17 @@ - - asn_enc_rval_t - NativeEnumerated_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, -- int ilevel, enum xer_encoder_flags_e flags, -- asn_app_consume_bytes_f *cb, void *app_key) { -+ int ilevel, enum xer_encoder_flags_e flags, -+ asn_app_consume_bytes_f *cb, void *app_key) { - asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics; -- asn_enc_rval_t er; -- const long *native = (const long *)sptr; -+ asn_enc_rval_t er; -+ const long *native = (const long *)sptr; - const asn_INTEGER_enum_map_t *el; - -- (void)ilevel; -- (void)flags; -+ (void)ilevel; -+ (void)flags; - -- if(!native) _ASN_ENCODE_FAILED; -+ if(!native) _ASN_ENCODE_FAILED; - - el = INTEGER_map_value2enum(specs, *native); - if(el) { -@@ -125,6 +127,61 @@ - return rval; - } - -+asn_dec_rval_t -+NativeEnumerated_decode_aper(asn_codec_ctx_t *opt_codec_ctx, -+ asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, -+ void **sptr, asn_per_data_t *pd) { -+ asn_INTEGER_specifics_t *specs = (asn_INTEGER_specifics_t *)td->specifics; -+ asn_dec_rval_t rval = { RC_OK, 0 }; -+ long *native = (long *)*sptr; -+ asn_per_constraint_t *ct; -+ long value; -+ -+ (void)opt_codec_ctx; -+ -+ if(constraints) ct = &constraints->value; -+ else if(td->per_constraints) ct = &td->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; -+ } -+ -+ 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; -+} -+ - static int - NativeEnumerated__compar_value2enum(const void *ap, const void *bp) { - const asn_INTEGER_enum_map_t *a = ap; -@@ -205,3 +262,71 @@ - _ASN_ENCODED_OK(er); - } - -+asn_enc_rval_t -+NativeEnumerated_encode_aper(asn_TYPE_descriptor_t *td, -+ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { -+ asn_INTEGER_specifics_t *specs = (asn_INTEGER_specifics_t *)td->specifics; -+ asn_enc_rval_t er; -+ long native, value; -+ 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->per_constraints) ct = &td->per_constraints->value; -+ else _ASN_ENCODE_FAILED; /* Mandatory! */ -+ -+ ASN_DEBUG("Encoding %s as NativeEnumerated", td->name); -+ -+ er.encoded = 0; -+ -+ native = *(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); -+} -Index: skeletons/TeletexString.c -=================================================================== ---- skeletons/TeletexString.c (revision 1410) -+++ skeletons/TeletexString.c (working copy) -@@ -24,6 +24,8 @@ - OCTET_STRING_encode_xer, - OCTET_STRING_decode_uper, - OCTET_STRING_encode_uper, -+ OCTET_STRING_decode_aper, -+ OCTET_STRING_encode_aper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_TeletexString_tags, - sizeof(asn_DEF_TeletexString_tags) -Index: skeletons/T61String.c -=================================================================== ---- skeletons/T61String.c (revision 1410) -+++ skeletons/T61String.c (working copy) -@@ -24,6 +24,8 @@ - OCTET_STRING_encode_xer, - OCTET_STRING_decode_uper, - OCTET_STRING_encode_uper, -+ OCTET_STRING_decode_aper, -+ OCTET_STRING_encode_aper, - 0, /* Use generic outmost tag fetcher */ - asn_DEF_T61String_tags, - sizeof(asn_DEF_T61String_tags) Index: skeletons/INTEGER.h =================================================================== ---- skeletons/INTEGER.h (revision 1410) +--- skeletons/INTEGER.h (revision 1516) +++ skeletons/INTEGER.h (working copy) -@@ -18,7 +18,7 @@ - - /* Map with to integer value association */ - typedef struct asn_INTEGER_enum_map_s { -- long nat_value; /* associated native integer value */ -+ int64_t nat_value; /* associated native integer value */ - size_t enum_len; /* strlen("tag") */ - const char *enum_name; /* "tag" */ - } asn_INTEGER_enum_map_t; @@ -41,6 +41,8 @@ xer_type_encoder_f INTEGER_encode_xer; per_type_decoder_f INTEGER_decode_uper; @@ -3588,9 +3703,615 @@ Index: skeletons/INTEGER.h int asn_long2INTEGER(INTEGER_t *i, long l); int asn_ulong2INTEGER(INTEGER_t *i, unsigned long l); +Index: skeletons/OCTET_STRING.c +=================================================================== +--- skeletons/OCTET_STRING.c (revision 1516) ++++ skeletons/OCTET_STRING.c (working copy) +@@ -36,6 +36,8 @@ + OCTET_STRING_encode_xer, + 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 */ + 0, /* Use generic outmost tag fetcher */ + asn_DEF_OCTET_STRING_tags, + sizeof(asn_DEF_OCTET_STRING_tags) +@@ -86,7 +88,7 @@ + void *ptr; \ + /* Be nice and round to the memory allocator */ \ + do { _ns = _ns ? _ns << 1 : 16; } \ +- while(_ns <= _es); \ ++ while(_ns <= _es); \ + /* int is really a typeof(st->size): */ \ + if((int)_ns < 0) RETURN(RC_FAIL); \ + ptr = REALLOC(st->buf, _ns); \ +@@ -195,7 +197,7 @@ + } + + /* Restore parsing context */ +- ctx = (asn_struct_ctx_t *)((void *)st + specs->ctx_offset); ++ ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset); + + switch(ctx->phase) { + case 0: +@@ -416,7 +418,7 @@ + ASN_DEBUG("Phase 2: Need %ld bytes, size=%ld, alrg=%ld, wn=%d", + (long)sel->left, (long)size, (long)sel->got, + sel->want_nulls); +- { ++ { + ber_tlv_len_t len; + + assert(sel->left >= 0); +@@ -446,7 +448,7 @@ + + PREV_PHASE(ctx); + goto phase1; +- } ++ } + break; + case 3: + phase3: +@@ -1143,7 +1145,7 @@ + } + + /* Restore parsing context */ +- ctx = (asn_struct_ctx_t *)(((void *)*sptr) + specs->ctx_offset); ++ ctx = (asn_struct_ctx_t *)(((char *)*sptr) + specs->ctx_offset); + + return xer_decode_general(opt_codec_ctx, ctx, *sptr, xml_tag, + buf_ptr, size, opt_unexpected_tag_decoder, body_receiver); +@@ -1392,7 +1394,7 @@ + if(!st) RETURN(RC_FAIL); + } + +- ASN_DEBUG("PER Decoding %s size %ld .. %ld bits %d", ++ ASN_DEBUG("PER Decoding %s size %"PRIdMAX" .. %"PRIdMAX" bits %d", + csiz->flags & APC_EXTENSIBLE ? "extensible" : "non-extensible", + csiz->lower_bound, csiz->upper_bound, csiz->effective_bits); + +@@ -1423,17 +1425,17 @@ + if(csiz->effective_bits == 0) { + int ret; + if(bpc) { +- ASN_DEBUG("Encoding OCTET STRING size %ld", ++ ASN_DEBUG("Encoding OCTET STRING size %"PRIdMAX, + 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("Encoding BIT STRING size %ld", ++ ASN_DEBUG("Encoding BIT STRING size %"PRIdMAX, + csiz->upper_bound); + ret = per_get_many_bits(pd, st->buf, 0, +- unit_bits * csiz->upper_bound); ++ unit_bits * csiz->upper_bound); + } + if(ret < 0) RETURN(RC_WMORE); + consumed_myself += unit_bits * csiz->upper_bound; +@@ -1492,9 +1494,197 @@ + return rval; + } + ++asn_dec_rval_t ++OCTET_STRING_decode_aper(asn_codec_ctx_t *opt_codec_ctx, ++ asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, ++ void **sptr, asn_per_data_t *pd) { ++ ++ asn_OCTET_STRING_specifics_t *specs = td->specifics ++ ? (asn_OCTET_STRING_specifics_t *)td->specifics ++ : &asn_DEF_OCTET_STRING_specs; ++ asn_per_constraints_t *pc = constraints ? constraints ++ : td->per_constraints; ++ asn_per_constraint_t *cval; ++ 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 %"PRIdMAX" .. %"PRIdMAX" 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 %"PRIdMAX, ++ 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 %"PRIdMAX, ++ 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_uper(asn_TYPE_descriptor_t *td, +- asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { ++ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { + + asn_OCTET_STRING_specifics_t *specs = td->specifics + ? (asn_OCTET_STRING_specifics_t *)td->specifics +@@ -1566,7 +1756,7 @@ + } + + ASN_DEBUG("Encoding %s into %d units of %d bits" +- " (%ld..%ld, effective %d)%s", ++ " (%"PRIdMAX"..%"PRIdMAX", effective %d)%s", + td->name, sizeinunits, unit_bits, + csiz->lower_bound, csiz->upper_bound, + csiz->effective_bits, ct_extensible ? " EXT" : ""); +@@ -1598,7 +1788,7 @@ + /* 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 %d bytes (%ld), length in %d bits", ++ ASN_DEBUG("Encoding %d bytes (%"PRIdMAX"), length in %d bits", + st->size, sizeinunits - csiz->lower_bound, + csiz->effective_bits); + ret = per_put_few_bits(po, sizeinunits - csiz->lower_bound, +@@ -1652,6 +1842,173 @@ + _ASN_ENCODED_OK(er); + } + ++asn_enc_rval_t ++OCTET_STRING_encode_aper(asn_TYPE_descriptor_t *td, ++ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { ++ ++ asn_OCTET_STRING_specifics_t *specs = td->specifics ++ ? (asn_OCTET_STRING_specifics_t *)td->specifics ++ : &asn_DEF_OCTET_STRING_specs; ++ asn_per_constraints_t *pc = constraints ? constraints ++ : td->per_constraints; ++ asn_per_constraint_t *cval; ++ 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 bits", ++ 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" ++ " (%"PRIdMAX"..%"PRIdMAX", 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 %d bytes (%"PRIdMAX"), length in %d bits", ++ st->size, sizeinunits - csiz->lower_bound, ++ csiz->effective_bits); ++ ret = per_put_few_bits(po, sizeinunits - csiz->lower_bound, ++ csiz->effective_bits); ++ 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 %d 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); ++} ++ + int + OCTET_STRING_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, + asn_app_consume_bytes_f *cb, void *app_key) { +@@ -1716,7 +2073,7 @@ + ? (asn_OCTET_STRING_specifics_t *)td->specifics + : &asn_DEF_OCTET_STRING_specs; + asn_struct_ctx_t *ctx = (asn_struct_ctx_t *) +- ((void *)st + specs->ctx_offset); ++ ((char *)st + specs->ctx_offset); + struct _stack *stck; + + if(!td || !st) +Index: skeletons/BIT_STRING.c +=================================================================== +--- skeletons/BIT_STRING.c (revision 1516) ++++ skeletons/BIT_STRING.c (working copy) +@@ -29,6 +29,8 @@ + BIT_STRING_encode_xer, + 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 */ + 0, /* Use generic outmost tag fetcher */ + asn_DEF_BIT_STRING_tags, + sizeof(asn_DEF_BIT_STRING_tags) +Index: skeletons/NativeInteger.c +=================================================================== +--- skeletons/NativeInteger.c (revision 1516) ++++ skeletons/NativeInteger.c (working copy) +@@ -31,6 +31,8 @@ + NativeInteger_encode_xer, + NativeInteger_decode_uper, /* Unaligned PER decoder */ + NativeInteger_encode_uper, /* Unaligned PER encoder */ ++ NativeInteger_decode_aper, /* Aligned PER decoder */ ++ NativeInteger_encode_aper, /* Aligned PER encoder */ + 0, /* Use generic outmost tag fetcher */ + asn_DEF_NativeInteger_tags, + sizeof(asn_DEF_NativeInteger_tags) / sizeof(asn_DEF_NativeInteger_tags[0]), +@@ -267,6 +269,46 @@ + return rval; + } + ++asn_dec_rval_t ++NativeInteger_decode_aper(asn_codec_ctx_t *opt_codec_ctx, ++ asn_TYPE_descriptor_t *td, ++ asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { ++ ++ asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics; ++ asn_dec_rval_t rval; ++ long *native = (long *)*sptr; ++ INTEGER_t tmpint; ++ void *tmpintptr = &tmpint; ++ int dynamic = 0; ++ ++ (void)opt_codec_ctx; ++ ASN_DEBUG("Decoding NativeInteger %s (APER)", td->name); ++ ++ if(!native) { ++ native = (long *)(*sptr = CALLOC(1, sizeof(*native))); ++ dynamic = 1; ++ 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); ++ if (dynamic) ++ free(native); ++ ++ return rval; ++} ++ + asn_enc_rval_t + NativeInteger_encode_uper(asn_TYPE_descriptor_t *td, + asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { +@@ -291,6 +333,44 @@ + return er; + } + ++asn_enc_rval_t ++NativeInteger_encode_aper( ++ asn_TYPE_descriptor_t *td, ++ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { ++ ++ asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics; ++ asn_enc_rval_t er; ++ INTEGER_t tmpint; ++ ++ if(!sptr) _ASN_ENCODE_FAILED; ++ memset(&tmpint, 0, sizeof(tmpint)); ++ ++ if(specs&&specs->field_unsigned) { ++ unsigned long native; ++ native = *(unsigned long *)sptr; ++ ++ ASN_DEBUG("Encoding NativeInteger %s %lu (APER) (unsigned)", td->name, native); ++ ++ if(asn_ulong2INTEGER(&tmpint, native)) ++ _ASN_ENCODE_FAILED; ++ } else { ++ long native; ++ native = *(long *)sptr; ++ ++ ASN_DEBUG("Encoding NativeInteger %s %ld (APER) (unsigned)", td->name, native); ++ if(asn_long2INTEGER(&tmpint, native)) ++ _ASN_ENCODE_FAILED; ++ } ++ ++// if((specs&&specs->field_unsigned) ++// ? asn_ulong2INTEGER(&tmpint, 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; ++} ++ + /* + * INTEGER specific human-readable output. + */ Index: skeletons/constr_SEQUENCE.h =================================================================== ---- skeletons/constr_SEQUENCE.h (revision 1410) +--- skeletons/constr_SEQUENCE.h (revision 1516) +++ skeletons/constr_SEQUENCE.h (working copy) @@ -52,6 +52,8 @@ xer_type_encoder_f SEQUENCE_encode_xer; @@ -3601,189 +4322,35 @@ Index: skeletons/constr_SEQUENCE.h #ifdef __cplusplus } -Index: skeletons/BMPString.c +Index: skeletons/NativeInteger.h =================================================================== ---- skeletons/BMPString.c (revision 1410) -+++ skeletons/BMPString.c (working copy) -@@ -35,6 +35,8 @@ - BMPString_encode_xer, /* Convert to UTF-8 */ - OCTET_STRING_decode_uper, - OCTET_STRING_encode_uper, -+ OCTET_STRING_decode_aper, /* Aligned PER decoder */ -+ OCTET_STRING_encode_aper, /* Aligned PER encoder */ - 0, /* Use generic outmost tag fetcher */ - asn_DEF_BMPString_tags, - sizeof(asn_DEF_BMPString_tags) -Index: skeletons/NativeEnumerated.h -=================================================================== ---- skeletons/NativeEnumerated.h (revision 1410) -+++ skeletons/NativeEnumerated.h (working copy) -@@ -24,6 +24,8 @@ - xer_type_encoder_f NativeEnumerated_encode_xer; - 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; +--- skeletons/NativeInteger.h (revision 1516) ++++ skeletons/NativeInteger.h (working copy) +@@ -29,6 +29,8 @@ + xer_type_encoder_f NativeInteger_encode_xer; + 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; #ifdef __cplusplus } -Index: skeletons/constr_SET_OF.c +Index: skeletons/OCTET_STRING.h =================================================================== ---- skeletons/constr_SET_OF.c (revision 1410) -+++ skeletons/constr_SET_OF.c (working copy) -@@ -884,7 +884,7 @@ - if(!st) { - st = *sptr = CALLOC(1, specs->struct_size); - if(!st) _ASN_DECODE_FAILED; -- } -+ } - list = _A_SET_FROM_VOID(st); +--- skeletons/OCTET_STRING.h (revision 1516) ++++ skeletons/OCTET_STRING.h (working copy) +@@ -32,6 +32,8 @@ + xer_type_encoder_f OCTET_STRING_encode_xer_utf8; + 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; - /* Figure out which constraints to use */ -@@ -901,7 +901,7 @@ - if(ct && ct->effective_bits >= 0) { - /* X.691, #19.5: No length determinant */ - nelems = per_get_few_bits(pd, ct->effective_bits); -- ASN_DEBUG("Preparing to fetch %ld+%ld elements from %s", -+ ASN_DEBUG("Preparing to fetch %ld+%lld elements from %s", - (long)nelems, ct->lower_bound, td->name); - if(nelems < 0) _ASN_DECODE_STARVED; - nelems += ct->lower_bound; -@@ -951,3 +951,91 @@ - return rv; - } - -+asn_dec_rval_t -+SET_OF_decode_aper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, -+ asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { -+ asn_dec_rval_t rv; -+ asn_SET_OF_specifics_t *specs = (asn_SET_OF_specifics_t *)td->specifics; -+ asn_TYPE_member_t *elm = td->elements; /* Single one */ -+ void *st = *sptr; -+ asn_anonymous_set_ *list; -+ 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->per_constraints) ct = &td->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 = per_get_few_bits(pd, ct->effective_bits); -+ nelems = aper_get_nsnnwn(pd, ct->upper_bound - ct->lower_bound); -+ ASN_DEBUG("Preparing to fetch %ld+%lld 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->aper_decoder(opt_codec_ctx, elm->type, -+ elm->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; -+} -Index: skeletons/per_opentype.c -=================================================================== ---- skeletons/per_opentype.c (revision 1410) -+++ skeletons/per_opentype.c (working copy) -@@ -53,6 +53,35 @@ - return 0; - } - -+int -+aper_open_type_put(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, 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 %d + overhead (1byte?)", -+ td->name, size); -+ -+ return 0; -+} -+ - static asn_dec_rval_t - uper_open_type_get_simple(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { + /****************************** + * Handy conversion routines. * Index: skeletons/UTCTime.c =================================================================== ---- skeletons/UTCTime.c (revision 1410) +--- skeletons/UTCTime.c (revision 1516) +++ skeletons/UTCTime.c (working copy) @@ -40,6 +40,8 @@ UTCTime_encode_xer, @@ -3794,49 +4361,45 @@ Index: skeletons/UTCTime.c 0, /* Use generic outmost tag fetcher */ asn_DEF_UTCTime_tags, sizeof(asn_DEF_UTCTime_tags) -Index: skeletons/constr_SET_OF.h +Index: skeletons/REAL.c =================================================================== ---- skeletons/constr_SET_OF.h (revision 1410) -+++ skeletons/constr_SET_OF.h (working copy) -@@ -34,6 +34,8 @@ - xer_type_encoder_f SET_OF_encode_xer; - 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; - - #ifdef __cplusplus - } -Index: skeletons/UTF8String.c -=================================================================== ---- skeletons/UTF8String.c (revision 1410) -+++ skeletons/UTF8String.c (working copy) -@@ -25,6 +25,8 @@ - OCTET_STRING_encode_xer_utf8, - OCTET_STRING_decode_uper, - OCTET_STRING_encode_uper, -+ OCTET_STRING_decode_aper, -+ OCTET_STRING_encode_aper, +--- skeletons/REAL.c (revision 1516) ++++ skeletons/REAL.c (working copy) +@@ -45,6 +45,8 @@ + REAL_encode_xer, + REAL_decode_uper, + REAL_encode_uper, ++ REAL_decode_aper, ++ REAL_encode_aper, 0, /* Use generic outmost tag fetcher */ - asn_DEF_UTF8String_tags, - sizeof(asn_DEF_UTF8String_tags) -Index: skeletons/per_opentype.h -=================================================================== ---- skeletons/per_opentype.h (revision 1410) -+++ skeletons/per_opentype.h (working copy) -@@ -15,6 +15,8 @@ - - int uper_open_type_put(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po); - -+int aper_open_type_put(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po); -+ - #ifdef __cplusplus + asn_DEF_REAL_tags, + sizeof(asn_DEF_REAL_tags) / sizeof(asn_DEF_REAL_tags[0]), +@@ -361,6 +363,21 @@ + return OCTET_STRING_encode_uper(td, 0, sptr, po); } - #endif -Index: skeletons/ISO646String.c + ++asn_dec_rval_t ++REAL_decode_aper(asn_codec_ctx_t *opt_codec_ctx, ++ asn_TYPE_descriptor_t *td, 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(asn_TYPE_descriptor_t *td, ++ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { ++ (void)constraints; /* No PER visible constraints */ ++ return OCTET_STRING_encode_aper(td, 0, sptr, po); ++} ++ + int + asn_REAL2double(const REAL_t *st, double *dbl_value) { + unsigned int octv; +Index: skeletons/VisibleString.c =================================================================== ---- skeletons/ISO646String.c (revision 1410) -+++ skeletons/ISO646String.c (working copy) +--- skeletons/VisibleString.c (revision 1516) ++++ skeletons/VisibleString.c (working copy) @@ -29,6 +29,8 @@ OCTET_STRING_encode_xer_utf8, OCTET_STRING_decode_uper, @@ -3844,46 +4407,11 @@ Index: skeletons/ISO646String.c + OCTET_STRING_decode_aper, + OCTET_STRING_encode_aper, 0, /* Use generic outmost tag fetcher */ - asn_DEF_ISO646String_tags, - sizeof(asn_DEF_ISO646String_tags) -Index: skeletons/asn_internal.h -=================================================================== ---- skeletons/asn_internal.h (revision 1410) -+++ skeletons/asn_internal.h (working copy) -@@ -20,7 +20,7 @@ - #endif - - /* Environment version might be used to avoid running with the old library */ --#define ASN1C_ENVIRONMENT_VERSION 922 /* Compile-time version */ -+#define ASN1C_ENVIRONMENT_VERSION 924 /* Compile-time version */ - int get_asn1c_environment_version(void); /* Run-time version */ - - #define CALLOC(nmemb, size) calloc(nmemb, size) -@@ -40,13 +40,17 @@ - #else /* !ASN_THREAD_SAFE */ - int asn_debug_indent; - #endif /* ASN_THREAD_SAFE */ --#define ASN_DEBUG(fmt, args...) do { \ -- int adi = asn_debug_indent; \ -+extern int asn_debug; -+#define ASN_DEBUG(fmt, args...) \ -+do { \ -+ if(asn_debug) { \ -+ int adi = asn_debug_indent; \ - while(adi--) fprintf(stderr, " "); \ - fprintf(stderr, fmt, ##args); \ - fprintf(stderr, " (%s:%d)\n", \ -- __FILE__, __LINE__); \ -- } while(0) -+ __FILE__, __LINE__); \ -+ } \ -+} while(0) - #else /* !__GNUC__ */ - void ASN_DEBUG_f(const char *fmt, ...); - #define ASN_DEBUG ASN_DEBUG_f + asn_DEF_VisibleString_tags, + sizeof(asn_DEF_VisibleString_tags) Index: skeletons/ANY.c =================================================================== ---- skeletons/ANY.c (revision 1410) +--- skeletons/ANY.c (revision 1516) +++ skeletons/ANY.c (working copy) @@ -21,7 +21,10 @@ OCTET_STRING_encode_der, @@ -4000,9 +4528,145 @@ Index: skeletons/ANY.c static int ANY__consume_bytes(const void *buffer, size_t size, void *key) { struct _callback_arg *arg = (struct _callback_arg *)key; +Index: skeletons/REAL.h +=================================================================== +--- skeletons/REAL.h (revision 1516) ++++ skeletons/REAL.h (working copy) +@@ -21,6 +21,8 @@ + xer_type_encoder_f REAL_encode_xer; + 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; + + /*********************************** + * Some handy conversion routines. * +Index: skeletons/NativeReal.c +=================================================================== +--- skeletons/NativeReal.c (revision 1516) ++++ skeletons/NativeReal.c (working copy) +@@ -32,6 +32,8 @@ + NativeReal_encode_xer, + NativeReal_decode_uper, + NativeReal_encode_uper, ++ NativeReal_decode_aper, ++ NativeReal_encode_aper, + 0, /* Use generic outmost tag fetcher */ + asn_DEF_NativeReal_tags, + sizeof(asn_DEF_NativeReal_tags) / sizeof(asn_DEF_NativeReal_tags[0]), +@@ -123,11 +125,11 @@ + tmp.size = length; + memcpy(tmp.buf, buf_ptr, length); + tmp.buf[tmp.size] = '\0'; +- if(asn_REAL2double(&tmp, &d)) { +- rval.code = RC_FAIL; +- rval.consumed = 0; +- return rval; +- } ++ if(asn_REAL2double(&tmp, &d)) { ++ rval.code = RC_FAIL; ++ rval.consumed = 0; ++ return rval; ++ } + } else { + /* This should probably never happen: impractically long value */ + tmp.buf = CALLOC(1, length + 1); +@@ -228,6 +230,43 @@ + return rval; + } + ++asn_dec_rval_t ++NativeReal_decode_aper(asn_codec_ctx_t *opt_codec_ctx, ++ asn_TYPE_descriptor_t *td, 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; ++} ++ + /* + * Encode the NativeReal using the OCTET STRING PER encoder. + */ +@@ -257,6 +296,32 @@ + return erval; + } + ++asn_enc_rval_t ++NativeReal_encode_aper(asn_TYPE_descriptor_t *td, ++ asn_per_constraints_t *constraints, 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; ++} ++ + /* + * Decode the chunk of XML text encoding REAL. + */ +Index: skeletons/asn_system.h +=================================================================== +--- skeletons/asn_system.h (revision 1516) ++++ skeletons/asn_system.h (working copy) +@@ -21,6 +21,11 @@ + #include /* For va_start */ + #include /* for offsetof and ptrdiff_t */ + ++#if HAVE_STDINT_H ++# include ++# include ++#endif ++ + #ifdef _WIN32 + + #include Index: skeletons/ANY.h =================================================================== ---- skeletons/ANY.h (revision 1410) +--- skeletons/ANY.h (revision 1516) +++ skeletons/ANY.h (working copy) @@ -32,10 +32,13 @@ @@ -4018,9 +4682,22 @@ Index: skeletons/ANY.h #define ANY_fromBuf(s, buf, size) OCTET_STRING_fromBuf((s), (buf), (size)) #define ANY_new_fromBuf(buf, size) OCTET_STRING_new_fromBuf( \ +Index: skeletons/NativeReal.h +=================================================================== +--- skeletons/NativeReal.h (revision 1516) ++++ skeletons/NativeReal.h (working copy) +@@ -27,6 +27,8 @@ + xer_type_encoder_f NativeReal_encode_xer; + 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; + + #ifdef __cplusplus + } Index: skeletons/UniversalString.c =================================================================== ---- skeletons/UniversalString.c (revision 1410) +--- skeletons/UniversalString.c (revision 1516) +++ skeletons/UniversalString.c (working copy) @@ -35,6 +35,8 @@ UniversalString_encode_xer, /* Convert into UTF-8 */ @@ -4031,104 +4708,90 @@ Index: skeletons/UniversalString.c 0, /* Use generic outmost tag fetcher */ asn_DEF_UniversalString_tags, sizeof(asn_DEF_UniversalString_tags) +Index: skeletons/GraphicString.c +=================================================================== +--- skeletons/GraphicString.c (revision 1516) ++++ skeletons/GraphicString.c (working copy) +@@ -24,6 +24,8 @@ + OCTET_STRING_encode_xer, /* Can't expect it to be ASCII/UTF8 */ + OCTET_STRING_decode_uper, /* Implemented in terms of OCTET STRING */ + OCTET_STRING_encode_uper, ++ OCTET_STRING_decode_aper, ++ OCTET_STRING_encode_aper, + 0, /* Use generic outmost tag fetcher */ + asn_DEF_GraphicString_tags, + sizeof(asn_DEF_GraphicString_tags) +Index: skeletons/GeneralizedTime.c +=================================================================== +--- skeletons/GeneralizedTime.c (revision 1516) ++++ skeletons/GeneralizedTime.c (working copy) +@@ -167,6 +167,8 @@ + GeneralizedTime_encode_xer, + OCTET_STRING_decode_uper, + OCTET_STRING_encode_uper, ++ OCTET_STRING_decode_aper, ++ OCTET_STRING_encode_aper, + 0, /* Use generic outmost tag fetcher */ + asn_DEF_GeneralizedTime_tags, + sizeof(asn_DEF_GeneralizedTime_tags) Index: libasn1compiler/asn1c_out.h =================================================================== ---- libasn1compiler/asn1c_out.h (revision 1410) +--- libasn1compiler/asn1c_out.h (revision 1516) +++ libasn1compiler/asn1c_out.h (working copy) -@@ -119,15 +119,23 @@ +@@ -117,16 +117,24 @@ + * Format LONG_MIN according to C90 rules. + */ #define OINT(iv) do { \ - if(iv == (-2147483647L - 1)) \ +- if(iv == (-2147483647L - 1)) \ ++ if(iv > 4294967295U) \ ++ OUT("%" PRIdASN"ULL", iv); \ ++ else if(iv > 2147483647L) \ ++ OUT("%" PRIdASN"U", iv); \ ++ else if(iv == (-2147483647L - 1)) \ OUT("(-2147483647L - 1)"); \ - else \ -- OUT("%" PRIdASN, iv); \ -+ else if (iv > 4294967296UL) \ -+ OUT("%" PRIdASN "ull", iv); \ -+ else if (iv > 2147483647L) \ -+ OUT("%" PRIdASN "ul", iv); \ + else \ -+ OUT("%" PRIdASN "l", iv); \ + OUT("%" PRIdASN, iv); \ } while(0) #define OINTS(iv) do { \ - if(iv == (-2147483647L - 1)) \ +- if(iv == (-2147483647L - 1)) \ ++ if(iv > 4294967295U) \ ++ OUT("%" PRIdASN"ULL", iv); \ ++ else if(iv > 2147483647L) \ ++ OUT("%" PRIdASN"U", iv); \ ++ else if(iv == (-2147483647L - 1)) \ OUT("(-2147483647L - 1)"); \ - else \ -- OUT("% " PRIdASN, iv); \ -+ else if (iv > 4294967296UL) \ -+ OUT("%" PRIdASN "ull", iv); \ -+ else if (iv > 2147483647L) \ -+ OUT("%" PRIdASN "ul", iv); \ + else \ -+ OUT("% " PRIdASN "l", iv); \ + OUT("% " PRIdASN, iv); \ } while(0) - #endif /* _ASN1_COMPILED_OUTPUT_H_ */ +Index: libasn1compiler/asn1compiler.h +=================================================================== +--- libasn1compiler/asn1compiler.h (revision 1516) ++++ libasn1compiler/asn1compiler.h (working copy) +@@ -77,7 +77,14 @@ + * -fline-refs + * Include ASN.1 module's line numbers in comments. + */ +- A1C_LINE_REFS = 0x20000 ++ A1C_LINE_REFS = 0x20000, ++ /* ++ * -fhave_native64 ++ * Assume target platform has native 64bits support and generate types using ++ * int64_t or uint64_t whereas possible ++ */ ++ A1C_HAVE_NATIVE_64 = 0x40000 ++ + }; + + /* Index: libasn1compiler/asn1c_C.c =================================================================== ---- libasn1compiler/asn1c_C.c (revision 1410) +--- libasn1compiler/asn1c_C.c (revision 1516) +++ libasn1compiler/asn1c_C.c (working copy) -@@ -139,9 +139,8 @@ - OUT("\t"); - out_name_chain(arg, ONC_noflags); - OUT("_%s", MKID(v)); -- OUT("\t= %" PRIdASN "%s\n", -- v->value->value.v_integer, -- (eidx+1 < el_count) ? "," : ""); -+ OUT("\t= %" PRIdASN ",\n", -+ v->value->value.v_integer); - v2e[eidx].name = v->Identifier; - v2e[eidx].value = v->value->value.v_integer; - eidx++; -@@ -157,6 +156,11 @@ - return -1; - } - } -+ /* Max value for comparing */ -+ OUT("\t"); -+ out_name_chain(arg, ONC_noflags); -+ OUT("_max,\n"); -+ - OUT("} e_"); - out_name_chain(arg, ONC_noflags); - OUT(";\n"); -@@ -513,6 +517,7 @@ - ); - mcount++; - } -+ - OUT("} "); out_name_chain(arg, ONC_noflags); OUT("_PR;\n"); - - REDIR(OT_TYPE_DECLS); -@@ -859,23 +864,23 @@ - out_name_chain(arg, ONC_noflags); - OUT("_PR {\n"); - INDENTED( -- int skipComma = 1; - out_name_chain(arg, ONC_noflags); - OUT("_PR_NOTHING,\t/* No components present */\n"); - TQ_FOR(v, &(expr->members), next) { -- if(skipComma) skipComma = 0; -- else OUT(",\n"); - if(v->expr_type == A1TC_EXTENSIBLE) { - OUT("/* Extensions may appear below */\n"); -- skipComma = 1; - continue; - } - out_name_chain(arg, ONC_noflags); - id = MKID(v); -- OUT("_PR_%s", id); -+ OUT("_PR_%s,\n", id); - } - OUT("\n"); - ); -+ INDENTED( -+ out_name_chain(arg, ONC_noflags); -+ OUT("_max,\n"); -+ ); - OUT("} "); out_name_chain(arg, ONC_noflags); OUT("_PR;\n"); - - REDIR(OT_TYPE_DECLS); -@@ -1242,6 +1247,8 @@ +@@ -1242,6 +1242,8 @@ OUT("td->xer_encoder = asn_DEF_%s.xer_encoder;\n", type_name); OUT("td->uper_decoder = asn_DEF_%s.uper_decoder;\n", type_name); OUT("td->uper_encoder = asn_DEF_%s.uper_encoder;\n", type_name); @@ -4137,12 +4800,11 @@ Index: libasn1compiler/asn1c_C.c if(!terminal && !tags_count) { OUT("/* The next four lines are here because of -fknown-extern-type */\n"); OUT("td->tags = asn_DEF_%s.tags;\n", type_name); -@@ -1394,8 +1401,40 @@ +@@ -1394,6 +1396,38 @@ ); OUT("}\n"); OUT("\n"); -- } - ++ + p = MKID(expr); + if(HIDE_INNER_DEFS) OUT("static "); + OUT("asn_enc_rval_t\n"); @@ -4174,12 +4836,10 @@ Index: libasn1compiler/asn1c_C.c + ); + OUT("}\n"); + OUT("\n"); -+ } -+ - REDIR(OT_FUNC_DECLS); + } - p = MKID(expr); -@@ -1415,6 +1454,8 @@ + REDIR(OT_FUNC_DECLS); +@@ -1415,6 +1449,8 @@ 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); @@ -4188,16 +4848,70 @@ Index: libasn1compiler/asn1c_C.c } } -@@ -2001,7 +2042,7 @@ - break; - case ASN_STRING_UniversalString: - OUT("{ APC_CONSTRAINED,\t32, 32," -- " 0, 2147483647 }" -+ " 0, 2147483647L }" - " /* special case 1 */\n"); - goto avoid; - default: -@@ -2454,9 +2495,13 @@ +@@ -1670,12 +1706,11 @@ + OUT("%d, ", tag2el[i].el_no); + OUT("%d, ", tag2el[i].toff_first); + OUT("%d ", tag2el[i].toff_last); +- OUT("}%s /* %s", ++ OUT("}%s /* %s at %d */\n", + (i + 1 < tag2el_count) ? "," : "", +- tag2el[i].from_expr->Identifier); +- if(arg->flags & A1C_LINE_REFS) +- OUT("at %d", tag2el[i].from_expr->_lineno); +- OUT(" */\n"); ++ tag2el[i].from_expr->Identifier, ++ tag2el[i].from_expr->_lineno ++ ); + } + OUT("};\n"); + +@@ -2111,19 +2146,22 @@ + try_inline_default(arg_t *arg, asn1p_expr_t *expr, int out) { + int save_target = arg->target->target; + asn1p_expr_type_e etype = expr_get_type(arg, expr); +- int fits_long = 0; ++// int fits_long = 0; ++ enum asn1c_fitslong_e fits = FL_NOTFIT; + + switch(etype) { + case ASN_BASIC_BOOLEAN: +- fits_long = 1; ++// fits_long = 1; ++ fits = FL_FITS_SIGNED; + case ASN_BASIC_INTEGER: + case ASN_BASIC_ENUMERATED: + if(expr->marker.default_value == NULL + || expr->marker.default_value->type != ATV_INTEGER) + break; +- if(!fits_long) +- fits_long = asn1c_type_fits_long(arg, expr)!=FL_NOTFIT; +- if(fits_long && !expr->marker.default_value->value.v_integer) ++ if(fits == FL_NOTFIT) ++// fits_long = asn1c_type_fits_long(arg, expr)!=FL_NOTFIT; ++ fits = asn1c_type_fits_long(arg, expr); ++ if(fits != FL_NOTFIT && !expr->marker.default_value->value.v_integer) + expr->marker.flags &= ~EM_INDIRECT; + if(!out) { + OUT("asn_DFL_%d_set_%" PRIdASN +@@ -2150,7 +2188,7 @@ + INDENT(+1); + OUT("/* Install default value %" PRIdASN " */\n", + expr->marker.default_value->value.v_integer); +- if(fits_long) { ++ if(fits != FL_NOTFIT) { + OUT("*st = "); + OINT(expr->marker.default_value->value.v_integer); + OUT(";\n"); +@@ -2165,7 +2203,7 @@ + INDENT(+1); + OUT("/* Test default value %" PRIdASN " */\n", + expr->marker.default_value->value.v_integer); +- if(fits_long) { ++ if(fits != FL_NOTFIT) { + OUT("return (*st == %" PRIdASN ");\n", + expr->marker.default_value->value.v_integer); + } else { +@@ -2455,9 +2493,13 @@ if(arg->flags & A1C_GEN_PER) { FUNCREF(decode_uper); FUNCREF(encode_uper); @@ -4212,29 +4926,157 @@ Index: libasn1compiler/asn1c_C.c } if(!terminal || terminal->expr_type == ASN_CONSTR_CHOICE) { +Index: libasn1compiler/asn1c_constraint.c +=================================================================== +--- libasn1compiler/asn1c_constraint.c (revision 1516) ++++ libasn1compiler/asn1c_constraint.c (working copy) +@@ -35,6 +35,7 @@ + int alphabet_table_compiled; + int produce_st = 0; + int ulong_optimize = 0; ++ enum asn1c_fitslong_e fits = FL_NOTFIT; + + ct = expr->combined_constraints; + if(ct == NULL) +@@ -74,7 +75,8 @@ + switch(etype) { + case ASN_BASIC_INTEGER: + case ASN_BASIC_ENUMERATED: +- if(asn1c_type_fits_long(arg, arg->expr) == FL_NOTFIT) ++ fits = asn1c_type_fits_long(arg, arg->expr); ++ if(fits == FL_NOTFIT) + produce_st = 1; + break; + case ASN_BASIC_REAL: +@@ -103,13 +105,19 @@ + switch(etype) { + case ASN_BASIC_INTEGER: + case ASN_BASIC_ENUMERATED: +- if(native_long_sign(r_value) >= 0) { +- ulong_optimize = ulong_optimization(etype, r_size, r_value); +- if(!ulong_optimize) { +- OUT("unsigned long value;\n"); ++ if(fits == FL_FITS_INT64) { ++ OUT("int64_t value;\n"); ++ } else if(fits == FL_FITS_UINT64) { ++ OUT("uint64_t value;\n"); ++ } else { ++ if(native_long_sign(r_value) >= 0) { ++ ulong_optimize = ulong_optimization(etype, r_size, r_value); ++ if(!ulong_optimize) { ++ OUT("unsigned long value;\n"); ++ } ++ } else { ++ OUT("long value;\n"); + } +- } else { +- OUT("long value;\n"); + } + break; + case ASN_BASIC_REAL: +@@ -603,13 +611,19 @@ + + static int + emit_value_determination_code(arg_t *arg, asn1p_expr_type_e etype, asn1cnst_range_t *r_value) { ++ enum asn1c_fitslong_e fits = FL_NOTFIT; + + switch(etype) { + case ASN_BASIC_INTEGER: + case ASN_BASIC_ENUMERATED: +- if(asn1c_type_fits_long(arg, arg->expr) == FL_FITS_UNSIGN) { ++ fits = asn1c_type_fits_long(arg, arg->expr); ++ if(fits == FL_FITS_INT64) { ++ OUT("value = *(const int64_t *)sptr;\n"); ++ } else if(fits == FL_FITS_UINT64) { ++ OUT("value = *(const uint64_t *)sptr;\n"); ++ } else if(fits == FL_FITS_UNSIGN) { + OUT("value = *(const unsigned long *)sptr;\n"); +- } else if(asn1c_type_fits_long(arg, arg->expr) != FL_NOTFIT) { ++ } else if(fits != FL_NOTFIT) { + OUT("value = *(const long *)sptr;\n"); + } else { + /* Index: libasn1compiler/asn1c_misc.c =================================================================== ---- libasn1compiler/asn1c_misc.c (revision 1410) +--- libasn1compiler/asn1c_misc.c (revision 1516) +++ libasn1compiler/asn1c_misc.c (working copy) -@@ -370,7 +370,7 @@ +@@ -158,6 +158,7 @@ + asn1p_expr_t *terminal; + int stdname = 0; + char *typename; ++ enum asn1c_fitslong_e fits; + + /* Rewind to the topmost parent expression */ + if((top_parent = expr->parent_expr)) +@@ -213,15 +214,20 @@ + case ASN_BASIC_INTEGER: + case ASN_BASIC_ENUMERATED: + case ASN_BASIC_REAL: ++ fits = asn1c_type_fits_long(arg, expr); + if((expr->expr_type == ASN_BASIC_REAL + && !(arg->flags & A1C_USE_WIDE_TYPES)) +- || asn1c_type_fits_long(arg, expr)) { ++ || (fits != FL_NOTFIT)) { + switch(_format) { + case TNF_CTYPE: + case TNF_RSAFE: + if(expr->expr_type == ASN_BASIC_REAL) + return "double"; +- else if(asn1c_type_fits_long(arg, expr) == FL_FITS_UNSIGN) ++ else if (fits == FL_FITS_INT64) ++ return "int64_t"; ++ else if (fits == FL_FITS_UINT64) ++ return "uint64_t"; ++ else if(fits == FL_FITS_UNSIGN) + return "unsigned long"; + else + return "long"; +@@ -377,11 +383,33 @@ + /* Special case for unsigned */ if(left.type == ARE_VALUE && left.value >= 0 - && right.type == ARE_VALUE -- && right.value > 2147483647 -+ && right.value > 2147483647L +- && right.type == ARE_VALUE ++ && right.type == ARE_VALUE + && right.value > 2147483647 && right.value <= 4294967295UL) return FL_FITS_UNSIGN; - -Index: asn1c/unber.c +- ++ /* Special for native 64 bits integer option */ ++ if (arg->flags & A1C_HAVE_NATIVE_64) { ++// printf("left.value %lld right.value %lld\n", left.value, right.value); ++ if(left.type == ARE_VALUE ++ && left.value >= 0 ++ && right.type == ARE_VALUE ++ && right.value > 9223372036854775807LL ++ && right.value <= 18446744073709551615ULL) ++ return FL_FITS_UINT64; ++ if(left.type == ARE_VALUE ++ && left.value < -2147483648 ++ && left.value >= -9223372036854775808LL ++ && right.type == ARE_VALUE ++ && right.value > 2147483647 ++ && right.value <= 9223372036854775807LL) ++ return FL_FITS_INT64; ++ if(left.type == ARE_VALUE ++ && left.value >= 0 ++ && right.type == ARE_VALUE ++ && right.value > 4294967295UL ++ && right.value <= 9223372036854775807LL) ++ return FL_FITS_INT64; ++ } + + /* If some fixed value is outside of target range, not fit */ + if(left.type == ARE_VALUE +Index: libasn1compiler/asn1c_misc.h =================================================================== ---- asn1c/unber.c (revision 1410) -+++ asn1c/unber.c (working copy) -@@ -772,4 +772,8 @@ - - asn_enc_rval_t OCTET_STRING_encode_uper(asn_TYPE_descriptor_t *td, asn_per_constraints_t *cts, void *sptr, asn_per_outp_t *po) { asn_enc_rval_t er = { 0, 0, 0 }; (void)td; (void)cts; (void)sptr; (void)po; return er; } - -+asn_dec_rval_t OCTET_STRING_decode_aper(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td, asn_per_constraints_t *cts, void **sptr, asn_per_data_t *pd) { asn_dec_rval_t rv = { 0, 0 }; (void)ctx; (void)td; (void)cts; (void)sptr; (void)pd; return rv; } -+ -+asn_enc_rval_t OCTET_STRING_encode_aper(asn_TYPE_descriptor_t *td, asn_per_constraints_t *cts, void *sptr, asn_per_outp_t *po) { asn_enc_rval_t er = { 0, 0, 0 }; (void)td; (void)cts; (void)sptr; (void)po; return er; } -+ - int xer_is_whitespace(const void *b, size_t s) { (void)b; (void)s; return 0; } +--- libasn1compiler/asn1c_misc.h (revision 1516) ++++ libasn1compiler/asn1c_misc.h (working copy) +@@ -36,6 +36,8 @@ + */ + enum asn1c_fitslong_e { + FL_NOTFIT, ++ FL_FITS_INT64, ++ FL_FITS_UINT64, + FL_FITS_SIGNED, + FL_FITS_UNSIGN, + FL_PRESUMED,