#include "stdinc.h"
#include "whack.h"

enum
{
	DMaxFastLen	= 7,
	DBigLenCode	= 0x3c,		/* minimum code for large lenth encoding */
	DBigLenBits	= 6,
	DBigLenBase	= 1		/* starting items to encode for big lens */
};

static uchar lenval[1 << (DBigLenBits - 1)] =
{
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	3, 3, 3, 3, 3, 3, 3, 3,
	4, 4, 4, 4,
	5,
	6,
	255,
	255
};

static uchar lenbits[] =
{
	0, 0, 0,
	2, 3, 5, 5
};

static uchar offbits[16] =
{
	5, 5, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 12, 13
};

static ushort offbase[16] =
{
	0, 0x20,
	0x40, 0x60,
	0x80, 0xc0,
	0x100, 0x180,
	0x200, 0x300,
	0x400, 0x600,
	0x800, 0xc00,
	0x1000,
	0x2000
};

void
unwhackinit(Unwhack *uw)
{
	uw->err[0] = '\0';
}

int
unwhack(Unwhack *uw, uchar *dst, int ndst, uchar *src, int nsrc)
{
	uchar *s, *d, *dmax, *smax, lit;
	ulong uwbits, lithist;
	int i, off, len, bits, use, code, uwnbits, overbits;

	d = dst;
	dmax = d + ndst;

	smax = src + nsrc;
	uwnbits = 0;
	uwbits = 0;
	overbits = 0;
	lithist = ~0;
	while(src < smax || uwnbits - overbits >= MinDecode){
		while(uwnbits <= 24){
			uwbits <<= 8;
			if(src < smax)
				uwbits |= *src++;
			else
				overbits += 8;
			uwnbits += 8;
		}

		/*
		 * literal
		 */
		len = lenval[(uwbits >> (uwnbits - 5)) & 0x1f];
		if(len == 0){
			if(lithist & 0xf){
				uwnbits -= 9;
				lit = (uwbits >> uwnbits) & 0xff;
				lit &= 255;
			}else{
				uwnbits -= 8;
				lit = (uwbits >> uwnbits) & 0x7f;
				if(lit < 32){
					if(lit < 24){
						uwnbits -= 2;
						lit = (lit << 2) | ((uwbits >> uwnbits) & 3);
					}else{
						uwnbits -= 3;
						lit = (lit << 3) | ((uwbits >> uwnbits) & 7);
					}
					lit = (lit - 64) & 0xff;
				}
			}
			if(d >= dmax){
				snprint(uw->err, WhackErrLen, "too much output");
				return -1;
			}
			*d++ = lit;
			lithist = (lithist << 1) | (lit < 32) | (lit > 127);
			continue;
		}

		/*
		 * length
		 */
		if(len < 255)
			uwnbits -= lenbits[len];
		else{
			uwnbits -= DBigLenBits;
			code = ((uwbits >> uwnbits) & ((1 << DBigLenBits) - 1)) - DBigLenCode;
			len = DMaxFastLen;
			use = DBigLenBase;
			bits = (DBigLenBits & 1) ^ 1;
			while(code >= use){
				len += use;
				code -= use;
				code <<= 1;
				uwnbits--;
				if(uwnbits < 0){
					snprint(uw->err, WhackErrLen, "len out of range");
					return -1;
				}
				code |= (uwbits >> uwnbits) & 1;
				use <<= bits;
				bits ^= 1;
			}
			len += code;

			while(uwnbits <= 24){
				uwbits <<= 8;
				if(src < smax)
					uwbits |= *src++;
				else
					overbits += 8;
				uwnbits += 8;
			}
		}

		/*
		 * offset
		 */
		uwnbits -= 4;
		bits = (uwbits >> uwnbits) & 0xf;
		off = offbase[bits];
		bits = offbits[bits];

		uwnbits -= bits;
		off |= (uwbits >> uwnbits) & ((1 << bits) - 1);
		off++;

		if(off > d - dst){
			snprint(uw->err, WhackErrLen, "offset out of range: off=%d d=%ld len=%d nbits=%d", off, d - dst, len, uwnbits);
			return -1;
		}
		if(d + len > dmax){
			snprint(uw->err, WhackErrLen, "len out of range");
			return -1;
		}
		s = d - off;
		for(i = 0; i < len; i++)
			d[i] = s[i];
		d += len;
	}
	if(uwnbits < overbits){
		snprint(uw->err, WhackErrLen, "compressed data overrun");
		return -1;
	}

	len = d - dst;

	return len;
}
