/*-
 * Copyright (c) 2004-2017 Lev Walkin <vlm@lionet.info>. All rights reserved.
 * Redistribution and modifications are permitted subject to BSD license.
 */
/*
 * Read the NativeReal.h for the explanation wrt. differences between
 * REAL and NativeReal.
 * Basically, both are decoders and encoders of ASN.1 REAL type, but this
 * implementation deals with the standard (machine-specific) representation
 * of them instead of using the platform-independent buffer.
 */
#include <asn_internal.h>
#include <NativeReal.h>
#include <REAL.h>
#include <OCTET_STRING.h>
#include <math.h>
#include <float.h>

#if defined(__clang__)
/*
 * isnan() is defined using generic selections and won't compile in
 * strict C89 mode because of too fancy system's standard library.
 * However, prior to C11 the math had a perfectly working isnan()
 * in the math library.
 * Disable generic selection warning so we can test C89 mode with newer libc.
 */
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wc11-extensions"
static int asn_isnan(double d) {
    return isnan(d);
}
#pragma clang diagnostic pop
#else
#define asn_isnan(v)    isnan(v)
#endif  /* generic selections */

/*
 * NativeReal basic type description.
 */
static const ber_tlv_tag_t asn_DEF_NativeReal_tags[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (9 << 2))
};
asn_TYPE_operation_t asn_OP_NativeReal = {
	NativeReal_free,
	NativeReal_print,
	NativeReal_compare,
	NativeReal_decode_ber,
	NativeReal_encode_der,
	NativeReal_decode_xer,
	NativeReal_encode_xer,
#ifdef	ASN_DISABLE_OER_SUPPORT
	0,
	0,
#else
	NativeReal_decode_oer,
	NativeReal_encode_oer,
#endif  /* ASN_DISABLE_OER_SUPPORT */
#ifdef	ASN_DISABLE_PER_SUPPORT
	0,
	0,
#else
	NativeReal_decode_uper,
	NativeReal_encode_uper,
#endif	/* ASN_DISABLE_PER_SUPPORT */
	NativeReal_random_fill,
	0	/* Use generic outmost tag fetcher */
};
asn_TYPE_descriptor_t asn_DEF_NativeReal = {
	"REAL",			/* The ASN.1 type is still REAL */
	"REAL",
	&asn_OP_NativeReal,
	asn_DEF_NativeReal_tags,
	sizeof(asn_DEF_NativeReal_tags) / sizeof(asn_DEF_NativeReal_tags[0]),
	asn_DEF_NativeReal_tags,	/* Same as above */
	sizeof(asn_DEF_NativeReal_tags) / sizeof(asn_DEF_NativeReal_tags[0]),
	{ 0, 0, asn_generic_no_constraint },
	0, 0,	/* No members */
	0	/* No specifics */
};

static size_t NativeReal__float_size(const asn_TYPE_descriptor_t *td);
static double NativeReal__get_double(const asn_TYPE_descriptor_t *td,
                                     const void *ptr);
static ssize_t NativeReal__set(const asn_TYPE_descriptor_t *td, void **sptr,
                               double d);
static void NativeReal__network_swap(size_t float_size, const void *srcp,
                                     uint8_t *dst);

/*
 * Decode REAL type.
 */
asn_dec_rval_t
NativeReal_decode_ber(const asn_codec_ctx_t *opt_codec_ctx,
                      const asn_TYPE_descriptor_t *td, void **sptr,
                      const void *buf_ptr, size_t size, int tag_mode) {
    asn_dec_rval_t rval;
    ber_tlv_len_t length;

    ASN_DEBUG("Decoding %s as REAL (tm=%d)", td->name, tag_mode);

    /*
     * Check tags.
     */
    rval = ber_check_tags(opt_codec_ctx, td, 0, buf_ptr, size, tag_mode, 0,
                          &length, 0);
    if(rval.code != RC_OK) return rval;
    assert(length >= 0);    /* Ensured by ber_check_tags */

    ASN_DEBUG("%s length is %d bytes", td->name, (int)length);

    /*
     * Make sure we have this length.
     */
    buf_ptr = ((const char *)buf_ptr) + rval.consumed;
    size -= rval.consumed;
    if(length > (ber_tlv_len_t)size) {
        rval.code = RC_WMORE;
        rval.consumed = 0;
        return rval;
    }

    /*
     * ASN.1 encoded REAL: buf_ptr, length
     * Fill the Dbl, at the same time checking for overflow.
     * If overflow occured, return with RC_FAIL.
     */
    {
        uint8_t scratch[24]; /* Longer than %.16f in decimal */
        REAL_t tmp;
        double d;
        int ret;

        if((size_t)length < sizeof(scratch)) {
            tmp.buf = scratch;
            tmp.size = length;
        } else {
            /* This rarely happens: impractically long value */
            tmp.buf = CALLOC(1, length + 1);
            tmp.size = length;
            if(!tmp.buf) {
                rval.code = RC_FAIL;
                rval.consumed = 0;
                return rval;
            }
        }

        memcpy(tmp.buf, buf_ptr, length);
        tmp.buf[length] = '\0';

        ret = asn_REAL2double(&tmp, &d);
        if(tmp.buf != scratch) FREEMEM(tmp.buf);
        if(ret) {
            rval.code = RC_FAIL;
            rval.consumed = 0;
            return rval;
        }

        if(NativeReal__set(td, sptr, d) < 0)
            ASN__DECODE_FAILED;
    }

    rval.code = RC_OK;
    rval.consumed += length;

    ASN_DEBUG("Took %ld/%ld bytes to encode %s", (long)rval.consumed,
              (long)length, td->name);

    return rval;
}

/*
 * Encode the NativeReal using the standard REAL type DER encoder.
 */
asn_enc_rval_t
NativeReal_encode_der(const asn_TYPE_descriptor_t *td, const void *sptr,
                      int tag_mode, ber_tlv_tag_t tag,
                      asn_app_consume_bytes_f *cb, void *app_key) {
    double d = NativeReal__get_double(td, sptr);
    asn_enc_rval_t erval;
	REAL_t tmp;

	/* Prepare a temporary clean structure */
	memset(&tmp, 0, sizeof(tmp));

    if(asn_double2REAL(&tmp, d))
        ASN__ENCODE_FAILED;

    /* Encode a fake REAL */
    erval = der_encode_primitive(td, &tmp, tag_mode, tag, cb, app_key);
    if(erval.encoded == -1) {
		assert(erval.structure_ptr == &tmp);
		erval.structure_ptr = sptr;
	}

	/* Free possibly allocated members of the temporary structure */
    ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_REAL, &tmp);

    return erval;
}

#ifndef ASN_DISABLE_PER_SUPPORT

/*
 * Decode REAL type using PER.
 */
asn_dec_rval_t
NativeReal_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
                       const asn_TYPE_descriptor_t *td,
                       const asn_per_constraints_t *constraints, void **sptr,
                       asn_per_data_t *pd) {
    asn_dec_rval_t rval;
    double d;
	REAL_t tmp;
	void *ptmp = &tmp;
	int ret;

	(void)constraints;

	memset(&tmp, 0, sizeof(tmp));
    rval = OCTET_STRING_decode_uper(opt_codec_ctx, &asn_DEF_REAL,
                                    NULL, &ptmp, pd);
    if(rval.code != RC_OK) {
		ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_REAL, &tmp);
		return rval;
	}

	ret = asn_REAL2double(&tmp, &d);
	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_REAL, &tmp);
	if(ret) ASN__DECODE_FAILED;

    if(NativeReal__set(td, sptr, d) < 0 )
        ASN__DECODE_FAILED;

	return rval;
}

/*
 * Encode the NativeReal using the OCTET STRING PER encoder.
 */
asn_enc_rval_t
NativeReal_encode_uper(const asn_TYPE_descriptor_t *td,
                       const asn_per_constraints_t *constraints,
                       const void *sptr, asn_per_outp_t *po) {
    double d = NativeReal__get_double(td, sptr);
	asn_enc_rval_t erval;
	REAL_t tmp;

	(void)constraints;

	/* Prepare a temporary clean structure */
	memset(&tmp, 0, sizeof(tmp));

	if(asn_double2REAL(&tmp, d))
		ASN__ENCODE_FAILED;
	
	/* Encode a DER REAL */
    erval = OCTET_STRING_encode_uper(&asn_DEF_REAL, NULL, &tmp, po);
    if(erval.encoded == -1)
		erval.structure_ptr = sptr;

	/* Free possibly allocated members of the temporary structure */
	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_REAL, &tmp);

	return erval;
}

#endif /* ASN_DISABLE_PER_SUPPORT */

#ifndef ASN_DISABLE_OER_SUPPORT

/*
 * Encode as Canonical OER.
 */
asn_enc_rval_t
NativeReal_encode_oer(const asn_TYPE_descriptor_t *td,
                      const asn_oer_constraints_t *constraints,
                      const void *sptr, asn_app_consume_bytes_f *cb,
                      void *app_key) {
    asn_enc_rval_t er = {0, 0, 0};

    if(!constraints) constraints = td->encoding_constraints.oer_constraints;
    if(constraints && constraints->value.width != 0) {
        /* X.696 IEEE 754 binary32 and binary64 encoding */
        uint8_t scratch[sizeof(double)];
        const asn_NativeReal_specifics_t *specs =
            (const asn_NativeReal_specifics_t *)td->specifics;
        size_t wire_size = constraints->value.width;

        if(specs ? (wire_size == specs->float_size)
                 : (wire_size == sizeof(double))) {
            /*
             * Our representation matches the wire, modulo endianness.
             * That was the whole point of compact encoding!
             */
        } else {
            assert((wire_size == sizeof(double))
                   || (specs && specs->float_size == wire_size));
            ASN__ENCODE_FAILED;
        }

        /*
         * The X.696 standard doesn't specify endianness, neither is IEEE 754.
         * So we assume the network format is big endian.
         */
        NativeReal__network_swap(wire_size, sptr, scratch);
        if(cb(scratch, wire_size, app_key) < 0) {
            ASN__ENCODE_FAILED;
        } else {
            er.encoded = wire_size;
            ASN__ENCODED_OK(er);
        }
    } else {
        double d = NativeReal__get_double(td, sptr);
        ssize_t len_len;
        REAL_t tmp;

        /* Prepare a temporary clean structure */
        memset(&tmp, 0, sizeof(tmp));

        if(asn_double2REAL(&tmp, d)) {
            ASN__ENCODE_FAILED;
        }

        /* Encode a fake REAL */
        len_len = oer_serialize_length(tmp.size, cb, app_key);
        if(len_len < 0 || cb(tmp.buf, tmp.size, app_key) < 0) {
            ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_REAL, &tmp);
            ASN__ENCODE_FAILED;
        } else {
            er.encoded = len_len + tmp.size;
            ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_REAL, &tmp);
            ASN__ENCODED_OK(er);
        }
    }
}

asn_dec_rval_t
NativeReal_decode_oer(const asn_codec_ctx_t *opt_codec_ctx,
                      const asn_TYPE_descriptor_t *td,
                      const asn_oer_constraints_t *constraints, void **sptr,
                      const void *ptr, size_t size) {
    asn_dec_rval_t ok = {RC_OK, 0};
    double d;
    ssize_t len_len;
    size_t real_body_len;

    (void)opt_codec_ctx;

    if(!constraints) constraints = td->encoding_constraints.oer_constraints;
    if(constraints && constraints->value.width != 0) {
        /* X.696 IEEE 754 binary32 and binary64 encoding */
        uint8_t scratch[sizeof(double)];
        size_t wire_size = constraints->value.width;

        if(size < wire_size)
            ASN__DECODE_STARVED;

        /*
         * The X.696 standard doesn't specify endianness, neither is IEEE 754.
         * So we assume the network format is big endian.
         */
        NativeReal__network_swap(wire_size, ptr, scratch);


        switch(wire_size) {
            case sizeof(double):
                {
                    double tmp;
                    memcpy(&tmp, scratch, sizeof(double));
                    if(NativeReal__set(td, sptr, tmp) < 0)
                        ASN__DECODE_FAILED;
                }
                break;
            case sizeof(float):
                {
                    float tmp;
                    memcpy(&tmp, scratch, sizeof(float));
                    if(NativeReal__set(td, sptr, tmp) < 0)
                        ASN__DECODE_FAILED;
                }
                break;
        default:
            ASN__DECODE_FAILED;
        }

        ok.consumed = wire_size;
        return ok;
    }

    len_len = oer_fetch_length(ptr, size, &real_body_len);
    if(len_len < 0) ASN__DECODE_FAILED;
    if(len_len == 0) ASN__DECODE_STARVED;

    ptr = (const char *)ptr + len_len;
    size -= len_len;

    if(real_body_len > size) ASN__DECODE_STARVED;

    {
        uint8_t scratch[24]; /* Longer than %.16f in decimal */
        REAL_t tmp;
        int ret;

        if(real_body_len < sizeof(scratch)) {
            tmp.buf = scratch;
            tmp.size = real_body_len;
        } else {
            /* This rarely happens: impractically long value */
            tmp.buf = CALLOC(1, real_body_len + 1);
            tmp.size = real_body_len;
            if(!tmp.buf) {
                ASN__DECODE_FAILED;
            }
        }

        memcpy(tmp.buf, ptr, real_body_len);
        tmp.buf[real_body_len] = '\0';

        ret = asn_REAL2double(&tmp, &d);
        if(tmp.buf != scratch) FREEMEM(tmp.buf);
        if(ret) {
            ASN_DEBUG("REAL decoded in %zu bytes, but can't convert t double",
                      real_body_len);
            ASN__DECODE_FAILED;
        }
    }

    if(NativeReal__set(td, sptr, d) < 0)
        ASN__DECODE_FAILED;

    ok.consumed = len_len + real_body_len;
    return ok;
}

#endif /* ASN_DISABLE_OER_SUPPORT */

/*
 * Decode the chunk of XML text encoding REAL.
 */
asn_dec_rval_t
NativeReal_decode_xer(const asn_codec_ctx_t *opt_codec_ctx,
                      const asn_TYPE_descriptor_t *td, void **sptr,
                      const char *opt_mname, const void *buf_ptr, size_t size) {
    asn_dec_rval_t rval;
	REAL_t st = { 0, 0 };
	REAL_t *stp = &st;

	rval = REAL_decode_xer(opt_codec_ctx, td, (void **)&stp, opt_mname,
		buf_ptr, size);
	if(rval.code == RC_OK) {
        double d;
        if(asn_REAL2double(&st, &d) || NativeReal__set(td, sptr, d) < 0) {
            rval.code = RC_FAIL;
            rval.consumed = 0;
        }
	} else {
        /* Convert all errors into RC_FAIL */
        rval.consumed = 0;
	}
	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_REAL, &st);
	return rval;
}

asn_enc_rval_t
NativeReal_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr,
                      int ilevel, enum xer_encoder_flags_e flags,
                      asn_app_consume_bytes_f *cb, void *app_key) {
    double d = NativeReal__get_double(td, sptr);
	asn_enc_rval_t er;

	(void)ilevel;

    er.encoded = REAL__dump(d, flags & XER_F_CANONICAL, cb, app_key);
    if(er.encoded < 0) ASN__ENCODE_FAILED;

	ASN__ENCODED_OK(er);
}

/*
 * REAL specific human-readable output.
 */
int
NativeReal_print(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
                 asn_app_consume_bytes_f *cb, void *app_key) {
    (void)ilevel;	/* Unused argument */

	if(sptr) {
        double d = NativeReal__get_double(td, sptr);
        return (REAL__dump(d, 0, cb, app_key) < 0) ? -1 : 0;
    } else {
        return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
    }
}

int
NativeReal_compare(const asn_TYPE_descriptor_t *td, const void *aptr,
                   const void *bptr) {

    if(aptr && bptr) {
        double a = NativeReal__get_double(td, aptr);
        double b = NativeReal__get_double(td, bptr);

        /* NaN sorted above everything else */
        if(asn_isnan(a)) {
            if(asn_isnan(b)) {
                return 0;
            } else {
                return -1;
            }
        } else if(asn_isnan(b)) {
            return 1;
        }
        /* Value comparison. */
        if(a < b) {
            return -1;
        } else if(a > b) {
            return 1;
        } else {
            return 0;
        }
    } else if(!aptr) {
        return -1;
    } else {
        return 1;
    }
}

void
NativeReal_free(const asn_TYPE_descriptor_t *td, void *ptr,
                enum asn_struct_free_method method) {
    if(!td || !ptr)
		return;

	ASN_DEBUG("Freeing %s as REAL (%d, %p, Native)",
		td->name, method, ptr);

    switch(method) {
    case ASFM_FREE_EVERYTHING:
        FREEMEM(ptr);
        break;
    case ASFM_FREE_UNDERLYING:
        break;
    case ASFM_FREE_UNDERLYING_AND_RESET: {
        const asn_NativeReal_specifics_t *specs;
        size_t float_size;
        specs = (const asn_NativeReal_specifics_t *)td->specifics;
        float_size = specs ? specs->float_size : sizeof(double);
        memset(ptr, 0, float_size);
    } break;
    }
}

asn_random_fill_result_t
NativeReal_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
                       const asn_encoding_constraints_t *constraints,
                       size_t max_length) {
    asn_random_fill_result_t result_ok = {ARFILL_OK, 0};
    asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
    asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
#ifndef INFINITY
#define INFINITY (1.0/0.0)
#endif
#ifndef NAN
#define NAN (0.0/0.0)
#endif
    static const double double_values[] = {
        -M_E, M_E, -M_PI, M_PI, /* Better precision than with floats */
        -1E+308, 1E+308,
        /* 2^51 */
        -2251799813685248.0, 2251799813685248.0,
        /* 2^52 */
        -4503599627370496.0, 4503599627370496.0,
        /* 2^100 */
        -1267650600228229401496703205376.0, 1267650600228229401496703205376.0,
        -DBL_MIN, DBL_MIN,
        -DBL_MAX, DBL_MAX,
#ifdef  DBL_TRUE_MIN
        -DBL_TRUE_MIN, DBL_TRUE_MIN
#endif
    };
    static const float float_values[] = {
        0, -0.0, -1, 1, -M_E, M_E, -3.14, 3.14, -M_PI, M_PI, -255, 255,
        -FLT_MIN, FLT_MIN,
        -FLT_MAX, FLT_MAX,
#ifdef  FLT_TRUE_MIN
        -FLT_TRUE_MIN, FLT_TRUE_MIN,
#endif
        INFINITY, -INFINITY, NAN
    };
    ssize_t float_set_size = NativeReal__float_size(td);
    const size_t n_doubles = sizeof(double_values) / sizeof(double_values[0]);
    const size_t n_floats = sizeof(float_values) / sizeof(float_values[0]);
    double d;

    (void)constraints;

    if(max_length == 0) return result_skipped;

    if(float_set_size == sizeof(double) && asn_random_between(0, 1) == 0) {
        d = double_values[asn_random_between(0, n_doubles - 1)];
    } else {
        d = float_values[asn_random_between(0, n_floats - 1)];
    }

    if(NativeReal__set(td, sptr, d) < 0) {
        return result_failed;
    }

    result_ok.length = float_set_size;
    return result_ok;
}


/*
 * Local helper functions.
 */

static size_t
NativeReal__float_size(const asn_TYPE_descriptor_t *td) {
    const asn_NativeReal_specifics_t *specs =
        (const asn_NativeReal_specifics_t *)td->specifics;
    return specs ? specs->float_size : sizeof(double);
}

static double
NativeReal__get_double(const asn_TYPE_descriptor_t *td, const void *ptr) {
    size_t float_size = NativeReal__float_size(td);
    if(float_size == sizeof(float)) {
        return *(const float *)ptr;
    } else {
        return *(const double *)ptr;
    }
}

static ssize_t  /* Returns -1 or float size. */
NativeReal__set(const asn_TYPE_descriptor_t *td, void **sptr, double d) {
    size_t float_size = NativeReal__float_size(td);
    void *native;

    if(!(native = *sptr)) {
        native = (*sptr = CALLOC(1, float_size));
        if(!native) {
            return -1;
        }
    }

    if(float_size == sizeof(float)) {
        if(asn_double2float(d, (float *)native)) {
            return -1;
        }
    } else {
        *(double *)native = d;
    }

    return float_size;
}

/*
 * Swap bytes from/to network, if local is little-endian.
 * Unused endianness sections are likely removed at compile phase.
 */
static void
NativeReal__network_swap(size_t float_size, const void *srcp, uint8_t *dst) {
    const uint8_t *src = srcp;
    double test = -0.0;
    int float_big_endian = *(const char *)&test != 0;
    /* In lieu of static_assert(sizeof(double) == 8) */
    static const char sizeof_double_is_8_a[sizeof(double)-7] CC_NOTUSED;
    static const char sizeof_double_is_8_b[9-sizeof(double)] CC_NOTUSED;
    /* In lieu of static_assert(sizeof(sizeof) == 4) */
    static const char sizeof_float_is_4_a[sizeof(float)-3] CC_NOTUSED;
    static const char sizeof_float_is_4_b[5-sizeof(float)] CC_NOTUSED;

    switch(float_size) {
    case sizeof(double):
        assert(sizeof(double) == 8);
        if(float_big_endian) {
            dst[0] = src[0];
            dst[1] = src[1];
            dst[2] = src[2];
            dst[3] = src[3];
            dst[4] = src[4];
            dst[5] = src[5];
            dst[6] = src[6];
            dst[7] = src[7];
        } else {
            dst[0] = src[7];
            dst[1] = src[6];
            dst[2] = src[5];
            dst[3] = src[4];
            dst[4] = src[3];
            dst[5] = src[2];
            dst[6] = src[1];
            dst[7] = src[0];
        }
        return;
    case sizeof(float):
        assert(sizeof(float) == 4);
        if(float_big_endian) {
            dst[0] = src[0];
            dst[1] = src[1];
            dst[2] = src[2];
            dst[3] = src[3];
        } else {
            dst[0] = src[3];
            dst[1] = src[2];
            dst[2] = src[1];
            dst[3] = src[0];
        }
        return;
    }
}
