
/*** <<< INCLUDES [SIGNED] >>> ***/

#include <REAL.h>
#include <constr_SEQUENCE.h>
#include <INTEGER.h>
#include <constr_SET.h>

/*** <<< DEPS [SIGNED] >>> ***/


/*
 * Method of determining the components presence
 */
typedef enum signed_PR {
	signed_PR_a,	/* Member a is present */
} signed_PR;

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

typedef struct SIGNED_16P0 {
	REAL_t	 Signed;
	
	/* Context for parsing across buffer boundaries */
	asn_struct_ctx_t _asn_ctx;
} SIGNED_16P0_t;
typedef struct SIGNED_16P1 {
	struct Signed {
		INTEGER_t	 a;
		
		/* Presence bitmask: ASN_SET_ISPRESENT(psigned, signed_PR_x) */
		unsigned int _presence_map
			[((1+(8*sizeof(unsigned int))-1)/(8*sizeof(unsigned int)))];
		
		/* Context for parsing across buffer boundaries */
		asn_struct_ctx_t _asn_ctx;
	} Signed;
	
	/* Context for parsing across buffer boundaries */
	asn_struct_ctx_t _asn_ctx;
} SIGNED_16P1_t;

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

extern asn_TYPE_descriptor_t asn_DEF_SIGNED_16P0;
extern asn_TYPE_descriptor_t asn_DEF_SIGNED_16P1;

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

static asn_TYPE_member_t asn_MBR_SIGNED_16P0_1[] = {
	{ ATF_NOFLAGS, 0, offsetof(struct SIGNED_16P0, Signed),
		.tag = (ASN_TAG_CLASS_UNIVERSAL | (9 << 2)),
		.tag_mode = 0,
		.type = &asn_DEF_REAL,
		.memb_constraints = 0,	/* Defer constraints checking to the member type */
		.oer_constraints = 0,	/* OER is not compiled, use -gen-OER */
		.per_constraints = 0,	/* PER is not compiled, use -gen-PER */
		.default_value = 0,
		.name = "signed"
		},
};
static const ber_tlv_tag_t asn_DEF_SIGNED_16P0_tags_1[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
};
static const asn_TYPE_tag2member_t asn_MAP_SIGNED_16P0_tag2el_1[] = {
    { (ASN_TAG_CLASS_UNIVERSAL | (9 << 2)), 0, 0, 0 } /* signed */
};
static asn_SEQUENCE_specifics_t asn_SPC_SIGNED_16P0_specs_1 = {
	sizeof(struct SIGNED_16P0),
	offsetof(struct SIGNED_16P0, _asn_ctx),
	asn_MAP_SIGNED_16P0_tag2el_1,
	1,	/* 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_SIGNED_16P0 = {
	"SIGNED",
	"SIGNED",
	SEQUENCE_free,
	SEQUENCE_print,
	SEQUENCE_constraint,
	SEQUENCE_decode_ber,
	SEQUENCE_encode_der,
	SEQUENCE_decode_xer,
	SEQUENCE_encode_xer,
	0, 0,	/* No OER support, use "-gen-OER" to enable */
	0, 0,	/* No PER support, use "-gen-PER" to enable */
	0,	/* Use generic outmost tag fetcher */
	asn_DEF_SIGNED_16P0_tags_1,
	sizeof(asn_DEF_SIGNED_16P0_tags_1)
		/sizeof(asn_DEF_SIGNED_16P0_tags_1[0]), /* 1 */
	asn_DEF_SIGNED_16P0_tags_1,	/* Same as above */
	sizeof(asn_DEF_SIGNED_16P0_tags_1)
		/sizeof(asn_DEF_SIGNED_16P0_tags_1[0]), /* 1 */
	0,	/* No OER visible constraints */
	0,	/* No PER visible constraints */
	asn_MBR_SIGNED_16P0_1,
	1,	/* Elements count */
	&asn_SPC_SIGNED_16P0_specs_1	/* Additional specs */
};

static asn_TYPE_member_t asn_MBR_signed_4[] = {
	{ ATF_NOFLAGS, 0, offsetof(struct Signed, a),
		.tag = (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
		.tag_mode = 0,
		.type = &asn_DEF_INTEGER,
		.memb_constraints = 0,	/* Defer constraints checking to the member type */
		.oer_constraints = 0,	/* OER is not compiled, use -gen-OER */
		.per_constraints = 0,	/* PER is not compiled, use -gen-PER */
		.default_value = 0,
		.name = "a"
		},
};
static const ber_tlv_tag_t asn_DEF_signed_tags_4[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (17 << 2))
};
static const asn_TYPE_tag2member_t asn_MAP_signed_tag2el_4[] = {
    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 0 } /* a */
};
static const uint8_t asn_MAP_signed_mmap_4[(1 + (8 * sizeof(unsigned int)) - 1) / 8] = {
	(1 << 7)
};
static asn_SET_specifics_t asn_SPC_signed_specs_4 = {
	sizeof(struct Signed),
	offsetof(struct Signed, _asn_ctx),
	offsetof(struct Signed, _presence_map),
	asn_MAP_signed_tag2el_4,
	1,	/* Count of tags in the map */
	asn_MAP_signed_tag2el_4,	/* Same as above */
	1,	/* Count of tags in the CXER map */
	0,	/* Whether extensible */
	(const unsigned int *)asn_MAP_signed_mmap_4	/* Mandatory elements map */
};
static /* Use -fall-defs-global to expose */
asn_TYPE_descriptor_t asn_DEF_signed_4 = {
	"signed",
	"signed",
	SET_free,
	SET_print,
	SET_constraint,
	SET_decode_ber,
	SET_encode_der,
	SET_decode_xer,
	SET_encode_xer,
	0, 0,	/* No OER support, use "-gen-OER" to enable */
	0, 0,	/* No PER support, use "-gen-PER" to enable */
	0,	/* Use generic outmost tag fetcher */
	asn_DEF_signed_tags_4,
	sizeof(asn_DEF_signed_tags_4)
		/sizeof(asn_DEF_signed_tags_4[0]), /* 1 */
	asn_DEF_signed_tags_4,	/* Same as above */
	sizeof(asn_DEF_signed_tags_4)
		/sizeof(asn_DEF_signed_tags_4[0]), /* 1 */
	0,	/* No OER visible constraints */
	0,	/* No PER visible constraints */
	asn_MBR_signed_4,
	1,	/* Elements count */
	&asn_SPC_signed_specs_4	/* Additional specs */
};

static asn_TYPE_member_t asn_MBR_SIGNED_16P1_3[] = {
	{ ATF_NOFLAGS, 0, offsetof(struct SIGNED_16P1, Signed),
		.tag = (ASN_TAG_CLASS_UNIVERSAL | (17 << 2)),
		.tag_mode = 0,
		.type = &asn_DEF_signed_4,
		.memb_constraints = 0,	/* Defer constraints checking to the member type */
		.oer_constraints = 0,	/* OER is not compiled, use -gen-OER */
		.per_constraints = 0,	/* PER is not compiled, use -gen-PER */
		.default_value = 0,
		.name = "signed"
		},
};
static const ber_tlv_tag_t asn_DEF_SIGNED_16P1_tags_3[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
};
static const asn_TYPE_tag2member_t asn_MAP_SIGNED_16P1_tag2el_3[] = {
    { (ASN_TAG_CLASS_UNIVERSAL | (17 << 2)), 0, 0, 0 } /* signed */
};
static asn_SEQUENCE_specifics_t asn_SPC_SIGNED_16P1_specs_3 = {
	sizeof(struct SIGNED_16P1),
	offsetof(struct SIGNED_16P1, _asn_ctx),
	asn_MAP_SIGNED_16P1_tag2el_3,
	1,	/* 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_SIGNED_16P1 = {
	"SIGNED",
	"SIGNED",
	SEQUENCE_free,
	SEQUENCE_print,
	SEQUENCE_constraint,
	SEQUENCE_decode_ber,
	SEQUENCE_encode_der,
	SEQUENCE_decode_xer,
	SEQUENCE_encode_xer,
	0, 0,	/* No OER support, use "-gen-OER" to enable */
	0, 0,	/* No PER support, use "-gen-PER" to enable */
	0,	/* Use generic outmost tag fetcher */
	asn_DEF_SIGNED_16P1_tags_3,
	sizeof(asn_DEF_SIGNED_16P1_tags_3)
		/sizeof(asn_DEF_SIGNED_16P1_tags_3[0]), /* 1 */
	asn_DEF_SIGNED_16P1_tags_3,	/* Same as above */
	sizeof(asn_DEF_SIGNED_16P1_tags_3)
		/sizeof(asn_DEF_SIGNED_16P1_tags_3[0]), /* 1 */
	0,	/* No OER visible constraints */
	0,	/* No PER visible constraints */
	asn_MBR_SIGNED_16P1_3,
	1,	/* Elements count */
	&asn_SPC_SIGNED_16P1_specs_3	/* Additional specs */
};


/*** <<< INCLUDES [SignedREAL] >>> ***/

#include "SIGNED.h"

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

typedef SIGNED_16P0_t	 SignedREAL_t;

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

extern asn_TYPE_descriptor_t asn_DEF_SignedREAL;
asn_struct_free_f SignedREAL_free;
asn_struct_print_f SignedREAL_print;
asn_constr_check_f SignedREAL_constraint;
ber_type_decoder_f SignedREAL_decode_ber;
der_type_encoder_f SignedREAL_encode_der;
xer_type_decoder_f SignedREAL_decode_xer;
xer_type_encoder_f SignedREAL_encode_xer;

/*** <<< CODE [SignedREAL] >>> ***/

int
SignedREAL_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
			asn_app_constraint_failed_f *ctfailcb, void *app_key) {
	/* Replace with underlying type checker */
	td->check_constraints = asn_DEF_SIGNED_16P0.check_constraints;
	return td->check_constraints(td, sptr, ctfailcb, app_key);
}

/*
 * This type is implemented using SIGNED_16P0,
 * so here we adjust the DEF accordingly.
 */
static void
SignedREAL_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
	td->free_struct    = asn_DEF_SIGNED_16P0.free_struct;
	td->print_struct   = asn_DEF_SIGNED_16P0.print_struct;
	td->check_constraints = asn_DEF_SIGNED_16P0.check_constraints;
	td->ber_decoder    = asn_DEF_SIGNED_16P0.ber_decoder;
	td->der_encoder    = asn_DEF_SIGNED_16P0.der_encoder;
	td->xer_decoder    = asn_DEF_SIGNED_16P0.xer_decoder;
	td->xer_encoder    = asn_DEF_SIGNED_16P0.xer_encoder;
	td->uper_decoder   = asn_DEF_SIGNED_16P0.uper_decoder;
	td->uper_encoder   = asn_DEF_SIGNED_16P0.uper_encoder;
	td->oer_decoder    = asn_DEF_SIGNED_16P0.oer_decoder;
	td->oer_encoder    = asn_DEF_SIGNED_16P0.oer_encoder;
	if(!td->oer_constraints)
		td->oer_constraints = asn_DEF_SIGNED_16P0.oer_constraints;
	if(!td->per_constraints)
		td->per_constraints = asn_DEF_SIGNED_16P0.per_constraints;
	td->elements       = asn_DEF_SIGNED_16P0.elements;
	td->elements_count = asn_DEF_SIGNED_16P0.elements_count;
	td->specifics      = asn_DEF_SIGNED_16P0.specifics;
}

void
SignedREAL_free(asn_TYPE_descriptor_t *td,
		void *struct_ptr, int contents_only) {
	SignedREAL_1_inherit_TYPE_descriptor(td);
	td->free_struct(td, struct_ptr, contents_only);
}

int
SignedREAL_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
		int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
	SignedREAL_1_inherit_TYPE_descriptor(td);
	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
}

asn_dec_rval_t
SignedREAL_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
		void **structure, const void *bufptr, size_t size, int tag_mode) {
	SignedREAL_1_inherit_TYPE_descriptor(td);
	return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
}

asn_enc_rval_t
SignedREAL_encode_der(asn_TYPE_descriptor_t *td,
		void *structure, int tag_mode, ber_tlv_tag_t tag,
		asn_app_consume_bytes_f *cb, void *app_key) {
	SignedREAL_1_inherit_TYPE_descriptor(td);
	return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
}

asn_dec_rval_t
SignedREAL_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
		void **structure, const char *opt_mname, const void *bufptr, size_t size) {
	SignedREAL_1_inherit_TYPE_descriptor(td);
	return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
}

asn_enc_rval_t
SignedREAL_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
		int ilevel, enum xer_encoder_flags_e flags,
		asn_app_consume_bytes_f *cb, void *app_key) {
	SignedREAL_1_inherit_TYPE_descriptor(td);
	return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
}


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

static const ber_tlv_tag_t asn_DEF_SignedREAL_tags_1[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
};
asn_TYPE_descriptor_t asn_DEF_SignedREAL = {
	"SignedREAL",
	"SignedREAL",
	SignedREAL_free,
	SignedREAL_print,
	SignedREAL_constraint,
	SignedREAL_decode_ber,
	SignedREAL_encode_der,
	SignedREAL_decode_xer,
	SignedREAL_encode_xer,
	0, 0,	/* No OER support, use "-gen-OER" to enable */
	0, 0,	/* No PER support, use "-gen-PER" to enable */
	0,	/* Use generic outmost tag fetcher */
	asn_DEF_SignedREAL_tags_1,
	sizeof(asn_DEF_SignedREAL_tags_1)
		/sizeof(asn_DEF_SignedREAL_tags_1[0]), /* 1 */
	asn_DEF_SignedREAL_tags_1,	/* Same as above */
	sizeof(asn_DEF_SignedREAL_tags_1)
		/sizeof(asn_DEF_SignedREAL_tags_1[0]), /* 1 */
	0,	/* No OER visible constraints */
	0,	/* No PER visible constraints */
	0, 0,	/* Defined elsewhere */
	0	/* No specifics */
};


/*** <<< INCLUDES [SignedSET] >>> ***/

#include "SIGNED.h"

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

typedef SIGNED_16P1_t	 SignedSET_t;

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

extern asn_TYPE_descriptor_t asn_DEF_SignedSET;
asn_struct_free_f SignedSET_free;
asn_struct_print_f SignedSET_print;
asn_constr_check_f SignedSET_constraint;
ber_type_decoder_f SignedSET_decode_ber;
der_type_encoder_f SignedSET_encode_der;
xer_type_decoder_f SignedSET_decode_xer;
xer_type_encoder_f SignedSET_encode_xer;

/*** <<< CODE [SignedSET] >>> ***/

int
SignedSET_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
			asn_app_constraint_failed_f *ctfailcb, void *app_key) {
	/* Replace with underlying type checker */
	td->check_constraints = asn_DEF_SIGNED_16P1.check_constraints;
	return td->check_constraints(td, sptr, ctfailcb, app_key);
}

/*
 * This type is implemented using SIGNED_16P1,
 * so here we adjust the DEF accordingly.
 */
static void
SignedSET_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
	td->free_struct    = asn_DEF_SIGNED_16P1.free_struct;
	td->print_struct   = asn_DEF_SIGNED_16P1.print_struct;
	td->check_constraints = asn_DEF_SIGNED_16P1.check_constraints;
	td->ber_decoder    = asn_DEF_SIGNED_16P1.ber_decoder;
	td->der_encoder    = asn_DEF_SIGNED_16P1.der_encoder;
	td->xer_decoder    = asn_DEF_SIGNED_16P1.xer_decoder;
	td->xer_encoder    = asn_DEF_SIGNED_16P1.xer_encoder;
	td->uper_decoder   = asn_DEF_SIGNED_16P1.uper_decoder;
	td->uper_encoder   = asn_DEF_SIGNED_16P1.uper_encoder;
	td->oer_decoder    = asn_DEF_SIGNED_16P1.oer_decoder;
	td->oer_encoder    = asn_DEF_SIGNED_16P1.oer_encoder;
	if(!td->oer_constraints)
		td->oer_constraints = asn_DEF_SIGNED_16P1.oer_constraints;
	if(!td->per_constraints)
		td->per_constraints = asn_DEF_SIGNED_16P1.per_constraints;
	td->elements       = asn_DEF_SIGNED_16P1.elements;
	td->elements_count = asn_DEF_SIGNED_16P1.elements_count;
	td->specifics      = asn_DEF_SIGNED_16P1.specifics;
}

void
SignedSET_free(asn_TYPE_descriptor_t *td,
		void *struct_ptr, int contents_only) {
	SignedSET_1_inherit_TYPE_descriptor(td);
	td->free_struct(td, struct_ptr, contents_only);
}

int
SignedSET_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
		int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
	SignedSET_1_inherit_TYPE_descriptor(td);
	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
}

asn_dec_rval_t
SignedSET_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
		void **structure, const void *bufptr, size_t size, int tag_mode) {
	SignedSET_1_inherit_TYPE_descriptor(td);
	return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
}

asn_enc_rval_t
SignedSET_encode_der(asn_TYPE_descriptor_t *td,
		void *structure, int tag_mode, ber_tlv_tag_t tag,
		asn_app_consume_bytes_f *cb, void *app_key) {
	SignedSET_1_inherit_TYPE_descriptor(td);
	return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
}

asn_dec_rval_t
SignedSET_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
		void **structure, const char *opt_mname, const void *bufptr, size_t size) {
	SignedSET_1_inherit_TYPE_descriptor(td);
	return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
}

asn_enc_rval_t
SignedSET_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
		int ilevel, enum xer_encoder_flags_e flags,
		asn_app_consume_bytes_f *cb, void *app_key) {
	SignedSET_1_inherit_TYPE_descriptor(td);
	return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
}


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

static const ber_tlv_tag_t asn_DEF_SignedSET_tags_1[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
};
asn_TYPE_descriptor_t asn_DEF_SignedSET = {
	"SignedSET",
	"SignedSET",
	SignedSET_free,
	SignedSET_print,
	SignedSET_constraint,
	SignedSET_decode_ber,
	SignedSET_encode_der,
	SignedSET_decode_xer,
	SignedSET_encode_xer,
	0, 0,	/* No OER support, use "-gen-OER" to enable */
	0, 0,	/* No PER support, use "-gen-PER" to enable */
	0,	/* Use generic outmost tag fetcher */
	asn_DEF_SignedSET_tags_1,
	sizeof(asn_DEF_SignedSET_tags_1)
		/sizeof(asn_DEF_SignedSET_tags_1[0]), /* 1 */
	asn_DEF_SignedSET_tags_1,	/* Same as above */
	sizeof(asn_DEF_SignedSET_tags_1)
		/sizeof(asn_DEF_SignedSET_tags_1[0]), /* 1 */
	0,	/* No OER visible constraints */
	0,	/* No PER visible constraints */
	0, 0,	/* Defined elsewhere */
	0	/* No specifics */
};

