support parsing realnumber tokens in constraints


git-svn-id: https://asn1c.svn.sourceforge.net/svnroot/asn1c/trunk@1152 59561ff5-6e30-0410-9f3c-9617f08c8826
diff --git a/skeletons/constr_SET.c b/skeletons/constr_SET.c
index 6d2d6c1..b43f0a8 100644
--- a/skeletons/constr_SET.c
+++ b/skeletons/constr_SET.c
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2003, 2004, 2005 Lev Walkin <vlm@lionet.info>.
+ * Copyright (c) 2003, 2004, 2005, 2006 Lev Walkin <vlm@lionet.info>.
  * All rights reserved.
  * Redistribution and modifications are permitted subject to BSD license.
  */
@@ -121,7 +121,10 @@
 	int edx;			/* SET element's index */
 
 	ASN_DEBUG("Decoding %s as SET", td->name);
-	
+
+	if(_ASN_STACK_OVERFLOW_CHECK(opt_codec_ctx))
+		_ASN_DECODE_FAILED;
+
 	/*
 	 * Create the target structure if it is not present already.
 	 */
@@ -862,6 +865,144 @@
 	_ASN_ENCODE_FAILED;
 }
 
+asn_dec_rval_t
+SET_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_SET_specifics_t *specs = (asn_SET_specifics_t *)td->specifics;
+	void *st = *sptr;	/* Target structure. */
+	int extpresent = 0;	/* Extension additions are present */
+	uint8_t *opres;		/* Presence of optional root members */
+	asn_per_data_t opmd;
+	asn_dec_rval_t rv;
+	int edx;
+
+	(void)constraints;
+
+	ASN_DEBUG("Decoding %s as SET", td->name);
+
+	if(_ASN_STACK_OVERFLOW_CHECK(opt_codec_ctx))
+		_ASN_DECODE_FAILED;
+
+	if(!st) {
+		st = *sptr = CALLOC(1, specs->struct_size);
+		if(!st) _ASN_DECODE_FAILED;
+	}
+
+	ASN_DEBUG("Decoding %s as SEQUENCE (UPER)", td->name);
+
+	/* Handle extensions */
+	if(specs->ext_before >= 0) {
+		extpresent = per_get_few_bits(pd, 1);
+		if(extpresent < 0) _ASN_DECODE_FAILED;
+	}
+
+	/* Prepare a place and read-in the presence bitmap */
+	if(specs->roms_count) {
+		opres = (uint8_t *)MALLOC(((specs->roms_count + 7) >> 3) + 1);
+		if(!opres) _ASN_DECODE_FAILED;
+		/* Get the presence map */
+		if(per_get_many_bits(pd, opres, 0, specs->roms_count)) {
+			FREEMEM(opres);
+			_ASN_DECODE_FAILED;
+		}
+		opmd.buffer = opres;
+		opmd.nboff = 0;
+		opmd.nbits = specs->roms_count;
+		ASN_DEBUG("Read in presence bitmap for %s of %d bits (%x..)",
+			td->name, specs->roms_count, *opres);
+	} else {
+		opres = 0;
+		memset(&opmd, 0, sizeof opmd);
+	}
+
+	/*
+	 * Get the sequence ROOT elements.
+	 */
+	for(edx = 0; edx < ((specs->ext_before < 0)
+			? td->elements_count : specs->ext_before + 1); edx++) {
+		asn_TYPE_member_t *elm = &td->elements[edx];
+		void *memb_ptr;		/* Pointer to the member */
+		void **memb_ptr2;	/* Pointer to that pointer */
+
+		/* Fetch the pointer to this member */
+		if(elm->flags & ATF_POINTER) {
+			memb_ptr2 = (void **)((char *)st + elm->memb_offset);
+		} else {
+			memb_ptr = (char *)st + elm->memb_offset;
+			memb_ptr2 = &memb_ptr;
+		}
+
+		/* Deal with optionality */
+		if(elm->optional) {
+			int present = per_get_few_bits(&opmd, 1);
+			ASN_DEBUG("Member %s->%s is optional, p=%d (%d->%d)",
+				td->name, elm->name, present,
+				(int)opmd.nboff, (int)opmd.nbits);
+			if(present == 0) {
+				/* This element is not present */
+				if(elm->default_value) {
+					/* Fill-in DEFAULT */
+					if(elm->default_value(1, memb_ptr2)) {
+						FREEMEM(opres);
+						_ASN_DECODE_FAILED;
+					}
+				}
+				/* The member is just not present */
+				continue;
+			}
+			/* Fall through */
+		}
+
+		/* Fetch the member from the stream */
+		ASN_DEBUG("Decoding member %s in %s", elm->name, td->name);
+		rv = elm->type->uper_decoder(opt_codec_ctx, elm->type,
+			elm->per_constraints, memb_ptr2, pd);
+		if(rv.code != RC_OK) {
+			ASN_DEBUG("Failed decode %s in %s",
+				elm->name, td->name);
+			FREEMEM(opres);
+			return rv;
+		}
+	}
+
+	/*
+	 * Deal with extensions.
+	 */
+	if(extpresent) {
+		ASN_DEBUG("Extensibility for %s: NOT IMPLEMENTED", td->name);
+		_ASN_DECODE_FAILED;
+	} else {
+		for(edx = specs->roms_count; edx < specs->roms_count
+				+ specs->aoms_count; edx++) {
+			asn_TYPE_member_t *elm = &td->elements[edx];
+			void *memb_ptr;		/* Pointer to the member */
+			void **memb_ptr2;	/* Pointer to that 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);
+			} else {
+				memb_ptr = (char *)st + elm->memb_offset;
+				memb_ptr2 = &memb_ptr;
+			}
+
+			/* Set default value */
+			if(elm->default_value(1, memb_ptr2)) {
+				FREEMEM(opres);
+				_ASN_DECODE_FAILED;
+			}
+		}
+	}
+
+	rv.consumed = 0;
+	rv.code = RC_OK;
+	FREEMEM(opres);
+	return rv;
+}
+
 int
 SET_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
 		asn_app_consume_bytes_f *cb, void *app_key) {
diff --git a/skeletons/constr_SET.h b/skeletons/constr_SET.h
index 3adfb33..0c78ed5 100644
--- a/skeletons/constr_SET.h
+++ b/skeletons/constr_SET.h
@@ -52,6 +52,8 @@
 der_type_encoder_f SET_encode_der;
 xer_type_decoder_f SET_decode_xer;
 xer_type_encoder_f SET_encode_xer;
+per_type_decoder_f SET_decode_uper;
+per_type_encoder_f SET_encode_uper;
 
 /***********************
  * Some handy helpers. *