
/*** <<< INCLUDES [Short] >>> ***/

#include <NativeInteger.h>

/*** <<< TYPE-DECLS [Short] >>> ***/

typedef long	 Short_t;

/*** <<< FUNC-DECLS [Short] >>> ***/

extern asn_TYPE_descriptor_t asn_DEF_Short;
asn_struct_free_f Short_free;
asn_struct_print_f Short_print;
asn_constr_check_f Short_constraint;
ber_type_decoder_f Short_decode_ber;
der_type_encoder_f Short_encode_der;
xer_type_decoder_f Short_decode_xer;
xer_type_encoder_f Short_encode_xer;
oer_type_decoder_f Short_decode_oer;
oer_type_encoder_f Short_encode_oer;

/*** <<< CODE [Short] >>> ***/

int
Short_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
			asn_app_constraint_failed_f *ctfailcb, void *app_key) {
	long value;
	
	if(!sptr) {
		ASN__CTFAIL(app_key, td, sptr,
			"%s: value not given (%s:%d)",
			td->name, __FILE__, __LINE__);
		return -1;
	}
	
	value = *(const long *)sptr;
	
	if((value >= 0 && value <= 65535)) {
		/* Constraint check succeeded */
		return 0;
	} else {
		ASN__CTFAIL(app_key, td, sptr,
			"%s: constraint failed (%s:%d)",
			td->name, __FILE__, __LINE__);
		return -1;
	}
}

/*
 * This type is implemented using NativeInteger,
 * so here we adjust the DEF accordingly.
 */

/*** <<< CTDEFS [Short] >>> ***/

static asn_oer_constraints_t asn_OER_type_Short_constr_1 GCC_NOTUSED = {
	{ 2, 1 }	/* (0..65535) */,
	-1};

/*** <<< STAT-DEFS [Short] >>> ***/

static const ber_tlv_tag_t asn_DEF_Short_tags_1[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
};
asn_TYPE_descriptor_t asn_DEF_Short = {
	"Short",
	"Short",
	&asn_OP_NativeInteger,
	Short_constraint,
	asn_DEF_Short_tags_1,
	sizeof(asn_DEF_Short_tags_1)
		/sizeof(asn_DEF_Short_tags_1[0]), /* 1 */
	asn_DEF_Short_tags_1,	/* Same as above */
	sizeof(asn_DEF_Short_tags_1)
		/sizeof(asn_DEF_Short_tags_1[0]), /* 1 */
	&asn_OER_type_Short_constr_1,
	0,	/* No PER visible constraints */
	0, 0,	/* No members */
	0	/* No specifics */
};


/*** <<< INCLUDES [Alias] >>> ***/

#include "Short.h"

/*** <<< TYPE-DECLS [Alias] >>> ***/

typedef Short_t	 Alias_t;

/*** <<< FUNC-DECLS [Alias] >>> ***/

extern asn_TYPE_descriptor_t asn_DEF_Alias;
asn_struct_free_f Alias_free;
asn_struct_print_f Alias_print;
asn_constr_check_f Alias_constraint;
ber_type_decoder_f Alias_decode_ber;
der_type_encoder_f Alias_encode_der;
xer_type_decoder_f Alias_decode_xer;
xer_type_encoder_f Alias_encode_xer;
oer_type_decoder_f Alias_decode_oer;
oer_type_encoder_f Alias_encode_oer;

/*** <<< CODE [Alias] >>> ***/

int
Alias_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
			asn_app_constraint_failed_f *ctfailcb, void *app_key) {
	long value;
	
	if(!sptr) {
		ASN__CTFAIL(app_key, td, sptr,
			"%s: value not given (%s:%d)",
			td->name, __FILE__, __LINE__);
		return -1;
	}
	
	value = *(const long *)sptr;
	
	if((value >= 0 && value <= 65535)) {
		/* Constraint check succeeded */
		return 0;
	} else {
		ASN__CTFAIL(app_key, td, sptr,
			"%s: constraint failed (%s:%d)",
			td->name, __FILE__, __LINE__);
		return -1;
	}
}

/*
 * This type is implemented using Short,
 * so here we adjust the DEF accordingly.
 */

/*** <<< STAT-DEFS [Alias] >>> ***/

static const ber_tlv_tag_t asn_DEF_Alias_tags_1[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
};
asn_TYPE_descriptor_t asn_DEF_Alias = {
	"Alias",
	"Alias",
	&asn_OP_NativeInteger,
	Alias_constraint,
	asn_DEF_Alias_tags_1,
	sizeof(asn_DEF_Alias_tags_1)
		/sizeof(asn_DEF_Alias_tags_1[0]), /* 1 */
	asn_DEF_Alias_tags_1,	/* Same as above */
	sizeof(asn_DEF_Alias_tags_1)
		/sizeof(asn_DEF_Alias_tags_1[0]), /* 1 */
	0,	/* No OER visible constraints */
	0,	/* No PER visible constraints */
	0, 0,	/* No members */
	0	/* No specifics */
};


/*** <<< INCLUDES [Soo] >>> ***/

#include <NativeInteger.h>
#include "Short.h"
#include "Alias.h"
#include <constr_SEQUENCE.h>

/*** <<< TYPE-DECLS [Soo] >>> ***/

typedef struct Soo {
	long	 foo;
	Short_t	 bar;
	Alias_t	 baz;
	
	/* Context for parsing across buffer boundaries */
	asn_struct_ctx_t _asn_ctx;
} Soo_t;

/*** <<< FUNC-DECLS [Soo] >>> ***/

extern asn_TYPE_descriptor_t asn_DEF_Soo;

/*** <<< CODE [Soo] >>> ***/

static int
memb_foo_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr,
			asn_app_constraint_failed_f *ctfailcb, void *app_key) {
	long value;
	
	if(!sptr) {
		ASN__CTFAIL(app_key, td, sptr,
			"%s: value not given (%s:%d)",
			td->name, __FILE__, __LINE__);
		return -1;
	}
	
	value = *(const long *)sptr;
	
	if((value >= 0 && value <= 65535)) {
		/* Constraint check succeeded */
		return 0;
	} else {
		ASN__CTFAIL(app_key, td, sptr,
			"%s: constraint failed (%s:%d)",
			td->name, __FILE__, __LINE__);
		return -1;
	}
}


/*** <<< CTDEFS [Soo] >>> ***/

static asn_oer_constraints_t asn_OER_memb_foo_constr_2 GCC_NOTUSED = {
	{ 2, 1 }	/* (0..65535) */,
	-1};

/*** <<< STAT-DEFS [Soo] >>> ***/

static asn_TYPE_member_t asn_MBR_Soo_1[] = {
	{ ATF_NOFLAGS, 0, offsetof(struct Soo, foo),
		.tag = (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
		.tag_mode = 0,
		.type = &asn_DEF_NativeInteger,
		.type_selector = 0,
		.memb_constraints = memb_foo_constraint_1,
		.oer_constraints = &asn_OER_memb_foo_constr_2,
		.per_constraints = 0,	/* PER is not compiled, use -gen-PER */
		.default_value = 0,
		.name = "foo"
		},
	{ ATF_NOFLAGS, 0, offsetof(struct Soo, bar),
		.tag = (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
		.tag_mode = 0,
		.type = &asn_DEF_Short,
		.type_selector = 0,
		.memb_constraints = 0,	/* Defer constraints checking to the member type */
		.oer_constraints = 0,	/* No OER visible constraints */
		.per_constraints = 0,	/* PER is not compiled, use -gen-PER */
		.default_value = 0,
		.name = "bar"
		},
	{ ATF_NOFLAGS, 0, offsetof(struct Soo, baz),
		.tag = (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
		.tag_mode = 0,
		.type = &asn_DEF_Alias,
		.type_selector = 0,
		.memb_constraints = 0,	/* Defer constraints checking to the member type */
		.oer_constraints = 0,	/* No OER visible constraints */
		.per_constraints = 0,	/* PER is not compiled, use -gen-PER */
		.default_value = 0,
		.name = "baz"
		},
};
static const ber_tlv_tag_t asn_DEF_Soo_tags_1[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
};
static const asn_TYPE_tag2member_t asn_MAP_Soo_tag2el_1[] = {
    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 2 }, /* foo */
    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 1, -1, 1 }, /* bar */
    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 2, -2, 0 } /* baz */
};
static asn_SEQUENCE_specifics_t asn_SPC_Soo_specs_1 = {
	sizeof(struct Soo),
	offsetof(struct Soo, _asn_ctx),
	.tag2el = asn_MAP_Soo_tag2el_1,
	.tag2el_count = 3,	/* Count of tags in the map */
	0, 0, 0,	/* Optional elements (not needed) */
	-1,	/* Start extensions */
	-1	/* Stop extensions */
};
asn_TYPE_descriptor_t asn_DEF_Soo = {
	"Soo",
	"Soo",
	&asn_OP_SEQUENCE,
	SEQUENCE_constraint,
	asn_DEF_Soo_tags_1,
	sizeof(asn_DEF_Soo_tags_1)
		/sizeof(asn_DEF_Soo_tags_1[0]), /* 1 */
	asn_DEF_Soo_tags_1,	/* Same as above */
	sizeof(asn_DEF_Soo_tags_1)
		/sizeof(asn_DEF_Soo_tags_1[0]), /* 1 */
	0,	/* No OER visible constraints */
	0,	/* No PER visible constraints */
	asn_MBR_Soo_1,
	3,	/* Elements count */
	&asn_SPC_Soo_specs_1	/* Additional specs */
};

