/*	TERM7.C		Subroutines for TERM.C - Part 7
			ASCII file transfer
	14 Feb 1988	A.Herrmann
*/

#include "stdio.h"
#include "term.h"
#include "term.e"


#define	FBDECR	1024			/* file buffer decrement	*/
#define FBSIZE	32*FBDECR		/* file buffer size		*/

static char *fbp;			/* file buffer pointers		*/
static char *fbbeg=NULL, *fbend;


int initfb()	/* initializes file buffer; Returns true buffer size	*/
		/* Note: Only one buffer can be open at a time!		*/
{
	static int fblen;
	char *alloc();

	if (fbbeg) return NULL;		/* Buffer already opened?	*/
	fblen = FBSIZE; 
	while ((fbbeg=fbp=alloc(fblen))==NULL && (fblen -=FBDECR) != 0) ;
	fbend = fbbeg + fblen - 1;
	return fblen;
}

	
FILE *iofopen(name,mode)	/* opens input/output file name in mode	*/
char *name, *mode;		/* Inits file buffer			*/
				/* Returns file pointer / NULL if error */
{
	if (initfb()) return fopen(name,mode);
	return NULL;
}


int iofclose(fp,item)		/* flushes IO file buffer and closes file fp */
FILE **fp;			/* Resets file pointer fp to NULL	     */
int item;			/* Returns EOF iff error		     */
{
	if ((item==IFITEM || flushfb()) && fclose(*fp)!=EOF) {
		free(fbbeg);
		return (fbbeg = *fp = NULL);
	}
	return EOF;
}


int gf()	/* gets next character ch from input file		*/
		/* Returns EOF on EOF or error, else ch			*/
		/* Note: LFs from input file are suppressed here	*/
{
	static int ch;

	do {
		if (fbp==fbbeg && !loadfb()) return EOF;
		ch = *fbp++;
		if (fbp>fbend) fbp = fbbeg;
	} while (ch==_LF && !passlf);
	return ch;
}


int loadfb()	/* loads buffer with next input file segment	*/
		/* beginning at fbbeg				*/
		/* Returns FALSE iff no input, else TRUE	*/
{
	static int c;
	static char *p;

	stophost();
	p=fbbeg;
	do {
		c=getc(input);		/* It's gotta be integer!	*/
		*p++=c;
	} while (p<=fbend && c!=EOF); 
	if (bufclr) wakehost();
	return (p!=fbbeg);
}


int pf(ch)	/* outputs character ch to output file	*/
char ch;	/* Returns EOF on error, else ch	*/
{
	*fbp++ = ch;
	if (fbp>fbend && !flushfb()) return EOF;
	return ch;
}


int flushfb()	/* flushes current IO file buffer to file	 */
		/* beginning at fbbeg up to, but NOT incl. fbp */
		/* Returns FALSE iff output error, else TRUE	 */
{
	static char *p;
	static int c;

	stophost();
	c = NULL;
	for (p=fbbeg; p<fbp && (c=putc(*p,output))!=EOF; p++) ;
	fbp = fbbeg;
	if (bufclr) wakehost();
	return (c!=EOF);
}
