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

#include <NativeInteger.h>

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

typedef long	 Short_t;

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

extern asn_per_constraints_t asn_PER_type_Short_constr_1;
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;
per_type_decoder_f Short_decode_uper;
per_type_encoder_f Short_encode_uper;

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

int
Short_constraint(const 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] >>> ***/

asn_per_constraints_t asn_PER_type_Short_constr_1 CC_NOTUSED = {
	{ APC_CONSTRAINED,	 16,  16,  0,  65535 }	/* (0..65535) */,
	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
	0, 0	/* No PER value map */
};

/*** <<< 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 */
	{ 0, &asn_PER_type_Short_constr_1, 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_per_constraints_t asn_PER_type_Alias_constr_1;
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;
per_type_decoder_f Alias_decode_uper;
per_type_encoder_f Alias_encode_uper;

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

int
Alias_constraint(const 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] >>> ***/

asn_per_constraints_t asn_PER_type_Alias_constr_1 CC_NOTUSED = {
	{ APC_CONSTRAINED,	 16,  16,  0,  65535 }	/* (0..65535) */,
	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
	0, 0	/* No PER value map */
};

/*** <<< 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 */
	{ 0, &asn_PER_type_Alias_constr_1, 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(const 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_per_constraints_t asn_PER_memb_foo_constr_2 CC_NOTUSED = {
	{ APC_CONSTRAINED,	 16,  16,  0,  65535 }	/* (0..65535) */,
	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
	0, 0	/* No PER value map */
};

/*** <<< 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 = 0, .per_constraints = &asn_PER_memb_foo_constr_2, .general_constraints =  memb_foo_constraint_1 },
		0, 0, /* No default value */
		.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 },
		0, 0, /* No default value */
		.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 },
		0, 0, /* No default value */
		.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 */
};

