/*******************************************************************************
 *	BFile.cc	BEAM BFile access class
 *			T.Barnaby,	BEAM Ltd,	27/11/95
 *******************************************************************************
 */
#include	<stdarg.h>
#include	<BFile.h>
#include	<sys/stat.h>
#include	<string.h>
#include	<errno.h>
#include	<unistd.h>

#define		STRBUF		10240

BFile::BFile(){
	ofile = NULL;
}

BFile::BFile(const BFile& file){
	open(file.ofileName, file.omode);
}

BFile& BFile::operator=(const BFile& file){
	open(file.ofileName, file.omode);
	return *this;
}

BFile::~BFile(){
	close();
}

BError BFile::open(BString name, BString mode){
	BError	err;
	
	ofileName = name;
	omode = mode;
	if(! (ofile = fopen64(name, mode)))
		err.set(-errno, BString("Cannot open file: ") + name + ": " + strerror(errno));

	return err;
}

BError BFile::open(FILE* file){
	BError	err;

	ofile = file;

	return err;
}

BError BFile::open(int fd, BString mode){
	BError	err;

	if(! (ofile = fdopen(fd, mode)))
		err.set(-errno, strerror(errno));

	return err;
}

BError BFile::close(){
	BError	err;
	int	e;
	
	if(ofile){
		if(e = fclose(ofile))
			err.set(-errno, strerror(errno));
		ofile = 0;
	}
	return err;
}

int BFile::isOpen(){
	return (ofile != 0);
}

int BFile::isEnd(){
	return feof(ofile);
}

FILE* BFile::getFd(){
	return ofile;
}

BUInt64 BFile::length(){
	struct stat64	s;
	
	fstat64(fileno(ofile), &s);
	return s.st_size;
}

int BFile::read(void* buf, int nbytes){
	return fread(buf, 1, nbytes, ofile);
}

int BFile::readString(BString& str){
	char	buf[STRBUF];

	if(fgets(buf, STRBUF)){
		str = buf;
		return str.len();
	}
	else {
		return 0;
	}
}

char* BFile::fgets(char* buf, size_t size){
	return ::fgets(buf, size, ofile);
}

int BFile::write(const void* buf, int nbytes){
	 return fwrite(buf, 1, nbytes, ofile);
}

int BFile::writeString(const BString& str){
	return fputs(str.retStr(), ofile);
}

int BFile::seek(BUInt64 pos){
	return fseeko64(ofile, pos, 0);
}

BUInt64	BFile::position(){
	return ftello64(ofile);
}

int BFile::setVBuf(char* buf, int mode, size_t size){
	return setvbuf(ofile, buf, mode, size);
}

int BFile::printf(const char* fmt, ...){
	va_list	ap;
	
	va_start(ap, fmt);
	return vfprintf(ofile, fmt, ap);
}

BError BFile::truncate(){
	BError	err;
	
	if(ftruncate(fileno(ofile), 0) < 0)
		err.set(-errno, strerror(errno));
	return err;
}

BError BFile::flush(){
	BError	err;
	
	if(::fflush(ofile) != 0)
		err.set(-errno, strerror(errno));
	
	return err;
}

BString BFile::fileName(){
	return ofileName;
}
