
/*** <<< INCLUDES [Narrow] >>> ***/

#include <NativeInteger.h>
#include <constr_SEQUENCE.h>

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

typedef struct Narrow_15P0 {
	long	*narrow1	/* DEFAULT 3 */;
	long	 narrow2;
	long	*narrow3	/* OPTIONAL */;
	
	/* Context for parsing across buffer boundaries */
	asn_struct_ctx_t _asn_ctx;
} Narrow_15P0_t;

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

extern asn_TYPE_descriptor_t asn_DEF_Narrow_15P0;
extern asn_SEQUENCE_specifics_t asn_SPC_Narrow_15P0_specs_1;
extern asn_TYPE_member_t asn_MBR_Narrow_15P0_1[3];

/*** <<< CODE [Narrow] >>> ***/

static int
memb_narrow1_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 >= 1 && value <= 5)) {
		/* Constraint check succeeded */
		return 0;
	} else {
		ASN__CTFAIL(app_key, td, sptr,
			"%s: constraint failed (%s:%d)",
			td->name, __FILE__, __LINE__);
		return -1;
	}
}

static int
memb_narrow2_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 >= 2 && value <= 5)) {
		/* Constraint check succeeded */
		return 0;
	} else {
		ASN__CTFAIL(app_key, td, sptr,
			"%s: constraint failed (%s:%d)",
			td->name, __FILE__, __LINE__);
		return -1;
	}
}

static int
memb_narrow3_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 >= 3 && value <= 5)) {
		/* Constraint check succeeded */
		return 0;
	} else {
		ASN__CTFAIL(app_key, td, sptr,
			"%s: constraint failed (%s:%d)",
			td->name, __FILE__, __LINE__);
		return -1;
	}
}


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

static int asn_DFL_2_cmp_3(const void *sptr) {
	const long *st = sptr;
	
	if(!st) {
		return -1; /* No value is not a default value */
	}
	
	/* Test default value 3 */
	return (*st != 3);
}
static int asn_DFL_2_set_3(void **sptr) {
	long *st = *sptr;
	
	if(!st) {
		st = (*sptr = CALLOC(1, sizeof(*st)));
		if(!st) return -1;
	}
	
	/* Install default value 3 */
	*st = 3;
	return 0;
}
asn_TYPE_member_t asn_MBR_Narrow_15P0_1[] = {
	{ ATF_POINTER, 1, offsetof(struct Narrow_15P0, narrow1),
		.tag = (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
		.tag_mode = 0,
		.type = &asn_DEF_NativeInteger,
		.type_selector = 0,
		{ .oer_constraints = 0, .per_constraints = 0, .general_constraints =  memb_narrow1_constraint_1 },
		.default_value_cmp = &asn_DFL_2_cmp_3,	/* Compare DEFAULT 3 */
		.default_value_set = &asn_DFL_2_set_3,	/* Set DEFAULT 3 */
		.name = "narrow1"
		},
	{ ATF_NOFLAGS, 0, offsetof(struct Narrow_15P0, narrow2),
		.tag = (ASN_TAG_CLASS_CONTEXT | (0 << 2)),
		.tag_mode = +1,	/* EXPLICIT tag at current level */
		.type = &asn_DEF_NativeInteger,
		.type_selector = 0,
		{ .oer_constraints = 0, .per_constraints = 0, .general_constraints =  memb_narrow2_constraint_1 },
		0, 0, /* No default value */
		.name = "narrow2"
		},
	{ ATF_POINTER, 1, offsetof(struct Narrow_15P0, narrow3),
		.tag = (ASN_TAG_CLASS_CONTEXT | (1 << 2)),
		.tag_mode = +1,	/* EXPLICIT tag at current level */
		.type = &asn_DEF_NativeInteger,
		.type_selector = 0,
		{ .oer_constraints = 0, .per_constraints = 0, .general_constraints =  memb_narrow3_constraint_1 },
		0, 0, /* No default value */
		.name = "narrow3"
		},
};
static const ber_tlv_tag_t asn_DEF_Narrow_15P0_tags_1[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
};
static const asn_TYPE_tag2member_t asn_MAP_Narrow_15P0_tag2el_1[] = {
    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 0 }, /* narrow1 */
    { (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 1, 0, 0 }, /* narrow2 */
    { (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 2, 0, 0 } /* narrow3 */
};
asn_SEQUENCE_specifics_t asn_SPC_Narrow_15P0_specs_1 = {
	sizeof(struct Narrow_15P0),
	offsetof(struct Narrow_15P0, _asn_ctx),
	.tag2el = asn_MAP_Narrow_15P0_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_Narrow_15P0 = {
	"Narrow",
	"Narrow",
	&asn_OP_SEQUENCE,
	asn_DEF_Narrow_15P0_tags_1,
	sizeof(asn_DEF_Narrow_15P0_tags_1)
		/sizeof(asn_DEF_Narrow_15P0_tags_1[0]), /* 1 */
	asn_DEF_Narrow_15P0_tags_1,	/* Same as above */
	sizeof(asn_DEF_Narrow_15P0_tags_1)
		/sizeof(asn_DEF_Narrow_15P0_tags_1[0]), /* 1 */
	{ 0, 0, SEQUENCE_constraint },
	asn_MBR_Narrow_15P0_1,
	3,	/* Elements count */
	&asn_SPC_Narrow_15P0_specs_1	/* Additional specs */
};


/*** <<< INCLUDES [NarrowInteger] >>> ***/

#include "Narrow.h"

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

typedef Narrow_15P0_t	 NarrowInteger_t;

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

extern asn_TYPE_descriptor_t asn_DEF_NarrowInteger;
asn_struct_free_f NarrowInteger_free;
asn_struct_print_f NarrowInteger_print;
asn_constr_check_f NarrowInteger_constraint;
ber_type_decoder_f NarrowInteger_decode_ber;
der_type_encoder_f NarrowInteger_encode_der;
xer_type_decoder_f NarrowInteger_decode_xer;
xer_type_encoder_f NarrowInteger_encode_xer;

/*** <<< CODE [NarrowInteger] >>> ***/

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

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

static const ber_tlv_tag_t asn_DEF_NarrowInteger_tags_1[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
};
asn_TYPE_descriptor_t asn_DEF_NarrowInteger = {
	"NarrowInteger",
	"NarrowInteger",
	&asn_OP_SEQUENCE,
	asn_DEF_NarrowInteger_tags_1,
	sizeof(asn_DEF_NarrowInteger_tags_1)
		/sizeof(asn_DEF_NarrowInteger_tags_1[0]), /* 1 */
	asn_DEF_NarrowInteger_tags_1,	/* Same as above */
	sizeof(asn_DEF_NarrowInteger_tags_1)
		/sizeof(asn_DEF_NarrowInteger_tags_1[0]), /* 1 */
	{ 0, 0, SEQUENCE_constraint },
	asn_MBR_Narrow_15P0_1,
	3,	/* Elements count */
	&asn_SPC_Narrow_15P0_specs_1	/* Additional specs */
};

