extensions support


git-svn-id: https://asn1c.svn.sourceforge.net/svnroot/asn1c/trunk@668 59561ff5-6e30-0410-9f3c-9617f08c8826
diff --git a/skeletons/constr_SET.c b/skeletons/constr_SET.c
index 120acb2..c5bb201 100644
--- a/skeletons/constr_SET.c
+++ b/skeletons/constr_SET.c
@@ -600,7 +600,6 @@
 
 	asn_dec_rval_t rval;		/* Return value from a decoder */
 	ssize_t consumed_myself = 0;	/* Consumed bytes from ptr */
-	int xer_state;			/* XER low level parsing context */
 	int edx;			/* Element index */
 
 	/*
@@ -621,8 +620,10 @@
 	 * Phase 0: Check that the opening tag matches our expectations.
 	 * Phase 1: Processing body and reacting on closing tag.
 	 * Phase 2: Processing inner type.
+	 * Phase 3: Skipping unknown extensions.
+	 * Phase 4: PHASED OUT
 	 */
-	for(xer_state = ctx->left, edx = ctx->step; ctx->phase <= 2;) {
+	for(edx = ctx->step; ctx->phase <= 3;) {
 		pxer_chunk_type_e ch_type;	/* XER chunk type */
 		ssize_t ch_size;		/* Chunk size */
 		xer_check_tag_e tcv;		/* Tag check value */
@@ -662,7 +663,6 @@
 			if(tmprval.code != RC_OK)
 				RETURN(tmprval.code);
 			ctx->phase = 1;	/* Back to body processing */
-			ctx->left = xer_state = 0;	/* New, clean state */
 			ASN_SET_MKPRESENT((char *)st + specs->pres_offset, edx);
 			ASN_DEBUG("XER/SET phase => %d", ctx->phase);
 			/* Fall through */
@@ -671,12 +671,10 @@
 		/*
 		 * Get the next part of the XML stream.
 		 */
-		ch_size = xer_next_token(&xer_state, buf_ptr, size, &ch_type);
+		ch_size = xer_next_token(buf_ptr, size, &ch_type);
 		switch(ch_size) {
 		case -1: RETURN(RC_FAIL);
-		case 0:
-			ctx->left = xer_state;
-			RETURN(RC_WMORE);
+		case 0:  RETURN(RC_WMORE);
 		default:
 			switch(ch_type) {
 			case PXER_COMMENT:	/* Got XML comment */
@@ -690,6 +688,26 @@
 
 		tcv = xer_check_tag(buf_ptr, ch_size, xml_tag);
 		ASN_DEBUG("XER/SET: tcv = %d, ph=%d", tcv, ctx->phase);
+
+		/* Skip the extensions section */
+		if(ctx->phase == 3) {
+			switch(xer_skip_unknown(tcv, &ctx->left)) {
+			case -1:
+				ctx->phase = 4;
+				RETURN(RC_FAIL);
+			case 0:
+				XER_ADVANCE(ch_size);
+				continue;
+			case 1:
+				XER_ADVANCE(ch_size);
+				ctx->phase = 1;
+				continue;
+			case 2:
+				ctx->phase = 1;
+				break;
+			}
+		}
+
 		switch(tcv) {
 		case XCT_CLOSING:
 			if(ctx->phase == 0) break;
@@ -699,7 +717,7 @@
 			if(ctx->phase == 0) {
 				if(_SET_is_populated(td, st)) {
 					XER_ADVANCE(ch_size);
-					ctx->phase = 3;	/* Phase out */
+					ctx->phase = 4;	/* Phase out */
 					RETURN(RC_OK);
 				} else {
 					ASN_DEBUG("Premature end of XER SET");
@@ -725,9 +743,8 @@
 			 * Search which member corresponds to this tag.
 			 */
 			for(edx = 0; edx < td->elements_count; edx++) {
-				elm = &elements[edx];
-				tcv = xer_check_tag(buf_ptr,ch_size,elm->name);
-				switch(tcv) {
+				switch(xer_check_tag(buf_ptr, ch_size,
+					elements[edx].name)) {
 				case XCT_BOTH:
 				case XCT_OPENING:
 					/*
@@ -750,11 +767,20 @@
 
 			/* It is expected extension */
 			if(specs->extensible) {
-				ASN_DEBUG("Got anticipated extension, "
-					"but NOT IMPLEMENTED YET");
+				ASN_DEBUG("Got anticipated extension");
 				/*
-				 * TODO: implement skipping of extensions
+				 * Check for (XCT_BOTH or XCT_UNKNOWN_BO)
+				 * By using a mask. Only record a pure
+				 * <opening> tags.
 				 */
+				if(tcv & XCT_CLOSING) {
+					/* Found </extension> without body */
+				} else {
+					ctx->left = 1;
+					ctx->phase = 3;	/* Skip ...'s */
+				}
+				XER_ADVANCE(ch_size);
+				continue;
 			}
 
 			/* Fall through */
@@ -766,7 +792,7 @@
 		break;
 	}
 
-	ctx->phase = 3;	/* "Phase out" on hard failure */
+	ctx->phase = 4;	/* "Phase out" on hard failure */
 	RETURN(RC_FAIL);
 }