/*
 * 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 <NativeInteger.h>
#include <errno.h>

asn_dec_rval_t
NativeInteger_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) {
    const asn_INTEGER_specifics_t *specs =
        (const asn_INTEGER_specifics_t *)td->specifics;
    asn_dec_rval_t rval = {RC_OK, 0};
    long *native = (long *)*nint_ptr;
    INTEGER_t tmpint;
    INTEGER_t *tmpintptr = &tmpint;

    memset(&tmpint, 0, sizeof(tmpint));

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

    /*
     * OPTIMIZATION: Encode directly rather than passing through INTEGER.
     * Saves a memory allocation.
     */
    rval = INTEGER_decode_oer(opt_codec_ctx, td, constraints,
                              (void **)&tmpintptr, ptr, size);
    if(rval.code != RC_OK) {
        ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &tmpint);
        return rval;
    }

    if(specs && specs->field_unsigned) {
        unsigned long ul;
        int ok = asn_INTEGER2ulong(&tmpint, &ul) == 0;
        ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &tmpint);
        if(ok) {
            *native = ul;
        } else {
            rval.code = RC_FAIL;
            return rval;
        }
    } else {
        long l;
        int ok = asn_INTEGER2long(&tmpint, &l) == 0;
        ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &tmpint);
        if(ok) {
            *native = l;
        } else {
            rval.code = RC_FAIL;
            return rval;
        }
    }

    return rval;
}

/*
 * Encode as Canonical OER.
 */
asn_enc_rval_t
NativeInteger_encode_oer(asn_TYPE_descriptor_t *td,
                         const asn_oer_constraints_t *constraints, void *sptr,
                         asn_app_consume_bytes_f *cb, void *app_key) {
    const asn_INTEGER_specifics_t *specs =
        (const asn_INTEGER_specifics_t *)td->specifics;
    INTEGER_t tmpint;
    long native;

    if(!sptr) ASN__ENCODE_FAILED;

    native = *(const long *)sptr;
    memset(&tmpint, 0, sizeof(tmpint));

    ASN_DEBUG("Encoding %s %ld as NativeInteger", td ? td->name : "", native);

    if((specs && specs->field_unsigned) ? asn_ulong2INTEGER(&tmpint, native)
                                        : asn_long2INTEGER(&tmpint, native)) {
        ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &tmpint);
        ASN__ENCODE_FAILED;
    } else {
        asn_enc_rval_t er =
            INTEGER_encode_oer(td, constraints, &tmpint, cb, app_key);
        ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &tmpint);
        return er;
    }
}

#endif  /* ASN_DISABLE_OER_SUPPORT */
