/*
 * Copyright (c) 2007 Lev Walkin <vlm@lionet.info>. All rights reserved.
 * Redistribution and modifications are permitted subject to BSD license.
 */
#include <asn_internal.h>
#include <per_support.h>
#include <constr_TYPE.h>
#include <per_opentype.h>

typedef struct uper_ugot_key {
	asn_per_data_t oldpd;	/* Old per data source */
	size_t unclaimed;
	size_t ot_moved;	/* Number of bits moved by OT processing */
	int repeat;
} uper_ugot_key;

static int uper_ugot_refill(asn_per_data_t *pd);
static int per_skip_bits(asn_per_data_t *pd, int skip_nbits);
static asn_dec_rval_t uper_sot_suck(asn_codec_ctx_t *, asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd);

/*
 * Encode an "open type field".
 * #10.1, #10.2
 */
int
uper_open_type_put(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
	void *buf;
	void *bptr;
	ssize_t size;
	size_t toGo;

	ASN_DEBUG("Open type put %s ...", td->name);

	size = uper_encode_to_new_buffer(td, constraints, sptr, &buf);
	if(size <= 0) return -1;

	for(bptr = buf, toGo = size; toGo;) {
		ssize_t maySave = uper_put_length(po, toGo);
		ASN_DEBUG("Prepending length %d to %s and allowing to save %d",
			(int)size, td->name, (int)maySave);
		if(maySave < 0) break;
		if(per_put_many_bits(po, bptr, maySave * 8)) break;
		bptr = (char *)bptr + maySave;
		toGo -= maySave;
	}

	FREEMEM(buf);
	if(toGo) return -1;

	ASN_DEBUG("Open type put %s of length %ld + overhead (1byte?)",
		td->name, (long)size);

	return 0;
}

int
aper_open_type_put(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
	void *buf;
	void *bptr;
	ssize_t size;
	size_t toGo;

	ASN_DEBUG("Open type put %s ...", td->name);

	size = aper_encode_to_new_buffer(td, constraints, sptr, &buf);
	if(size <= 0) return -1;

	for(bptr = buf, toGo = size; toGo;) {
		ssize_t maySave = aper_put_length(po, -1, toGo);
		if(maySave < 0) break;
		if(per_put_many_bits(po, bptr, maySave * 8)) break;
		bptr = (char *)bptr + maySave;
		toGo -= maySave;
	}

	FREEMEM(buf);
	if(toGo) return -1;

	ASN_DEBUG("Open type put %s of length %d + overhead (1byte?)",
			  td->name, size);

	return 0;
}

static asn_dec_rval_t
uper_open_type_get_simple(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td,
	asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
	asn_dec_rval_t rv;
	ssize_t chunk_bytes;
	int repeat;
	uint8_t *buf = 0;
	size_t bufLen = 0;
	size_t bufSize = 0;
	asn_per_data_t spd;
	size_t padding;

	_ASN_STACK_OVERFLOW_CHECK(ctx);

	ASN_DEBUG("Getting open type %s...", td->name);

	do {
		chunk_bytes = uper_get_length(pd, -1, &repeat);
		if(chunk_bytes < 0) {
			FREEMEM(buf);
			_ASN_DECODE_STARVED;
		}
		if(bufLen + chunk_bytes > bufSize) {
			void *ptr;
			bufSize = chunk_bytes + (bufSize << 2);
			ptr = REALLOC(buf, bufSize);
			if(!ptr) {
				FREEMEM(buf);
				_ASN_DECODE_FAILED;
			}
			buf = ptr;
		}
		if(per_get_many_bits(pd, buf + bufLen, 0, chunk_bytes << 3)) {
			FREEMEM(buf);
			_ASN_DECODE_STARVED;
		}
		bufLen += chunk_bytes;
	} while(repeat);

	ASN_DEBUG("Getting open type %s encoded in %ld bytes", td->name,
		(long)bufLen);

	memset(&spd, 0, sizeof(spd));
	spd.buffer = buf;
	spd.nbits = bufLen << 3;

	ASN_DEBUG_INDENT_ADD(+4);
	rv = td->uper_decoder(ctx, td, constraints, sptr, &spd);
	ASN_DEBUG_INDENT_ADD(-4);

	if(rv.code == RC_OK) {
		/* Check padding validity */
		padding = spd.nbits - spd.nboff;
                if ((padding < 8 ||
		/* X.691#10.1.3 */
		(spd.nboff == 0 && spd.nbits == 8 && spd.buffer == buf)) &&
                    per_get_few_bits(&spd, padding) == 0) {
			/* Everything is cool */
			FREEMEM(buf);
			return rv;
		}
		FREEMEM(buf);
		if(padding >= 8) {
			ASN_DEBUG("Too large padding %d in open type", (int)padding);
			_ASN_DECODE_FAILED;
		} else {
			ASN_DEBUG("Non-zero padding");
			_ASN_DECODE_FAILED;
		}
	} else {
		FREEMEM(buf);
		/* rv.code could be RC_WMORE, nonsense in this context */
		rv.code = RC_FAIL; /* No one would give us more */
	}

	return rv;
}

static asn_dec_rval_t GCC_NOTUSED
uper_open_type_get_complex(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td,
	asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
	uper_ugot_key arg;
	asn_dec_rval_t rv;
	ssize_t padding;

	_ASN_STACK_OVERFLOW_CHECK(ctx);

	ASN_DEBUG("Getting open type %s from %s", td->name,
		per_data_string(pd));
	arg.oldpd = *pd;
	arg.unclaimed = 0;
	arg.ot_moved = 0;
	arg.repeat = 1;
	pd->refill = uper_ugot_refill;
	pd->refill_key = &arg;
	pd->nbits = pd->nboff;	/* 0 good bits at this point, will refill */
	pd->moved = 0;	/* This now counts the open type size in bits */

	ASN_DEBUG_INDENT_ADD(+4);
	rv = td->uper_decoder(ctx, td, constraints, sptr, pd);
	ASN_DEBUG_INDENT_ADD(-4);

#define	UPDRESTOREPD	do {						\
	/* buffer and nboff are valid, preserve them. */		\
	pd->nbits = arg.oldpd.nbits - (pd->moved - arg.ot_moved);	\
	pd->moved = arg.oldpd.moved + (pd->moved - arg.ot_moved);	\
	pd->refill = arg.oldpd.refill;					\
	pd->refill_key = arg.oldpd.refill_key;				\
  } while(0)

	if(rv.code != RC_OK) {
		UPDRESTOREPD;
		return rv;
	}

	ASN_DEBUG("OpenType %s pd%s old%s unclaimed=%d, repeat=%d", td->name,
		per_data_string(pd),
		per_data_string(&arg.oldpd),
		(int)arg.unclaimed, (int)arg.repeat);

	padding = pd->moved % 8;
	if(padding) {
		int32_t pvalue;
		if(padding > 7) {
			ASN_DEBUG("Too large padding %d in open type",
				(int)padding);
			rv.code = RC_FAIL;
			UPDRESTOREPD;
			return rv;
		}
		padding = 8 - padding;
		ASN_DEBUG("Getting padding of %d bits", (int)padding);
		pvalue = per_get_few_bits(pd, padding);
		switch(pvalue) {
		case -1:
			ASN_DEBUG("Padding skip failed");
			UPDRESTOREPD;
			_ASN_DECODE_STARVED;
		case 0: break;
		default:
			ASN_DEBUG("Non-blank padding (%d bits 0x%02x)",
				(int)padding, (int)pvalue);
			UPDRESTOREPD;
			_ASN_DECODE_FAILED;
		}
	}
	if(pd->nboff != pd->nbits) {
		ASN_DEBUG("Open type %s overhead pd%s old%s", td->name,
			per_data_string(pd), per_data_string(&arg.oldpd));
		if(1) {
			UPDRESTOREPD;
			_ASN_DECODE_FAILED;
		} else {
			arg.unclaimed += pd->nbits - pd->nboff;
		}
	}

	/* Adjust pd back so it points to original data */
	UPDRESTOREPD;

	/* Skip data not consumed by the decoder */
	if(arg.unclaimed) {
		ASN_DEBUG("Getting unclaimed %d", (int)arg.unclaimed);
		switch(per_skip_bits(pd, arg.unclaimed)) {
		case -1:
			ASN_DEBUG("Claim of %d failed", (int)arg.unclaimed);
			_ASN_DECODE_STARVED;
		case 0:
			ASN_DEBUG("Got claim of %d", (int)arg.unclaimed);
			break;
		default:
			/* Padding must be blank */
			ASN_DEBUG("Non-blank unconsumed padding");
			_ASN_DECODE_FAILED;
		}
		arg.unclaimed = 0;
	}

	if(arg.repeat) {
		ASN_DEBUG("Not consumed the whole thing");
		rv.code = RC_FAIL;
		return rv;
	}

	return rv;
}


asn_dec_rval_t
uper_open_type_get(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td,
	asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {

	return uper_open_type_get_simple(ctx, td, constraints, sptr, pd);
}

int
uper_open_type_skip(asn_codec_ctx_t *ctx, asn_per_data_t *pd) {
	asn_TYPE_descriptor_t s_td;
	asn_dec_rval_t rv;

	s_td.name = "<unknown extension>";
	s_td.uper_decoder = uper_sot_suck;

	rv = uper_open_type_get(ctx, &s_td, 0, 0, pd);
	if(rv.code != RC_OK)
		return -1;
	else
		return 0;
}

/*
 * Internal functions.
 */

static asn_dec_rval_t
uper_sot_suck(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td,
	asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
	asn_dec_rval_t rv;

	(void)ctx;
	(void)td;
	(void)constraints;
	(void)sptr;

	while(per_get_few_bits(pd, 1) >= 0);

	rv.code = RC_OK;
	rv.consumed = pd->moved;

	return rv;
}

static int
uper_ugot_refill(asn_per_data_t *pd) {
	uper_ugot_key *arg = pd->refill_key;
	ssize_t next_chunk_bytes, next_chunk_bits;
	ssize_t avail;

	asn_per_data_t *oldpd = &arg->oldpd;

	ASN_DEBUG("REFILLING pd->moved=%ld, oldpd->moved=%ld",
		(long)pd->moved, (long)oldpd->moved);

	/* Advance our position to where pd is */
	oldpd->buffer = pd->buffer;
	oldpd->nboff  = pd->nboff;
	oldpd->nbits -= pd->moved - arg->ot_moved;
	oldpd->moved += pd->moved - arg->ot_moved;
	arg->ot_moved = pd->moved;

	if(arg->unclaimed) {
		/* Refill the container */
		if(per_get_few_bits(oldpd, 1))
			return -1;
		if(oldpd->nboff == 0) {
			assert(0);
			return -1;
		}
		pd->buffer = oldpd->buffer;
		pd->nboff = oldpd->nboff - 1;
		pd->nbits = oldpd->nbits;
		ASN_DEBUG("UNCLAIMED <- return from (pd->moved=%ld)",
			(long)pd->moved);
		return 0;
	}

	if(!arg->repeat) {
		ASN_DEBUG("Want more but refill doesn't have it");
		return -1;
	}

	next_chunk_bytes = uper_get_length(oldpd, -1, &arg->repeat);
	ASN_DEBUG("Open type LENGTH %ld bytes at off %ld, repeat %ld",
		(long)next_chunk_bytes, (long)oldpd->moved, (long)arg->repeat);
	if(next_chunk_bytes < 0) return -1;
	if(next_chunk_bytes == 0) {
		pd->refill = 0;	/* No more refills, naturally */
		assert(!arg->repeat);	/* Implementation guarantee */
	}
	next_chunk_bits = next_chunk_bytes << 3;
	avail = oldpd->nbits - oldpd->nboff;
	if(avail >= next_chunk_bits) {
		pd->nbits = oldpd->nboff + next_chunk_bits;
		arg->unclaimed = 0;
		ASN_DEBUG("!+Parent frame %ld bits, alloting %ld [%ld..%ld] (%ld)",
			(long)next_chunk_bits, (long)oldpd->moved,
			(long)oldpd->nboff, (long)oldpd->nbits,
			(long)(oldpd->nbits - oldpd->nboff));
	} else {
		pd->nbits = oldpd->nbits;
		arg->unclaimed = next_chunk_bits - avail;
		ASN_DEBUG("!-Parent frame %ld, require %ld, will claim %ld",
			(long)avail, (long)next_chunk_bits,
			(long)arg->unclaimed);
	}
	pd->buffer = oldpd->buffer;
	pd->nboff = oldpd->nboff;
	ASN_DEBUG("Refilled pd%s old%s",
		per_data_string(pd), per_data_string(oldpd));
	return 0;
}

static int
per_skip_bits(asn_per_data_t *pd, int skip_nbits) {
	int hasNonZeroBits = 0;
	while(skip_nbits > 0) {
		int skip;

		/* per_get_few_bits() is more efficient when nbits <= 24 */
		if(skip_nbits < 24)
			skip = skip_nbits;
		else
			skip = 24;
		skip_nbits -= skip;

		switch(per_get_few_bits(pd, skip)) {
		case -1: return -1;	/* Starving */
		case 0: continue;	/* Skipped empty space */
		default: hasNonZeroBits = 1; continue;
		}
	}
	return hasNonZeroBits;
}
