/*-
 * Copyright (c) 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
 * Redistribution and modifications are permitted subject to BSD license.
 */
#include <asn_internal.h>
#include <ANY.h>
#include <assert.h>
#include <errno.h>

asn1_TYPE_descriptor_t asn1_DEF_ANY = {
	"ANY",
	OCTET_STRING_free,
	OCTET_STRING_print,
	asn_generic_no_constraint,
	OCTET_STRING_decode_ber,
	OCTET_STRING_encode_der,
	0,				/* Not implemented yet */
	ANY_encode_xer,
	0, /* Use generic outmost tag fetcher */
	0, 0, 0, 0,
	-1,	/* Both ways are fine (primitive and constructed) */
	0, 0,	/* No members */
	(void *)1	/* Special indicator that this is an ANY type */
};


asn_enc_rval_t
ANY_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr,
	int ilevel, enum xer_encoder_flags_e flags,
		asn_app_consume_bytes_f *cb, void *app_key) {

	(void)ilevel;
	(void)flags;
	(void)cb;
	(void)app_key;

	/*
	 * XER-encoding of ANY type is not supported.
	 */

	_ASN_ENCODE_FAILED;
}

struct _callback_arg {
	uint8_t *buffer;
	size_t offset;
	size_t size;
};

static int ANY__consume_bytes(const void *buffer, size_t size, void *key);

int
ANY_fromType(ANY_t *st, asn1_TYPE_descriptor_t *td, void *sptr) {
	struct _callback_arg arg;
	asn_enc_rval_t erval;

	if(!st || !td) {
		errno = EINVAL;
		return -1;
	}

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

	arg.offset = arg.size = 0;
	arg.buffer = 0;

	erval = der_encode(td, sptr, ANY__consume_bytes, &arg);
	if(erval.encoded == -1) {
		if(arg.buffer) FREEMEM(arg.buffer);
		return -1;
	}
	assert((size_t)erval.encoded == arg.offset);

	if(st->buf) FREEMEM(st->buf);
	st->buf = arg.buffer;
	st->size = arg.offset;

	return 0;
}

ANY_t *
ANY_new_fromType(asn1_TYPE_descriptor_t *td, void *sptr) {
	ANY_t tmp;
	ANY_t *st;

	if(!td || !sptr) {
		errno = EINVAL;
		return 0;
	}

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

	if(ANY_fromType(&tmp, td, sptr)) return 0;

	st = (ANY_t *)MALLOC(sizeof(*st));
	if(st) {
		*st = tmp;
		return st;
	} else {
		FREEMEM(tmp.buf);
		return 0;
	}
}

int
ANY_to_type(ANY_t *st, asn1_TYPE_descriptor_t *td, void **struct_ptr) {
	ber_dec_rval_t rval;
	void *newst = 0;

	if(!st || !td || !struct_ptr) {
		errno = EINVAL;
		return -1;
	}

	if(st->buf == 0) {
		/* Nothing to convert, make it empty. */
		*struct_ptr = (void *)0;
		return 0;
	}

	rval = ber_decode(td, (void **)&newst, st->buf, st->size);
	if(rval.code == RC_OK) {
		*struct_ptr = newst;
		return 0;
	} else {
		/* Remove possibly partially decoded data. */
		td->free_struct(td, newst, 0);
		return -1;
	}
}

static int ANY__consume_bytes(const void *buffer, size_t size, void *key) {
	struct _callback_arg *arg = (struct _callback_arg *)key;

	if((arg->offset + size) >= arg->size) {
		size_t nsize = (arg->size ? arg->size << 2 : 16) + size;
		void *p = REALLOC(arg->buffer, nsize);
		if(!p) return -1;
		(void *)arg->buffer = p;
		arg->size = nsize;
	}

	memcpy(arg->buffer + arg->offset, buffer, size);
	arg->offset += size;
	assert(arg->offset < arg->size);

	return 0;
}

