XER support

diff --git a/skeletons/constr_CHOICE.c b/skeletons/constr_CHOICE.c
index b7d38fb..ac2bbd6 100644
--- a/skeletons/constr_CHOICE.c
+++ b/skeletons/constr_CHOICE.c
@@ -2,6 +2,7 @@
  * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
  * Redistribution and modifications are permitted subject to BSD license.
  */
+#include <asn_internal.h>
 #include <constr_CHOICE.h>
 #include <assert.h>
 
@@ -348,14 +349,14 @@
 	RETURN(RC_OK);
 }
 
-der_enc_rval_t
+asn_enc_rval_t
 CHOICE_encode_der(asn1_TYPE_descriptor_t *td,
 		void *struct_ptr,
 		int tag_mode, ber_tlv_tag_t tag,
 		asn_app_consume_bytes_f *cb, void *app_key) {
 	asn1_CHOICE_specifics_t *specs = (asn1_CHOICE_specifics_t *)td->specifics;
 	asn1_TYPE_member_t *elm;	/* CHOICE element */
-	der_enc_rval_t erval;
+	asn_enc_rval_t erval;
 	void *memb_ptr;
 	size_t computed_size = 0;
 	int present;
@@ -536,6 +537,57 @@
 	}
 }
 
+asn_enc_rval_t
+CHOICE_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr,
+	int ilevel, enum xer_encoder_flags_e flags,
+		asn_app_consume_bytes_f *cb, void *app_key) {
+	asn1_CHOICE_specifics_t *specs=(asn1_CHOICE_specifics_t *)td->specifics;
+	asn_enc_rval_t er;
+	int present;
+
+	if(!sptr)
+		_ASN_ENCODE_FAILED;
+
+	/*
+	 * Figure out which CHOICE element is encoded.
+	 */
+	present = _fetch_present_idx(sptr, specs->pres_offset,specs->pres_size);
+
+	if(present <= 0 || present > td->elements_count) {
+		_ASN_ENCODE_FAILED;
+	}  else {
+		asn_enc_rval_t tmper;
+		asn1_TYPE_member_t *elm = &td->elements[present-1];
+		void *memb_ptr;
+		const char *mname = elm->name;
+		unsigned int mlen = strlen(mname);
+
+		if(elm->flags & ATF_POINTER) {
+			memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
+			if(!memb_ptr) _ASN_ENCODE_FAILED;
+		} else {
+			memb_ptr = (void *)((char *)sptr + elm->memb_offset);
+		}
+
+		er.encoded = 0;
+
+                if(!(flags & XER_F_CANONICAL)) _i_ASN_TEXT_INDENT(1, ilevel);
+		_ASN_CALLBACK3("<", 1, mname, mlen, ">", 1);
+
+		tmper = elm->type->xer_encoder(elm->type, memb_ptr,
+				ilevel + 1, flags, cb, app_key);
+		if(tmper.encoded == -1) return tmper;
+
+		_ASN_CALLBACK3("</", 2, mname, mlen, ">", 1);
+
+		er.encoded += 5 + (2 * mlen) + tmper.encoded;
+	}
+
+	if(!(flags & XER_F_CANONICAL)) _i_ASN_TEXT_INDENT(1, ilevel - 1);
+
+	return er;
+}
+
 int
 CHOICE_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
 		asn_app_consume_bytes_f *cb, void *app_key) {
@@ -550,7 +602,7 @@
 	present = _fetch_present_idx(sptr, specs->pres_offset,specs->pres_size);
 
 	/*
-	 * Free that element.
+	 * Print that element.
 	 */
 	if(present > 0 && present <= td->elements_count) {
 		asn1_TYPE_member_t *elm = &td->elements[present-1];