/*
 * Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
 * All rights reserved.
 * Redistribution and modifications are permitted subject to BSD license.
 */
#ifndef ASN_DISABLE_OER_SUPPORT

#include <asn_internal.h>
#include <NativeEnumerated.h>
#include <errno.h>

/*
 * This function is only to get rid of Undefined Behavior Sanitizer warning.
 */
static intmax_t CC_ATTR_NO_SANITIZE("shift-base")
asn__safe_nativeenumerated_convert_helper(const uint8_t *b,
                                          const uint8_t *end) {
    intmax_t value;

    /* Perform the sign initialization */
    /* Actually value = -(*b >> 7); gains nothing, yet unreadable! */
    if((*b >> 7)) {
        value = -1;
    } else {
        value = 0;
    }

    /* Conversion engine */
    for(; b < end; b++) {
        value = (value << 8) | *b;
    }

    return value;
}

asn_dec_rval_t
NativeEnumerated_decode_oer(const asn_codec_ctx_t *opt_codec_ctx,
                            asn_TYPE_descriptor_t *td,
                            const asn_oer_constraints_t *constraints,
                            void **nint_ptr, const void *ptr, size_t size) {
    asn_dec_rval_t rval = {RC_OK, 0};
    long *native = (long *)*nint_ptr;
    const uint8_t *b = ptr;

    (void)opt_codec_ctx;
    (void)constraints;

    if(size < 1) {
        ASN__DECODE_STARVED;
    }

    if((*b & 0x80) == 0) {
        /*
         * X.696 (08/2015) #11.2 Short form for Enumerated.
         */
        if(!native) {
            native = (long *)(*nint_ptr = CALLOC(1, sizeof(*native)));
            if(!native) ASN__DECODE_FAILED;
        }

        *native = *b;
        rval.consumed = 1;
    } else {
        /*
         * X.696 (08/2015) #11.4 Long form for Enumerated.
         */
        size_t length = *b & 0x7f;
        const uint8_t *bend;
        intmax_t value;

        if(length < 1 || length > sizeof(*native)) {
            ASN__DECODE_FAILED;
        }
        if((1 + length) > size) {
            ASN__DECODE_STARVED;
        }
        b++;
        bend = b + length;

        value = asn__safe_nativeenumerated_convert_helper(b, bend);
        if(value < 0) {
            const asn_INTEGER_specifics_t *specs =
                (const asn_INTEGER_specifics_t *)td->specifics;
            if(specs && specs->field_unsigned) {
                ASN__DECODE_FAILED;
            }
        }

        if(!native) {
            native = (long *)(*nint_ptr = CALLOC(1, sizeof(*native)));
            if(!native) ASN__DECODE_FAILED;
        }

        *native = value;

        rval.consumed = (1 + length);
    }

    return rval;
}

/*
 * Encode as Canonical OER.
 */
asn_enc_rval_t
NativeEnumerated_encode_oer(asn_TYPE_descriptor_t *td,
                            const asn_oer_constraints_t *constraints,
                            void *sptr, asn_app_consume_bytes_f *cb,
                            void *app_key) {
    asn_enc_rval_t er;
    long native;

    (void)constraints;

    if(!sptr) ASN__ENCODE_FAILED;

    native = *(const long *)sptr;

    if(native >= 0 && native <= 127) {
        /* #11.2 Short form */
        uint8_t b = native;
        er.encoded = 1;
        if(cb(&b, er.encoded, app_key) < 0) {
            ASN__ENCODE_FAILED;
        }
        ASN__ENCODED_OK(er);
    } else {
        /* #11.2 Long form */
        uint8_t buf[1 + sizeof(native)];
        uint8_t *b = &buf[sizeof(native)];  /* Last addressable */
        long final_pattern = -1 * (native < 0);

        for(;;) {
            *b-- = native;
            native >>= 8;
            if(native == final_pattern) {
                if(final_pattern) {
                    if((b[1] & 0x80)) break;
                } else {
                    if(!(b[1] & 0x80)) break;
                }
            }
        }
        *b = 0x80 | (&buf[sizeof(native)] - b);
        er.encoded = 1 + (&buf[sizeof(native)] - b);
        if(cb(b, er.encoded, app_key) < 0) {
            ASN__ENCODE_FAILED;
        }
        ASN__ENCODED_OK(er);
    }
}

#endif  /* ASN_DISABLE_OER_SUPPORT */
