update to asn1c aper branch commit 6e00cbce7304a6972e82a12bb5fa82e41fa541be

which is closes to Lev Walkins master 62913d8b8e1eb96d74315ff748475ca818b69752
diff --git a/include/asn1c/ANY.h b/include/asn1c/ANY.h
index b7d92fa..a68441d 100644
--- a/include/asn1c/ANY.h
+++ b/include/asn1c/ANY.h
@@ -32,10 +32,13 @@
 
 /* Convert another ASN.1 type into the ANY. This implies DER encoding. */
 int ANY_fromType(ANY_t *, asn_TYPE_descriptor_t *td, void *struct_ptr);
+int ANY_fromType_aper(ANY_t *st, asn_TYPE_descriptor_t *td, void *sptr);
 ANY_t *ANY_new_fromType(asn_TYPE_descriptor_t *td, void *struct_ptr);
+ANY_t *ANY_new_fromType_aper(asn_TYPE_descriptor_t *td, void *sptr);
 
 /* Convert the contents of the ANY type into the specified type. */
 int ANY_to_type(ANY_t *, asn_TYPE_descriptor_t *td, void **struct_ptr);
+int ANY_to_type_aper(ANY_t *, asn_TYPE_descriptor_t *td, void **struct_ptr);
 
 #define	ANY_fromBuf(s, buf, size)	OCTET_STRING_fromBuf((s), (buf), (size))
 #define	ANY_new_fromBuf(buf, size)	OCTET_STRING_new_fromBuf(	\
diff --git a/include/asn1c/BOOLEAN.h b/include/asn1c/BOOLEAN.h
index 217d0f1..8ea2892 100644
--- a/include/asn1c/BOOLEAN.h
+++ b/include/asn1c/BOOLEAN.h
@@ -28,6 +28,8 @@
 xer_type_encoder_f BOOLEAN_encode_xer;
 per_type_decoder_f BOOLEAN_decode_uper;
 per_type_encoder_f BOOLEAN_encode_uper;
+per_type_decoder_f BOOLEAN_decode_aper;
+per_type_encoder_f BOOLEAN_encode_aper;
 
 #ifdef __cplusplus
 }
diff --git a/include/asn1c/ENUMERATED.h b/include/asn1c/ENUMERATED.h
index 542dcae..5c4a2ed 100644
--- a/include/asn1c/ENUMERATED.h
+++ b/include/asn1c/ENUMERATED.h
@@ -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
 }
diff --git a/include/asn1c/INTEGER.h b/include/asn1c/INTEGER.h
index 8411bfc..e8b36c7 100644
--- a/include/asn1c/INTEGER.h
+++ b/include/asn1c/INTEGER.h
@@ -18,15 +18,15 @@
 
 /* Map with <tag> 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;
 
 /* This type describes an enumeration for INTEGER and ENUMERATED types */
-typedef struct asn_INTEGER_specifics_s {
-	asn_INTEGER_enum_map_t *value2enum;	/* N -> "tag"; sorted by N */
-	unsigned int *enum2value;		/* "tag" => N; sorted by tag */
+typedef const struct asn_INTEGER_specifics_s {
+	const asn_INTEGER_enum_map_t *value2enum;	/* N -> "tag"; sorted by N */
+	const unsigned int *enum2value;		/* "tag" => N; sorted by tag */
 	int map_count;				/* Elements in either map */
 	int extension;				/* This map is extensible */
 	int strict_enumeration;			/* Enumeration set is fixed */
@@ -41,6 +41,8 @@
 xer_type_encoder_f INTEGER_encode_xer;
 per_type_decoder_f INTEGER_decode_uper;
 per_type_encoder_f INTEGER_encode_uper;
+per_type_decoder_f INTEGER_decode_aper;
+per_type_encoder_f INTEGER_encode_aper;
 
 /***********************************
  * Some handy conversion routines. *
@@ -52,11 +54,28 @@
  * -1/ERANGE: Value encoded is out of range for long representation
  * -1/ENOMEM: Memory allocation failed (in asn_long2INTEGER()).
  */
+int asn_INTEGER2int64(const INTEGER_t *i, int64_t *l);
+int asn_INTEGER2uint64(const INTEGER_t *i, uint64_t *l);
 int asn_INTEGER2long(const INTEGER_t *i, long *l);
 int asn_INTEGER2ulong(const INTEGER_t *i, unsigned long *l);
+int asn_int642INTEGER(INTEGER_t *i, int64_t l);
+int asn_uint642INTEGER(INTEGER_t *i, uint64_t l);
 int asn_long2INTEGER(INTEGER_t *i, long l);
 int asn_ulong2INTEGER(INTEGER_t *i, unsigned long l);
 
+/* A a reified version of strtol(3) with nicer error reporting. */
+enum asn_strtol_result_e {
+    ASN_STRTOL_ERROR_RANGE = -3,  /* Input outside of numeric range for long type */
+    ASN_STRTOL_ERROR_INVAL = -2,  /* Invalid data encountered (e.g., "+-") */
+    ASN_STRTOL_EXPECT_MORE = -1,  /* More data expected (e.g. "+") */
+    ASN_STRTOL_OK          =  0,  /* Conversion succeded, number ends at (*end) */
+    ASN_STRTOL_EXTRA_DATA  =  1,  /* Conversion succeded, but the string has extra stuff */
+};
+enum asn_strtol_result_e asn_strtol_lim(const char *str, const char **end, long *l);
+
+/* The asn_strtol is going to be DEPRECATED soon */
+enum asn_strtol_result_e asn_strtol(const char *str, const char *end, long *l);
+
 /*
  * Convert the integer value into the corresponding enumeration map entry.
  */
diff --git a/include/asn1c/NULL.h b/include/asn1c/NULL.h
index 131e775..90784d8 100644
--- a/include/asn1c/NULL.h
+++ b/include/asn1c/NULL.h
@@ -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
 }
diff --git a/include/asn1c/NativeEnumerated.h b/include/asn1c/NativeEnumerated.h
index b5acc71..9db2611 100644
--- a/include/asn1c/NativeEnumerated.h
+++ b/include/asn1c/NativeEnumerated.h
@@ -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;
 asn_struct_print_f NativeEnumerated_print;
 
 #ifdef __cplusplus
diff --git a/include/asn1c/NativeInteger.h b/include/asn1c/NativeInteger.h
index 4e63a83..14aa1a4 100644
--- a/include/asn1c/NativeInteger.h
+++ b/include/asn1c/NativeInteger.h
@@ -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
 }
diff --git a/include/asn1c/NativeReal.h b/include/asn1c/NativeReal.h
index 68a81d9..94ed9de 100644
--- a/include/asn1c/NativeReal.h
+++ b/include/asn1c/NativeReal.h
@@ -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
 }
diff --git a/include/asn1c/OBJECT_IDENTIFIER.h b/include/asn1c/OBJECT_IDENTIFIER.h
index 2bb5d03..c2c6373 100644
--- a/include/asn1c/OBJECT_IDENTIFIER.h
+++ b/include/asn1c/OBJECT_IDENTIFIER.h
@@ -68,7 +68,7 @@
  * WARNING: The function always returns the real number of arcs,
  * even if there is no sufficient (_arc_slots) provided.
  */
-int OBJECT_IDENTIFIER_get_arcs(OBJECT_IDENTIFIER_t *_oid,
+int OBJECT_IDENTIFIER_get_arcs(const OBJECT_IDENTIFIER_t *_oid,
 	void *_arcs,			/* e.g., unsigned int arcs[N] */
 	unsigned int _arc_type_size,	/* e.g., sizeof(arcs[0]) */
 	unsigned int _arc_slots		/* e.g., N */);
@@ -91,12 +91,12 @@
 /*
  * Print the specified OBJECT IDENTIFIER arc.
  */
-int OBJECT_IDENTIFIER_print_arc(uint8_t *arcbuf, int arclen,
+int OBJECT_IDENTIFIER_print_arc(const uint8_t *arcbuf, int arclen,
 	int add, /* Arbitrary offset, required to process the first two arcs */
 	asn_app_consume_bytes_f *cb, void *app_key);
 
 /* Same as above, but returns the number of written digits, instead of 0 */
-ssize_t OBJECT_IDENTIFIER__dump_arc(uint8_t *arcbuf, int arclen, int add,
+ssize_t OBJECT_IDENTIFIER__dump_arc(const uint8_t *arcbuf, int arclen, int add,
 	asn_app_consume_bytes_f *cb, void *app_key);
 
 /*
@@ -127,7 +127,7 @@
  * Internal functions.
  * Used by RELATIVE-OID implementation in particular.
  */
-int OBJECT_IDENTIFIER_get_single_arc(uint8_t *arcbuf, unsigned int arclen,
+int OBJECT_IDENTIFIER_get_single_arc(const uint8_t *arcbuf, unsigned int arclen,
 	signed int add, void *value, unsigned int value_size);
 int OBJECT_IDENTIFIER_set_single_arc(uint8_t *arcbuf,
 	const void *arcval, unsigned int arcval_size, int _prepared_order);
diff --git a/include/asn1c/OCTET_STRING.h b/include/asn1c/OCTET_STRING.h
index 8df9a18..bc25666 100644
--- a/include/asn1c/OCTET_STRING.h
+++ b/include/asn1c/OCTET_STRING.h
@@ -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. *
@@ -63,7 +65,7 @@
  * Internally useful stuff. *
  ****************************/
 
-typedef struct asn_OCTET_STRING_specifics_s {
+typedef const struct asn_OCTET_STRING_specifics_s {
 	/*
 	 * Target structure description.
 	 */
diff --git a/include/asn1c/REAL.h b/include/asn1c/REAL.h
index af3e84c..503e254 100644
--- a/include/asn1c/REAL.h
+++ b/include/asn1c/REAL.h
@@ -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. *
diff --git a/include/asn1c/RELATIVE-OID.h b/include/asn1c/RELATIVE-OID.h
index 2235cfd..65acaab 100644
--- a/include/asn1c/RELATIVE-OID.h
+++ b/include/asn1c/RELATIVE-OID.h
@@ -25,7 +25,7 @@
  **********************************/
 
 /* See OBJECT_IDENTIFIER_get_arcs() function in OBJECT_IDENTIFIER.h */
-int RELATIVE_OID_get_arcs(RELATIVE_OID_t *_roid,
+int RELATIVE_OID_get_arcs(const RELATIVE_OID_t *_roid,
 	void *arcs, unsigned int arc_type_size, unsigned int arc_slots);
 
 /* See OBJECT_IDENTIFIER_set_arcs() function in OBJECT_IDENTIFIER.h */
diff --git a/include/asn1c/asn_codecs.h b/include/asn1c/asn_codecs.h
index 4a251d9..e560014 100644
--- a/include/asn1c/asn_codecs.h
+++ b/include/asn1c/asn_codecs.h
@@ -62,7 +62,7 @@
 	tmp_error.encoded = -1;					\
 	tmp_error.failed_type = td;				\
 	tmp_error.structure_ptr = sptr;				\
-	ASN_DEBUG("Failed to encode element %s", td->name);	\
+	ASN_DEBUG("Failed to encode element %s", td ? td->name : "");	\
 	return tmp_error;					\
 } while(0)
 #define	_ASN_ENCODED_OK(rval) do {				\
@@ -92,7 +92,7 @@
 	asn_dec_rval_t tmp_error;				\
 	tmp_error.code = RC_FAIL;				\
 	tmp_error.consumed = 0;					\
-	ASN_DEBUG("Failed to decode element %s", td->name);	\
+	ASN_DEBUG("Failed to decode element %s", td ? td->name : "");	\
 	return tmp_error;					\
 } while(0)
 #define	_ASN_DECODE_STARVED do {				\
diff --git a/include/asn1c/asn_internal.h b/include/asn1c/asn_internal.h
index e6da3fe..58b4583 100644
--- a/include/asn1c/asn_internal.h
+++ b/include/asn1c/asn_internal.h
@@ -22,7 +22,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 */
 
 extern void *talloc_asn1_ctx;
@@ -32,6 +32,9 @@
 #define	REALLOC(oldptr, size)	talloc_realloc_size(talloc_asn1_ctx, oldptr, size)
 #define	FREEMEM(ptr)		talloc_free(ptr)
 
+#define	asn_debug_indent	0
+#define ASN_DEBUG_INDENT_ADD(i) do{}while(0)
+
 /*
  * A macro for debugging the ASN.1 internals.
  * You may enable or override it.
@@ -40,17 +43,25 @@
 #if	EMIT_ASN_DEBUG == 1	/* And it was asked to emit this code... */
 #ifdef	__GNUC__
 #ifdef	ASN_THREAD_SAFE
-#define	asn_debug_indent	0
+/* Thread safety requires sacrifice in output indentation:
+ * Retain empty definition of ASN_DEBUG_INDENT_ADD. */
 #else	/* !ASN_THREAD_SAFE */
+#undef  ASN_DEBUG_INDENT_ADD
+#undef  asn_debug_indent
 int asn_debug_indent;
+#define ASN_DEBUG_INDENT_ADD(i) do { asn_debug_indent += i; } while(0)
 #endif	/* ASN_THREAD_SAFE */
-#define	ASN_DEBUG(fmt, args...)	do {			\
+extern int asn_debug; /* Allow option on execution */
+#define	ASN_DEBUG(fmt, args...) \
+if (asn_debug) {    \
+    do {			\
 		int adi = asn_debug_indent;		\
 		while(adi--) fprintf(stderr, " ");	\
 		fprintf(stderr, fmt, ##args);		\
 		fprintf(stderr, " (%s:%d)\n",		\
 			__FILE__, __LINE__);		\
-	} while(0)
+	} while(0);  \
+}
 #else	/* !__GNUC__ */
 void ASN_DEBUG_f(const char *fmt, ...);
 #define	ASN_DEBUG	ASN_DEBUG_f
diff --git a/include/asn1c/asn_system.h b/include/asn1c/asn_system.h
index 0a9b092..e420ad2 100644
--- a/include/asn1c/asn_system.h
+++ b/include/asn1c/asn_system.h
@@ -21,7 +21,7 @@
 #include <stdarg.h>	/* For va_start */
 #include <stddef.h>	/* for offsetof and ptrdiff_t */
 
-#ifdef	WIN32
+#ifdef	_WIN32
 
 #include <malloc.h>
 #define	 snprintf	_snprintf
@@ -29,9 +29,9 @@
 
 /* To avoid linking with ws2_32.lib, here's the definition of ntohl() */
 #define sys_ntohl(l)	((((l) << 24)  & 0xff000000)	\
-			| (((l) << 16) & 0xff0000)	\
-			| (((l) << 8)  & 0xff00)	\
-			| ((l) & 0xff))
+			| (((l) << 8) & 0xff0000)	\
+			| (((l) >> 8)  & 0xff00)	\
+			| ((l >> 24) & 0xff))
 
 #ifdef _MSC_VER			/* MSVS.Net */
 #ifndef __cplusplus
@@ -57,7 +57,7 @@
 #include <stdint.h>
 #endif	/* _MSC_VER */
 
-#else	/* !WIN32 */
+#else	/* !_WIN32 */
 
 #if defined(__vxworks)
 #include <types/vxTypes.h>
@@ -90,7 +90,7 @@
 
 #endif	/* defined(__vxworks) */
 
-#endif	/* WIN32 */
+#endif	/* _WIN32 */
 
 #if	__GNUC__ >= 3
 #ifndef	GCC_PRINTFLIKE
diff --git a/include/asn1c/constr_CHOICE.h b/include/asn1c/constr_CHOICE.h
index 83404e6..ddcbb39 100644
--- a/include/asn1c/constr_CHOICE.h
+++ b/include/asn1c/constr_CHOICE.h
@@ -12,7 +12,7 @@
 extern "C" {
 #endif
 
-typedef struct asn_CHOICE_specifics_s {
+typedef const struct asn_CHOICE_specifics_s {
 	/*
 	 * Target structure description.
 	 */
@@ -24,7 +24,7 @@
 	/*
 	 * Tags to members mapping table.
 	 */
-	asn_TYPE_tag2member_t *tag2el;
+	const asn_TYPE_tag2member_t *tag2el;
 	int tag2el_count;
 
 	/* Canonical ordering of CHOICE elements, for PER */
@@ -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
diff --git a/include/asn1c/constr_SEQUENCE.h b/include/asn1c/constr_SEQUENCE.h
index 5f589d5..d181848 100644
--- a/include/asn1c/constr_SEQUENCE.h
+++ b/include/asn1c/constr_SEQUENCE.h
@@ -11,7 +11,7 @@
 extern "C" {
 #endif
 
-typedef struct asn_SEQUENCE_specifics_s {
+typedef const struct asn_SEQUENCE_specifics_s {
 	/*
 	 * Target structure description.
 	 */
@@ -21,14 +21,14 @@
 	/*
 	 * Tags to members mapping table (sorted).
 	 */
-	asn_TYPE_tag2member_t *tag2el;
+	const asn_TYPE_tag2member_t *tag2el;
 	int tag2el_count;
 
 	/*
 	 * Optional members of the extensions root (roms) or additions (aoms).
 	 * Meaningful for PER.
 	 */
-	int *oms;		/* Optional MemberS */
+	const int *oms;		/* Optional MemberS */
 	int  roms_count;	/* Root optional members count */
 	int  aoms_count;	/* Additions optional members count */
 
@@ -52,6 +52,8 @@
 xer_type_encoder_f SEQUENCE_encode_xer;
 per_type_decoder_f SEQUENCE_decode_uper;
 per_type_encoder_f SEQUENCE_encode_uper;
+per_type_decoder_f SEQUENCE_decode_aper;
+per_type_encoder_f SEQUENCE_encode_aper;
 
 #ifdef __cplusplus
 }
diff --git a/include/asn1c/constr_SEQUENCE_OF.h b/include/asn1c/constr_SEQUENCE_OF.h
index e2272f3..94a7cd5 100644
--- a/include/asn1c/constr_SEQUENCE_OF.h
+++ b/include/asn1c/constr_SEQUENCE_OF.h
@@ -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
 }
diff --git a/include/asn1c/constr_SET.h b/include/asn1c/constr_SET.h
index 0c78ed5..11b7153 100644
--- a/include/asn1c/constr_SET.h
+++ b/include/asn1c/constr_SET.h
@@ -12,7 +12,7 @@
 #endif
 
 
-typedef struct asn_SET_specifics_s {
+typedef const struct asn_SET_specifics_s {
 	/*
 	 * Target structure description.
 	 */
@@ -25,21 +25,21 @@
 	 * Sometimes suitable for DER encoding (untagged CHOICE is present);
 	 * if so, tag2el_count will be greater than td->elements_count.
 	 */
-	asn_TYPE_tag2member_t *tag2el;
+	const asn_TYPE_tag2member_t *tag2el;
 	int tag2el_count;
 
 	/*
 	 * Tags to members mapping table, second edition.
 	 * Suitable for CANONICAL-XER encoding.
 	 */
-	asn_TYPE_tag2member_t *tag2el_cxer;
+	const asn_TYPE_tag2member_t *tag2el_cxer;
 	int tag2el_cxer_count;
 
 	/*
 	 * Extensions-related stuff.
 	 */
 	int extensible;				/* Whether SET is extensible */
-	unsigned int *_mandatory_elements;	/* Bitmask of mandatory ones */
+	const unsigned int *_mandatory_elements;	/* Bitmask of mandatory ones */
 } asn_SET_specifics_t;
 
 /*
@@ -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. *
diff --git a/include/asn1c/constr_SET_OF.h b/include/asn1c/constr_SET_OF.h
index bcd0966..8ddd0e3 100644
--- a/include/asn1c/constr_SET_OF.h
+++ b/include/asn1c/constr_SET_OF.h
@@ -11,7 +11,7 @@
 extern "C" {
 #endif
 
-typedef struct asn_SET_OF_specifics_s {
+typedef const struct asn_SET_OF_specifics_s {
 	/*
 	 * Target structure description.
 	 */
@@ -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
 }
diff --git a/include/asn1c/constr_TYPE.h b/include/asn1c/constr_TYPE.h
index 95507c8..13c60f3 100644
--- a/include/asn1c/constr_TYPE.h
+++ b/include/asn1c/constr_TYPE.h
@@ -73,7 +73,7 @@
  * Do not use it in your application.
  */
 typedef ber_tlv_tag_t (asn_outmost_tag_f)(
-		struct asn_TYPE_descriptor_s *type_descriptor,
+		const struct asn_TYPE_descriptor_s *type_descriptor,
 		const void *struct_ptr, int tag_mode, ber_tlv_tag_t tag);
 /* The instance of the above function type; used internally. */
 asn_outmost_tag_f asn_TYPE_outmost_tag;
@@ -83,8 +83,8 @@
  * The definitive description of the destination language's structure.
  */
 typedef struct asn_TYPE_descriptor_s {
-	char *name;	/* A name of the ASN.1 type. "" in some cases. */
-	char *xml_tag;	/* Name used in XML tag */
+	const char *name;	/* A name of the ASN.1 type. "" in some cases. */
+	const char *xml_tag;	/* Name used in XML tag */
 
 	/*
 	 * Generalized functions for dealing with the specific type.
@@ -99,6 +99,8 @@
 	xer_type_encoder_f *xer_encoder;	/* [Canonical] XER encoder */
 	per_type_decoder_f *uper_decoder;	/* Unaligned PER decoder */
 	per_type_encoder_f *uper_encoder;	/* Unaligned PER encoder */
+	per_type_decoder_f *aper_decoder;	/* Aligned PER decoder */
+	per_type_encoder_f *aper_encoder;	/* Aligned PER encoder */
 
 	/***********************************************************************
 	 * Internally useful members. Not to be used by applications directly. *
@@ -108,10 +110,10 @@
 	 * Tags that are expected to occur.
 	 */
 	asn_outmost_tag_f  *outmost_tag;	/* <optional, internal> */
-	ber_tlv_tag_t *tags;	/* Effective tags sequence for this type */
-	int tags_count;		/* Number of tags which are expected */
-	ber_tlv_tag_t *all_tags;/* Every tag for BER/containment */
-	int all_tags_count;	/* Number of tags */
+	const ber_tlv_tag_t *tags;	/* Effective tags sequence for this type */
+	int tags_count;			/* Number of tags which are expected */
+	const ber_tlv_tag_t *all_tags;	/* Every tag for BER/containment */
+	int all_tags_count;		/* Number of tags */
 
 	asn_per_constraints_t *per_constraints;	/* PER compiled constraints */
 
@@ -125,7 +127,7 @@
 	 * Additional information describing the type, used by appropriate
 	 * functions above.
 	 */
-	void *specifics;
+	const void *specifics;
 } asn_TYPE_descriptor_t;
 
 /*
@@ -147,7 +149,7 @@
 	asn_constr_check_f *memb_constraints;	/* Constraints validator */
 	asn_per_constraints_t *per_constraints;	/* PER compiled constraints */
 	int (*default_value)(int setval, void **sptr);	/* DEFAULT <value> */
-	char *name;			/* ASN.1 identifier of the element */
+	const char *name;			/* ASN.1 identifier of the element */
 } asn_TYPE_member_t;
 
 /*
diff --git a/include/asn1c/per_decoder.h b/include/asn1c/per_decoder.h
index 8397a54..5541bae 100644
--- a/include/asn1c/per_decoder.h
+++ b/include/asn1c/per_decoder.h
@@ -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,
diff --git a/include/asn1c/per_encoder.h b/include/asn1c/per_encoder.h
index 95a6506..e3b9190 100644
--- a/include/asn1c/per_encoder.h
+++ b/include/asn1c/per_encoder.h
@@ -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.
  */
diff --git a/include/asn1c/per_opentype.h b/include/asn1c/per_opentype.h
index facfaa6..2117efe 100644
--- a/include/asn1c/per_opentype.h
+++ b/include/asn1c/per_opentype.h
@@ -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
diff --git a/include/asn1c/per_support.h b/include/asn1c/per_support.h
index 7cb1a0c..181fe24 100644
--- a/include/asn1c/per_support.h
+++ b/include/asn1c/per_support.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2006, 2007 Lev Walkin <vlm@lionet.info>.
+ * Copyright (c) 2005-2014 Lev Walkin <vlm@lionet.info>.
  * All rights reserved.
  * Redistribution and modifications are permitted subject to BSD license.
  */
@@ -15,7 +15,7 @@
 /*
  * Pre-computed PER constraints.
  */
-typedef struct asn_per_constraint_s {
+typedef const struct asn_per_constraint_s {
 	enum asn_per_constraint_flags {
 		APC_UNCONSTRAINED	= 0x0,	/* No PER visible constraints */
 		APC_SEMI_CONSTRAINED	= 0x1,	/* Constrained at "lb" */
@@ -24,12 +24,12 @@
 	} flags;
 	int  range_bits;		/* Full number of bits in the range */
 	int  effective_bits;		/* Effective bits */
-	long lower_bound;		/* "lb" value */
-	long upper_bound;		/* "ub" value */
+	int64_t lower_bound;		/* "lb" value */
+	int64_t upper_bound;		/* "ub" value */
 } asn_per_constraint_t;
-typedef struct asn_per_constraints_s {
-	asn_per_constraint_t value;
-	asn_per_constraint_t size;
+typedef const struct asn_per_constraints_s {
+	struct asn_per_constraint_s value;
+	struct asn_per_constraint_s size;
 	int (*value2code)(unsigned int value);
 	int (*code2value)(unsigned int code);
 } asn_per_constraints_t;
@@ -39,9 +39,9 @@
  */
 typedef struct asn_per_data_s {
   const uint8_t *buffer;  /* Pointer to the octet stream */
-         size_t  nboff;   /* Bit offset to the meaningful bit */
-         size_t  nbits;   /* Number of bits in the stream */
-         size_t  moved;   /* Number of bits moved through this bit stream */
+		 size_t  nboff;   /* Bit offset to the meaningful bit */
+		 size_t  nbits;   /* Number of bits in the stream */
+		 size_t  moved;   /* Number of bits moved through this bit stream */
   int (*refill)(struct asn_per_data_s *);
   void *refill_key;
 } asn_per_data_t;
@@ -71,15 +71,25 @@
 			int effective_bound_bits,
 			int *repeat);
 
+ssize_t aper_get_length(asn_per_data_t *pd,
+						int range,
+						int effective_bound_bits,
+						int *repeat);
+
 /*
  * Get the normally small length "n".
  */
 ssize_t uper_get_nslength(asn_per_data_t *pd);
+ssize_t aper_get_nslength(asn_per_data_t *pd);
 
 /*
  * Get the normally small non-negative whole number.
  */
 ssize_t uper_get_nsnnwn(asn_per_data_t *pd);
+ssize_t aper_get_nsnnwn(asn_per_data_t *pd, int range);
+
+/* X.691-2008/11, #11.5.6 */
+int uper_get_constrained_whole_number(asn_per_data_t *pd, unsigned long *v, int nbits);
 
 /* Non-thread-safe debugging function, don't use it */
 char *per_data_string(asn_per_data_t *pd);
@@ -103,6 +113,14 @@
 /* Output a large number of bits */
 int per_put_many_bits(asn_per_outp_t *po, const uint8_t *src, int put_nbits);
 
+/* X.691-2008/11, #11.5 */
+int uper_put_constrained_whole_number_s(asn_per_outp_t *po, long v, int nbits);
+int uper_put_constrained_whole_number_u(asn_per_outp_t *po, unsigned long v, int nbits);
+
+/* Align the current bit position to octet bundary */
+int aper_put_align(asn_per_outp_t *po);
+int32_t aper_get_align(asn_per_data_t *pd);
+
 /*
  * Put the length "n" to the Unaligned PER stream.
  * This function returns the number of units which may be flushed
@@ -110,17 +128,23 @@
  */
 ssize_t uper_put_length(asn_per_outp_t *po, size_t whole_length);
 
+ssize_t aper_put_length(asn_per_outp_t *po, int range, size_t length);
+
 /*
  * Put the normally small length "n" to the Unaligned PER stream.
  * Returns 0 or -1.
  */
 int uper_put_nslength(asn_per_outp_t *po, size_t length);
 
+int aper_put_nslength(asn_per_outp_t *po, size_t length);
+
 /*
  * Put the normally small non-negative whole number.
  */
 int uper_put_nsnnwn(asn_per_outp_t *po, int n);
 
+int aper_put_nsnnwn(asn_per_outp_t *po, int range, int number);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/asn1c/xer_decoder.h b/include/asn1c/xer_decoder.h
index cf0d846..6988648 100644
--- a/include/asn1c/xer_decoder.h
+++ b/include/asn1c/xer_decoder.h
@@ -87,12 +87,11 @@
 		const char *need_tag);
 
 /*
- * Check whether this buffer consists of entirely XER whitespace characters.
+ * Get the number of bytes consisting entirely of XER whitespace characters.
  * RETURN VALUES:
- * 1:	Whitespace or empty string
- * 0:	Non-whitespace
+ * >=0:	Number of whitespace characters in the string.
  */
-int xer_is_whitespace(const void *chunk_buf, size_t chunk_size);
+size_t xer_whitespace_span(const void *chunk_buf, size_t chunk_size);
 
 /*
  * Skip the series of anticipated extensions.