upgrade: PER related changes

diff --git a/skeletons/constr_CHOICE.c b/skeletons/constr_CHOICE.c
index 6ab4a0b..d3738df 100644
--- a/skeletons/constr_CHOICE.c
+++ b/skeletons/constr_CHOICE.c
@@ -118,7 +118,7 @@
 	ssize_t consumed_myself = 0;	/* Consumed bytes from ptr */
 
 	ASN_DEBUG("Decoding %s as CHOICE", td->name);
-	
+
 	/*
 	 * Create the target structure if it is not present already.
 	 */
@@ -196,7 +196,7 @@
 				NEXT_PHASE(ctx);
 				ctx->step = t2m->el_no;
 				break;
-			} else if(specs->extensible == 0) {
+			} else if(specs->ext_start == -1) {
 				ASN_DEBUG("Unexpected tag %s "
 					"in non-extensible CHOICE %s",
 					ber_tlv_tag_string(tlv_tag), td->name);
@@ -252,16 +252,16 @@
 			memb_ptr = (char *)st + elm->memb_offset;
 			memb_ptr2 = &memb_ptr;
 		}
+		/* Set presence to be able to free it properly at any time */
+		_set_present_idx(st, specs->pres_offset,
+				specs->pres_size, ctx->step + 1);
 		/*
 		 * Invoke the member fetch routine according to member's type
 		 */
 		rval = elm->type->ber_decoder(opt_codec_ctx, elm->type,
-				memb_ptr2, ptr, LEFT,
-				elm->tag_mode);
+				memb_ptr2, ptr, LEFT, elm->tag_mode);
 		switch(rval.code) {
 		case RC_OK:
-			_set_present_idx(st, specs->pres_offset,
-				specs->pres_size, ctx->step + 1);
 			break;
 		case RC_WMORE: /* More data expected */
 			if(!SIZE_VIOLATION) {
@@ -377,7 +377,7 @@
 		if(present == 0 && td->elements_count == 0) {
 			/* The CHOICE is empty?! */
 			erval.encoded = 0;
-			return erval;
+			_ASN_ENCODED_OK(erval);
 		}
 		_ASN_ENCODE_FAILED;
 	}
@@ -391,7 +391,7 @@
 		if(memb_ptr == 0) {
 			if(elm->optional) {
 				erval.encoded = 0;
-				return erval;
+				_ASN_ENCODED_OK(erval);
 			}
 			/* Mandatory element absent */
 			_ASN_ENCODE_FAILED;
@@ -729,7 +729,7 @@
 				continue;
 
 			/* It is expected extension */
-			if(specs->extensible) {
+			if(specs->ext_start != -1) {
 				ASN_DEBUG("Got anticipated extension");
 				/*
 				 * Check for (XCT_BOTH or XCT_UNKNOWN_BO)
@@ -810,11 +810,86 @@
 
 	if(!(flags & XER_F_CANONICAL)) _i_ASN_TEXT_INDENT(1, ilevel - 1);
 
-	return er;
+	_ASN_ENCODED_OK(er);
 cb_failed:
 	_ASN_ENCODE_FAILED;
 }
 
+asn_dec_rval_t
+CHOICE_decode_uper(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;
+
+	/*
+	 * 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_FAILED;
+		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_FAILED;
+		if(value > ct->upper_bound)
+			_ASN_DECODE_FAILED;
+		ASN_DEBUG("CHOICE %s got index %d in range %d",
+			td->name, value, ct->range_bits);
+	} else {
+		if(specs->ext_start == -1)
+			_ASN_DECODE_FAILED;
+		value = uper_get_nsnnwn(pd);
+		if(value < 0) _ASN_DECODE_FAILED;
+		value += specs->ext_start;
+		if(value >= td->elements_count)
+			_ASN_DECODE_FAILED;
+		ASN_DEBUG("NOT IMPLEMENTED YET");
+		_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);
+
+	rv = elm->type->uper_decoder(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)",
+			elm->name, td->name);
+	return rv;
+}
+   
+
 int
 CHOICE_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
 		asn_app_consume_bytes_f *cb, void *app_key) {