static char sccsid[]="%Z% %M% %I% %E% %U%";
#include "akxcommon.h"

int akxtmmanfunc(cmd,pM,s,len,_opt_malloc)
int  cmd;	/* 0/1/2=non/set/cpy */
MCAT *pM;
char *s;
int len;
char *(*_opt_malloc)();
{
	char *p;
	int extlen,alen;

	if (!pM) return -1;
/*
if (_opt_malloc) printf("akxtmmanfunc: len=%d\n",len);
*/
	if ((cmd && !s) || len<=0) return (pM->mc_ipos);
	if (!(extlen=pM->mc_extlen)) extlen = 65536;
	if (pM->mc_alclen<=0 || !pM->mc_bufp) {
		pM->mc_alclen = 0;
		pM->mc_extcnt = 0;
		pM->mc_ipos   = 0;
		while (pM->mc_ipos+len > pM->mc_alclen) {
			if (pM->mc_maxcnt>0 && pM->mc_extcnt>=pM->mc_maxcnt) return -16;
			pM->mc_alclen += extlen;
			pM->mc_extcnt++;
		}
#if 1
		alen = pM->mc_alclen;
		if (_opt_malloc) {
/*
printf("akxtmmanfunc:1: alen=%d\n",alen);
*/
			if (!(p=_opt_malloc(pM->mc_id[1],alen))) return -4;
		}
		else {
			if (!(p=Malloc(alen))) return -4;
		}
		pM->mc_bufp = p;
#else
		if (!(pM->mc_bufp=Malloc(pM->mc_alclen))) return -4;
#endif
	}
	if (pM->mc_ipos+len > pM->mc_alclen) {
		while (pM->mc_ipos+len > pM->mc_alclen) {
			if (pM->mc_maxcnt>0 && pM->mc_extcnt>=pM->mc_maxcnt) return -16;
			pM->mc_alclen += extlen;
			pM->mc_extcnt++;
		}
#if 1
		alen = pM->mc_alclen;
		if (_opt_malloc) {
/*
printf("akxtmmanfunc:2: alen=%d\n",alen);
*/
			if (!(p=_opt_malloc(pM->mc_id[1],alen))) return -8;
			memcpy(p,pM->mc_bufp,pM->mc_ipos);
		}
		else {
			if (!(p=Realloc(pM->mc_bufp,alen))) return -8;
		}
#else
		if (!(p=Realloc(pM->mc_bufp,pM->mc_alclen))) return -8;
#endif
		pM->mc_bufp = p;
	}
	if (cmd == 1)
		memset(pM->mc_bufp+pM->mc_ipos,*s,len);
	else if (cmd == 2)
		memcpy(pM->mc_bufp+pM->mc_ipos,s,len);
	pM->mc_ipos += len;
	return (pM->mc_ipos);
}

int akxtmman(cmd,pM,s,len)
int  cmd;	/* 0/1/2=non/set/cpy */
MCAT *pM;
char *s;
int len;
{
	return akxtmmanfunc(cmd,pM,s,len,NULL);
}

int akxtmcat(pM,s,len)
MCAT *pM;
char *s;
int len;
{
	return akxtmman(2,pM,s,len);
}

int akxtmset(pM,c,len)
MCAT *pM;
int  c;
int len;
{
	char s[1];

	s[0] = c;
	return akxtmman(1,pM,s,len);
}

int akxtmexp(pM,len)
MCAT *pM;
int len;
{
	return akxtmman(0,pM,0,len);
}

int akxtmcatz(pM,s,len)
MCAT *pM;
char *s;
int len;
{
	int n,ipos;

	n = pM->mc_ipos;
	if (len < 0) return n;
	else if (!len) s = "";
	else if (!s) return n;
	ipos = akxtmman(0,pM,0,len+1);
	if (ipos > 0) {
		ipos--;
		pM->mc_ipos = ipos;
		memzcpy(pM->mc_bufp+n,s,len);
	}
	return ipos;
}

int akxtmcats(pM,s)
MCAT *pM;
char *s;
{
#if 1
	if (!s) s = "";
	return akxtmcatz(pM,s,strlen(s));
#else
	int ipos;

	if (!s) s = "";
	ipos=akxtmcat(pM,s,strlen(s)+1);
	if (ipos>0) {
		ipos--;
		pM->mc_ipos=ipos;
	}
	return (ipos);
#endif
}

int akxtmcat2(pM,s,len)
MCAT2 *pM;
char *s;
int len;
{
	return akxtmmanfunc(2,pM,s,len,pM->mc_malloc);
}

int akxtmcats2(pM,s)
MCAT2 *pM;
char *s;
{
	if (!s) s = "";
	return akxtmcatz2(pM,s,strlen(s));
}

int akxtmcatz2(pM,s,len)
MCAT2 *pM;
char *s;
int len;
{
	int n,ipos;

	n = pM->mc_ipos;
	if (len < 0) return n;
	else if (!len) s = "";
	else if (!s) return n;
	ipos = akxtmmanfunc(0,pM,0,len+1,pM->mc_malloc);
	if (ipos > 0) {
		ipos--;
		pM->mc_ipos = ipos;
		memzcpy(pM->mc_bufp+n,s,len);
	}
	return ipos;
}
