
/*** <<< 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 CC_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,
	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, Short_constraint },
	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.
 */

/*** <<< CTDEFS [Alias] >>> ***/

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

/*** <<< 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,
	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 */
	{ &asn_OER_type_Alias_constr_1, 0, Alias_constraint },
	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 CC_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,
		{ .oer_constraints = &asn_OER_memb_foo_constr_2, .per_constraints = 0, .general_constraints =  memb_foo_constraint_1 },
		.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,
		{ .oer_constraints = 0, .per_constraints = 0, .general_constraints = 0 },
		.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,
		{ .oer_constraints = 0, .per_constraints = 0, .general_constraints = 0 },
		.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,
	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, 0, SEQUENCE_constraint },
	asn_MBR_Soo_1,
	3,	/* Elements count */
	&asn_SPC_Soo_specs_1	/* Additional specs */
};

