
/*** <<< 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(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(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(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_set_3(int set_value, void **sptr) {
	long *st = *sptr;
	
	if(!st) {
		if(!set_value) return -1;	/* Not a default value */
		st = (*sptr = CALLOC(1, sizeof(*st)));
		if(!st) return -1;
	}
	
	if(set_value) {
		/* Install default value 3 */
		*st = 3;
		return 0;
	} else {
		/* Test default value 3 */
		return (*st == 3);
	}
}
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,
		.memb_constraints = memb_narrow1_constraint_1,
		.oer_constraints = 0,	/* OER is not compiled, use -gen-OER */
		.per_constraints = 0,	/* PER is not compiled, use -gen-PER */
		.default_value = asn_DFL_2_set_3,	/* 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,
		.memb_constraints = memb_narrow2_constraint_1,
		.oer_constraints = 0,	/* OER is not compiled, use -gen-OER */
		.per_constraints = 0,	/* PER is not compiled, use -gen-PER */
		.default_value = 0,
		.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,
		.memb_constraints = memb_narrow3_constraint_1,
		.oer_constraints = 0,	/* OER is not compiled, use -gen-OER */
		.per_constraints = 0,	/* PER is not compiled, use -gen-PER */
		.default_value = 0,
		.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,
	SEQUENCE_constraint,
	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,	/* No OER visible constraints */
	0,	/* No PER visible constraints */
	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,
	SEQUENCE_constraint,
	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,	/* No OER visible constraints */
	0,	/* No PER visible constraints */
	asn_MBR_Narrow_15P0_1,
	3,	/* Elements count */
	&asn_SPC_Narrow_15P0_specs_1	/* Additional specs */
};

