/*
 * 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_DEF_OCTET_STRING.specifics;
    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_DEF_OCTET_STRING.specifics;
    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 %d 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 (%d)",
                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 */
