/*
 * 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>

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;
        long value;

        if(length < 1 || length > sizeof(*native)) {
            ASN__DECODE_FAILED;
        }
        if((1 + length) > size) {
            ASN__DECODE_STARVED;
        }
        b++;
        bend = b + length;
        value = (*b & 0x80) ? -1 : 0; /* Determine sign */
        for(; b < bend; b++)
            value = (value << 8) | *b;

        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 */
