Move type operations to another structure

Every type has free, print, check_constraints, ber_decoder, der_encoder,
xer_decoder, xer_encoder, uper_decoder, uper_encoder and outmost_tag
operations. We move them out to a separate structure asn_TYPE_operation_t.

Combined with previous logic simplification, these operations are based
on ASN.1 basic types, constructed types and string types. So we can
reduce the space occupied by asn_TYPE_descriptor_t variables.
diff --git a/skeletons/constr_SET.c b/skeletons/constr_SET.c
index 4f370bf..2f91d0e 100644
--- a/skeletons/constr_SET.c
+++ b/skeletons/constr_SET.c
@@ -296,7 +296,7 @@
 		/*
 		 * Invoke the member fetch routine according to member's type
 		 */
-		rval = elements[edx].type->ber_decoder(opt_codec_ctx,
+		rval = elements[edx].type->op->ber_decoder(opt_codec_ctx,
 				elements[edx].type,
 				memb_ptr2, ptr, LEFT,
 				elements[edx].tag_mode);
@@ -488,7 +488,7 @@
 		} else {
 			memb_ptr = (void *)((char *)sptr + elm->memb_offset);
 		}
-		tmper = elm->type->der_encoder(elm->type, memb_ptr,
+		tmper = elm->type->op->der_encoder(elm->type, memb_ptr,
 			elm->tag_mode, elm->tag,
 			0, 0);
 		if(tmper.encoded == -1)
@@ -555,7 +555,7 @@
 		} else {
 			memb_ptr = (void *)((char *)sptr + elm->memb_offset);
 		}
-		tmper = elm->type->der_encoder(elm->type, memb_ptr,
+		tmper = elm->type->op->der_encoder(elm->type, memb_ptr,
 			elm->tag_mode, elm->tag,
 			cb, app_key);
 		if(tmper.encoded == -1)
@@ -658,7 +658,7 @@
 			}
 
 			/* Invoke the inner type decoder, m.b. multiple times */
-			tmprval = elm->type->xer_decoder(opt_codec_ctx,
+			tmprval = elm->type->op->xer_decoder(opt_codec_ctx,
 					elm->type, memb_ptr2, elm->name,
 					buf_ptr, size);
 			XER_ADVANCE(tmprval.consumed);
@@ -846,7 +846,7 @@
 		ASN__CALLBACK3("<", 1, mname, mlen, ">", 1);
 
 		/* Print the member itself */
-		tmper = elm->type->xer_encoder(elm->type, memb_ptr,
+		tmper = elm->type->op->xer_encoder(elm->type, memb_ptr,
 				ilevel + 1, flags, cb, app_key);
 		if(tmper.encoded == -1) return tmper;
 
@@ -898,7 +898,7 @@
 			return -1;
 
 		/* Print the member itself */
-		ret = elm->type->print_struct(elm->type, memb_ptr, ilevel + 1,
+		ret = elm->type->op->print_struct(elm->type, memb_ptr, ilevel + 1,
 			cb, app_key);
 		if(ret) return ret;
 	}
@@ -911,7 +911,7 @@
 
 void
 SET_free(const asn_TYPE_descriptor_t *td, void *ptr, int contents_only) {
-    size_t edx;
+	size_t edx;
 
 	if(!td || !ptr)
 		return;
@@ -997,7 +997,7 @@
 		asn_TYPE_member_t *elm = &td->elements[edx];
 		const void *amemb;
 		const void *bmemb;
-        int ret;
+		int ret;
 
 		if(elm->flags & ATF_POINTER) {
             amemb =
@@ -1015,10 +1015,25 @@
             bmemb = (const void *)((const char *)bptr + elm->memb_offset);
 		}
 
-        ret = elm->type->compare_struct(elm->type, amemb, bmemb);
+        ret = elm->type->op->compare_struct(elm->type, amemb, bmemb);
         if(ret != 0) return ret;
     }
 
     return 0;
 }
 
+
+asn_TYPE_operation_t asn_OP_SET = {
+	SET_free,
+	SET_print,
+	SET_compare,
+	SET_constraint,
+	SET_decode_ber,
+	SET_encode_der,
+	SET_decode_xer,
+	SET_encode_xer,
+	0,	/* SET_decode_uper */
+	0,	/* SET_encode_uper */
+	0	/* Use generic outmost tag fetcher */
+};
+