/* helper functions to dela with asn1c data types */

/* (C) 2014-2015 by Harald Welte <laforge@gnumonks.org>
 * All Rights Reserved
 *
 * Redistribution and modifications are permitted subject to BSD license
 * contained in COPYING file.
 */

#include <string.h>
#include <errno.h>
#include <arpa/inet.h>

#include "asn1helpers.h"
#include "asn_internal.h"

#define ASN1C_ASSERT(exp)    \
        if (!(exp)) { \
                fprintf(stderr, "Assert failed %s %s:%d\n", #exp, __FILE__, __LINE__); \
                abort(); \
        }

void asn1_u32_to_bitstring(BIT_STRING_t *bitstr, uint32_t *buf, uint32_t in)
{
	*buf = htonl(in);
	bitstr->buf = (uint8_t *) buf;
	bitstr->size = sizeof(uint32_t);
	bitstr->bits_unused = 0;
}

void asn1_u28_to_bitstring(BIT_STRING_t *bitstr, uint32_t *buf, uint32_t in)
{
	*buf = htonl(in<<4);
	bitstr->buf = (uint8_t *) buf;
	bitstr->size = sizeof(uint32_t);
	bitstr->bits_unused = 4;
}

void asn1_u24_to_bitstring(BIT_STRING_t *bitstr, uint32_t *buf, uint32_t in)
{
	*buf = htonl(in<<8);
	bitstr->buf = (uint8_t *) buf;
	bitstr->size = 24/8;
	bitstr->bits_unused = 0;
}

int BIT_STRING_fromBuf(BIT_STRING_t *st, const uint8_t *str, unsigned int bit_len)
{
	void *buf;
	unsigned int len = bit_len / 8;

	if (bit_len % 8)
		len++;

	if (!st || (!str && len)) {
		errno = EINVAL;
		return -1;
	}

	if (!str) {
		FREEMEM(st->buf);
		st->buf = 0;
		st->size = 0;
		st->bits_unused = 0;
		return 0;
	}

	buf = MALLOC(len);
	if (!buf) {
		errno = ENOMEM;
		return -1;
	}

	memcpy(buf, str, len);
	FREEMEM(st->buf);
	st->buf = buf;
	st->size = len;
	st->bits_unused = (len * 8) - bit_len;

	return 0;
}

void asn1_u32_to_str(OCTET_STRING_t *str, uint32_t *buf, uint32_t in)
{
	*buf = htonl(in);
	str->buf = (uint8_t *) buf;
	str->size = sizeof(uint32_t);
}

void asn1_u16_to_str(OCTET_STRING_t *str, uint16_t *buf, uint16_t in)
{
	*buf = htons(in);
	str->buf = (uint8_t *) buf;
	str->size = sizeof(uint16_t);
}

void asn1_u8_to_str(OCTET_STRING_t *str, uint8_t *buf, uint8_t in)
{
	*buf = in;
	str->buf = buf;
	str->size = sizeof(uint8_t);
}

int asn1_strncpy(char *out, const OCTET_STRING_t *in, size_t n)
{
	size_t cpylen = n-1;

	if (in->size < cpylen)
		cpylen = in->size;

	strncpy(out, (char *)in->buf, cpylen);
	out[cpylen] = '\0';

	return cpylen;
}

uint32_t asn1str_to_u32(const OCTET_STRING_t *in)
{
	ASN1C_ASSERT(in && in->size == sizeof(uint32_t));
	return ntohl(*(uint32_t *)in->buf);
}

uint16_t asn1str_to_u16(const OCTET_STRING_t *in)
{
	ASN1C_ASSERT(in && in->size == sizeof(uint16_t));
	return ntohs(*(uint16_t *)in->buf);
}

uint8_t asn1str_to_u8(const OCTET_STRING_t *in)
{
	ASN1C_ASSERT(in && in->size == sizeof(uint8_t));
	return *(uint8_t *)in->buf;
}

uint32_t asn1bitstr_to_u32(const BIT_STRING_t *in)
{
	ASN1C_ASSERT(in && in->size == sizeof(uint32_t));

	return ntohl(*(uint32_t *)in->buf);
}

uint32_t asn1bitstr_to_u28(const BIT_STRING_t *in)
{
	ASN1C_ASSERT(in && in->size == sizeof(uint32_t) && in->bits_unused == 4);

	return ntohl(*(uint32_t *)in->buf) >> 4;
}

uint32_t asn1bitstr_to_u24(const BIT_STRING_t *in)
{
	ASN1C_ASSERT(in && in->size == 3);

	return ntohl(*(uint32_t *)in->buf) >> 8;
}
