#include	"all.h"
#include	<fio.h>

Fbuffer**	Ffb = 0;
static	int	nfds = 0;
static	int	setfioexit = 0;
static	void	_F_extend(int);

static
void
Fdie(void)
{
	Fexit(0);
}

void
Finit(int fd, void *buf)
{
	Fbuffer *f;

	if(setfioexit == 0) {
		setfioexit = 1;
		atexit(Fdie);
	}
	if(fd >= nfds)
		_F_extend(fd);
	if(buf)
		Ffb[fd] = buf;
	else
	if(!Ffb[fd]) {
		Ffb[fd] = malloc(sizeof(Fbuffer));
		Ffb[fd]->flags |= FIO_MALLOCED;
	}
	f = Ffb[fd];
	_F_reset(f);
	f->offset = lseek(fd, 0L, 1);
	if(f->offset < 0)
		f->offset = 0;		/* file not been written yet */
}

Fbuffer*
_F_set(int fd)
{
	Fbuffer *f;

	if(fd >= nfds)
		_F_extend(fd);
	if((f = Ffb[fd]) == 0){
		Finit(fd, 0);
		f = Ffb[fd];
	}
	return(f);
}

void
_F_reset(Fbuffer *f)
{
	f->next = f->buf;
	f->lnext = f->buf;
	f->end = f->buf;
	f->flags &= ~FIO_MALLOCED;
	f->oflush = -1;
}

static
void
_F_extend(int fd)
{
	Fbuffer **base;
	int n;

	n = fd+1;
	base = (Fbuffer**)malloc(n * sizeof(Fbuffer*));
	if(Ffb) {
		if(n > nfds)
			n = nfds;
		memmove(base, Ffb, n*sizeof(Fbuffer*));
		for(n = nfds; n <= fd; n++)
			base[n] = 0;
		free(Ffb);
	} else
		memset(base, 0, n*sizeof(Fbuffer*));
	nfds = fd+1;
	Ffb = base;
}

void
Fexit(int type)
{
	int n;

	for(n = 0; n < nfds; n++)
		if(Ffb[n])
			if(type == 0)
				Fflush(n);
			else
				Fclose(n);
}
