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

asn_dec_rval_t
OCTET_STRING_decode_oer(asn_codec_ctx_t *opt_codec_ctx,
                        asn_TYPE_descriptor_t *td,
                        const asn_oer_constraints_t *constraints, void **sptr,
                        const void *ptr, size_t size) {
    asn_OCTET_STRING_specifics_t *specs =
        td->specifics
            ? (asn_OCTET_STRING_specifics_t *)td->specifics
            : (asn_OCTET_STRING_specifics_t *)&asn_SPC_OCTET_STRING_specs;
    OCTET_STRING_t *st = (OCTET_STRING_t *)*sptr;
    const asn_oer_constraints_t *cts =
        constraints ? constraints : td->oer_constraints;
    ssize_t ct_size = cts ? cts->size : -1;
    asn_dec_rval_t rval = {RC_OK, 0};
    size_t expected_length = 0;

    size_t unit_bytes;
    switch(specs->subvariant) {
    default:
    case ASN_OSUBV_BIT:
        ASN_DEBUG("Invalid use of OCTET STRING to decode BIT STRING");
        ASN__DECODE_FAILED;
    case ASN_OSUBV_ANY:
        /* Fall through */
    case ASN_OSUBV_STR:
        unit_bytes = 1;
        break;
    case ASN_OSUBV_U16:
        unit_bytes = 2;
        break;
    case ASN_OSUBV_U32:
        unit_bytes = 4;
        break;
    }

    (void)opt_codec_ctx;

    if(!st) {
        st = (OCTET_STRING_t *)(*sptr = CALLOC(1, specs->struct_size));
        if(!st) ASN__DECODE_FAILED;
    }

    if(ct_size >= 0) {
        expected_length = unit_bytes * ct_size;
    } else {
        /*
         * X.696 (08/2015) #27.2
         * Encode length determinant as _number of octets_, but only
         * if upper bound is not equal to lower bound.
         */
        ssize_t len_len = oer_fetch_length(ptr, size, &expected_length);
        if(len_len > 0) {
            rval.consumed = len_len;
            ptr = (const char *)ptr + len_len;
            size -= len_len;
        } else if(len_len == 0) {
            ASN__DECODE_STARVED;
        } else if(len_len < 0) {
            ASN__DECODE_FAILED;
        }

        if(expected_length % unit_bytes != 0) {
            ASN_DEBUG(
                "Data size %zu bytes is not consistent with multiplier %zu",
                expected_length, unit_bytes);
            ASN__DECODE_FAILED;
        }
    }

    if(size < expected_length) {
        ASN__DECODE_STARVED;
    } else {
        uint8_t *buf = MALLOC(expected_length + 1);
        if(buf == NULL) {
            ASN__DECODE_FAILED;
        } else {
            memcpy(buf, ptr, expected_length);
            buf[expected_length] = '\0';
        }
        FREEMEM(st->buf);
        st->buf = buf;
        st->size = expected_length;

        rval.consumed += expected_length;
        return rval;
    }
}

/*
 * Encode as Canonical OER.
 */
asn_enc_rval_t
OCTET_STRING_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_OCTET_STRING_specifics_t *specs =
        td->specifics
            ? (asn_OCTET_STRING_specifics_t *)td->specifics
            : (asn_OCTET_STRING_specifics_t *)&asn_SPC_OCTET_STRING_specs;
    OCTET_STRING_t *st = (OCTET_STRING_t *)sptr;
    const asn_oer_constraints_t *cts =
        constraints ? constraints : td->oer_constraints;
    ssize_t ct_size = cts ? cts->size : -1;
    asn_enc_rval_t er = {0, 0, 0};

    if(!st) ASN__ENCODE_FAILED;

    ASN_DEBUG("Encoding %s %zu as OCTET STRING", td ? td->name : "", st->size);

    if(ct_size >= 0) {
        /*
         * Check that available data matches the constraint
         */
        size_t unit_bytes;
        switch(specs->subvariant) {
        default:
        case ASN_OSUBV_BIT:
            ASN_DEBUG("Invalid use of OCTET STRING to encode BIT STRING");
            ASN__ENCODE_FAILED;
        case ASN_OSUBV_ANY:
            /* Fall through */
        case ASN_OSUBV_STR:
            unit_bytes = 1;
            break;
        case ASN_OSUBV_U16:
            unit_bytes = 2;
            break;
        case ASN_OSUBV_U32:
            unit_bytes = 4;
            break;
        }

        if(st->size != unit_bytes * (size_t)ct_size) {
            ASN_DEBUG(
                "Trying to encode %s (%zu bytes) which doesn't fit SIZE "
                "constraint (%zu)",
                td->name, st->size, ct_size);
            ASN__ENCODE_FAILED;
        }
    } else {
        /*
         * X.696 (08/2015) #27.2
         * Encode length determinant as _number of octets_, but only
         * if upper bound is not equal to lower bound.
         */
        ssize_t ret = oer_serialize_length(st->size, cb, app_key);
        if(ret < 0) {
            ASN__ENCODE_FAILED;
        }
        er.encoded += ret;
    }

    er.encoded += st->size;
    if(cb(st->buf, st->size, app_key) < 0) {
        ASN__ENCODE_FAILED;
    } else {
        ASN__ENCODED_OK(er);
    }
}

#endif  /* ASN_DISABLE_OER_SUPPORT */
