#ifdef UEMF
	#include	"uemf.h"
#else
	#include	"basic/basicInternal.h"
#endif

static int	getBinBlockSize(int size);
static int	ringqGrow(ringq_t *rq);

#define RINGQ_LEN(rq) \
	((rq->servp > rq->endp) ? \
		(rq->buflen + (rq->endp - rq->servp)) : \
		(rq->endp - rq->servp))



int			ringqGrowCalls = 0;

int ringqOpen(ringq_t *rq, int initSize, int maxsize)
{
	int	increment;

	a_assert(rq);
	a_assert(initSize >= 0);

	increment = getBinBlockSize(initSize);
	if ((rq->buf = balloc(B_L, (increment))) == NULL) {
		return -1;
	}
	rq->maxsize = maxsize;
	rq->buflen = increment;
	rq->increment = increment;
	rq->endbuf = &rq->buf[rq->buflen];
	rq->servp = rq->buf;
	rq->endp = rq->buf;
	*rq->servp = '\0';
	return 0;
}

int ringqInsertc(ringq_t *rq, char_t c)
{
	char_t *cp;

	a_assert(rq);
	a_assert(rq->buflen == (rq->endbuf - rq->buf));

	if (ringqPutBlkMax(rq) < (int) sizeof(char_t) && !ringqGrow(rq)) {
		return -1;
	}
	if (rq->servp <= rq->buf) {
		rq->servp = rq->endbuf;
	}
	cp = (char_t*) rq->servp;
	*--cp = (char_t) c;
	rq->servp = (unsigned char *) cp;
	return 0;
}

int ringqPutc(ringq_t *rq, char_t c)
{
	char_t *cp;

	a_assert(rq);
	a_assert(rq->buflen == (rq->endbuf - rq->buf));

	if ((ringqPutBlkMax(rq) < (int) sizeof(char_t)) && !ringqGrow(rq)) {
		return -1;
	}

	cp = (char_t*) rq->endp;
	*cp++ = (char_t) c;
	rq->endp = (unsigned char *) cp;
	if (rq->endp >= rq->endbuf) {
		rq->endp = rq->buf;
	}
	return 0;
}

int ringqGetc(ringq_t *rq)
{
	char_t	c;
	char_t*	cp;

	a_assert(rq);
	a_assert(rq->buflen == (rq->endbuf - rq->buf));

	if (rq->servp == rq->endp) {
		return -1;
	}

	cp = (char_t*) rq->servp;
	c = *cp++;
	rq->servp = (unsigned char *) cp;
	if (rq->servp >= rq->endbuf) {
		rq->servp = rq->buf;
	}
	return (int) ((unsigned char) c);
}

int ringqLen(ringq_t *rq)
{
	a_assert(rq);
	a_assert(rq->buflen == (rq->endbuf - rq->buf));

	if (rq->servp > rq->endp) {
		return rq->buflen + rq->endp - rq->servp;
	} else {
		return rq->endp - rq->servp;
	}
}

void ringqAddNull(ringq_t *rq)
{
	a_assert(rq);
	a_assert(rq->buflen == (rq->endbuf - rq->buf));

	*((char_t*) rq->endp) = (char_t) '\0';
}

int ringqPutStr(ringq_t *rq, char_t *str)
{
	int		rc;

	a_assert(rq);
	a_assert(str);
	a_assert(rq->buflen == (rq->endbuf - rq->buf));

	rc = ringqPutBlk(rq, (unsigned char*) str, gstrlen(str) * sizeof(char_t));
	*((char_t*) rq->endp) = (char_t) '\0';
	return rc;
}


void ringqClose(ringq_t *rq)
{
	a_assert(rq);
	a_assert(rq->buflen == (rq->endbuf - rq->buf));

	if (rq == NULL) {
		return;
	}

	ringqFlush(rq);
	bfree(B_L, (char*) rq->buf);
	rq->buf = NULL;
}


void ringqFlush(ringq_t *rq)
{
	a_assert(rq);
	a_assert(rq->servp);

	rq->servp = rq->buf;
	rq->endp = rq->buf;
	if (rq->servp) {
		*rq->servp = '\0';
	}
}


#ifdef UNICODE
int ringqPutStrA(ringq_t *rq, char *str)
{
	int		rc;

	a_assert(rq);
	a_assert(str);
	a_assert(rq->buflen == (rq->endbuf - rq->buf));

	rc = ringqPutBlk(rq, (unsigned char*) str, strlen(str));
	rq->endp[0] = '\0';
	return rc;
}

int ringqGetcA(ringq_t *rq)
{
	unsigned char	c;

	a_assert(rq);
	a_assert(rq->buflen == (rq->endbuf - rq->buf));

	if (rq->servp == rq->endp) {
		return -1;
	}

	c = *rq->servp++;
	if (rq->servp >= rq->endbuf) {
		rq->servp = rq->buf;
	}
	return c;
}

int ringqInsertcA(ringq_t *rq, char c)
{
	a_assert(rq);
	a_assert(rq->buflen == (rq->endbuf - rq->buf));

	if (ringqPutBlkMax(rq) == 0 && !ringqGrow(rq)) {
		return -1;
	}
	if (rq->servp <= rq->buf) {
		rq->servp = rq->endbuf;
	}
	*--rq->servp = (unsigned char) c;
	return 0;
}

int ringqPutcA(ringq_t *rq, char c)
{
	a_assert(rq);
	a_assert(rq->buflen == (rq->endbuf - rq->buf));

	if (ringqPutBlkMax(rq) == 0 && !ringqGrow(rq)) {
		return -1;
	}

	*rq->endp++ = (unsigned char) c;
	if (rq->endp >= rq->endbuf) {
		rq->endp = rq->buf;
	}
	return 0;
}

#endif /* UNICODE */

void ringqGetBlkAdj(ringq_t *rq, int size)
{
	a_assert(rq);
	a_assert(rq->buflen == (rq->endbuf - rq->buf));
	a_assert(0 < size && size < rq->buflen);

	rq->servp += size;
	if (rq->servp >= rq->endbuf) {
		rq->servp -= rq->buflen;
	}

	if (rq->servp >= rq->endbuf) {
		error(E_L, E_LOG, T("Bad serv pointer"));
		ringqFlush(rq);
	}
}

int ringqGetBlkMax(ringq_t *rq)
{
	int		len, in_a_line;

	a_assert(rq);
	a_assert(rq->buflen == (rq->endbuf - rq->buf));

	len = RINGQ_LEN(rq);
	in_a_line = rq->endbuf - rq->servp;

	return min(in_a_line, len);
}

int ringqGetBlk(ringq_t *rq, unsigned char *buf, int size)
{
	int		this, bytes_read;

	a_assert(rq);
	a_assert(rq->buflen == (rq->endbuf - rq->buf));
	a_assert(buf);
	a_assert(0 <= size && size < rq->buflen);

	bytes_read = 0;
	while (size > 0) {
		this = ringqGetBlkMax(rq);
		this = min(this, size);
		if (this <= 0) {
			break;
		}

		memcpy(buf, rq->servp, this);
		buf += this;
		rq->servp += this;
		size -= this;
		bytes_read += this;

		if (rq->servp >= rq->endbuf) {
			rq->servp = rq->buf;
		}
	}
	return bytes_read;
}

int ringqPutBlk(ringq_t *rq, unsigned char *buf, int size)
{
	int		this, bytes_put;

	a_assert(rq);
	a_assert(rq->buflen == (rq->endbuf - rq->buf));
	a_assert(buf);
	a_assert(0 <= size);

	bytes_put = 0;
	while (size > 0) {
		this = min(ringqPutBlkMax(rq), size);
		if (this <= 0) {
			if (! ringqGrow(rq)) {
				break;
			}
			this = min(ringqPutBlkMax(rq), size);
		}

		memcpy(rq->endp, buf, this);
		buf += this;
		rq->endp += this;
		size -= this;
		bytes_put += this;

		if (rq->endp >= rq->endbuf) {
			rq->endp = rq->buf;
		}
	}
	return bytes_put;
}


int ringqPutBlkMax(ringq_t *rq)
{
	int		space, in_a_line;

	a_assert(rq);
	a_assert(rq->buflen == (rq->endbuf - rq->buf));
	
	space = rq->buflen - RINGQ_LEN(rq) - 1;
	in_a_line = rq->endbuf - rq->endp;

	return min(in_a_line, space);
}


void ringqPutBlkAdj(ringq_t *rq, int size)
{
	a_assert(rq);
	a_assert(rq->buflen == (rq->endbuf - rq->buf));
	a_assert(0 <= size && size < rq->buflen);

	rq->endp += size;
	if (rq->endp >= rq->endbuf) {
		rq->endp -= rq->buflen;
	}

	if (rq->endp >= rq->endbuf) {
		error(E_L, E_LOG, T("Bad end pointer"));
		ringqFlush(rq);
	}
}



static int ringqGrow(ringq_t *rq)
{
	int 			rq_len;
	unsigned char	*reall_buf;


	a_assert(rq);

	if (rq->maxsize >= 0 && rq->buflen >= rq->maxsize) {
		return 0;
	}

	rq_len = ringqLen(rq);

	if ((reall_buf = balloc(B_L, rq->buflen + rq->increment)) == NULL) {
		return 0;
	}
	ringqGetBlk(rq, reall_buf, ringqLen(rq));
	bfree(B_L, (char*) rq->buf);

#ifdef OLD
	rq->endp = &reall_buf[endp];
	rq->servp = &reall_buf[servp];
	rq->endbuf = &reall_buf[rq->buflen];
	rq->buf = reall_buf;
#endif

	rq->buflen += rq->increment;
	rq->endp = reall_buf;
	rq->servp = reall_buf;
	rq->buf = reall_buf;
	rq->endbuf = &rq->buf[rq->buflen];

	ringqPutBlk(rq, reall_buf, rq_len);

	rq->increment = getBinBlockSize(2 * rq->increment);

	return 1;
}

static int	getBinBlockSize(int size)
{
	int	q;

	size = size >> B_SHIFT;
	for (q = 0; size; size >>= 1) {
		q++;
	}
	return (1 << (B_SHIFT + q));
}

