/******************************************************************************
 * to emulate the serial input and output of an 8051 controller               *
 * fileio.cc - file input and output                                          *
 ******************************************************************************/
#include <sys/types.h>
#include <iostream>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include "fileio.hh"

FileIO::FileIO()
{

	// make the input fifo
	if(mkfifo(DEF_INFILE, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) == -1) {
		if(errno != EEXIST) {
			std::cerr << "mkfifo(): Error number " << errno << " occourred: " << strerror(errno) << "\n";
			exit(-1);
		}
	}

	// the input fifo - non blocking
	if ((fdin = open(DEF_INFILE, O_RDONLY|O_NONBLOCK)) == -1) {
		std::cerr << "open(): Error number " << errno << " occourred: " << strerror(errno) << "\n";
		exit(-1);
	}

	// make the output fifo
	if(mkfifo(DEF_OUTFILE, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) == -1) {
		if(errno != EEXIST) {
			std::cerr << "mkfifo(): Error number " << errno << " occourred: " << strerror(errno) << "\n";
			exit(-1);
		}
	}

	// the output fifo
	if ((fdout = open(DEF_OUTFILE, O_RDWR|O_NONBLOCK)) == -1) {
		std::cerr << "open(): Error number " << errno << " occourred: " << strerror(errno) << "\n";
		exit(-1);
	}
}

FileIO::FileIO(const char *infile, const char *outfile)
{
	// make the input fifo
	if(mkfifo(infile, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) == -1) {
		if(errno != EEXIST) {
			std::cerr << "mkfifo(): Error number " << errno << " occourred: " << strerror(errno);
			exit(-1);
		}
	}

	// the input fifo - non blocking
	if ((fdin = open(infile, O_RDONLY|O_NONBLOCK)) == -1) {
		std::cerr << "open(): Error number " << errno << " occourred: " << strerror(errno);
		exit(-1);
	}

	// make the output fifo
	if(mkfifo(outfile, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) == -1) {
		if(errno != EEXIST) {
			std::cerr << "mkfifo(): Error number " << errno << " occourred: " << strerror(errno);
			exit(-1);
		}
	}

	// the output fifo
	if ((fdout = open(outfile, O_RDWR|O_NONBLOCK)) == -1) {
		std::cerr << "open(): Error number " << errno << " occourred: " << strerror(errno);
		exit(-1);
	}
}


FileIO::~FileIO()
{
	close(fdin);
	close(fdout);
}

int FileIO::SendByte(char b)
{
	int ret;

	if((ret = write(fdout, &b, 1)) != 1)
	{
		std::cerr << "write(): Error number " << errno << " occourred: " << strerror(errno);
		exit(-1);
	}

	return(ret);
}


int FileIO::RecvByte(char *b)
{
	int ret;

	ret = read(fdin, b, 1);

	if((ret == -1) && (errno != EAGAIN))
	{
		std::cerr << "read(): Error number " << errno << " occourred: " << strerror(errno);
		exit(-1);
	}

	return(ret);
}

// send a string
int FileIO::SendStr(char *str)
{
	int ret;

	if((ret = write(fdout, str, strlen(str))) != (int)strlen(str))
	{
		std::cerr << "write(): Error number " << errno << " occourred: " << strerror(errno);
		exit(-1);
	}

	return(ret);
}


int FileIO::RecvStr(char *str)
{
	int ret;

	ret = read(fdin, str, MAX_SIZ-1);
	str[MAX_SIZ] = 0;

	if((ret == -1) && (errno != EAGAIN))
	{
		std::cerr << "read(): Error number " << errno << " occourred: " << strerror(errno);
		exit(-1);
	}

	return(ret);
}
