#include <cstring>
#include "File.hpp"

CFile::CFile()
{
	file_fd = NULL;
	mem_file = NULL;
	filesize = 0;
	Pos = 0;
}

CFile::CFile(const char * filepath, const char * mode)
{
	file_fd = NULL;
	open(filepath, mode);
}

CFile::CFile(const u8 * mem, int size)
{
	file_fd = NULL;
	open(mem, size);
}

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

int CFile::open(const char * filepath, const char * mode)
{
	close();

	file_fd = fopen(filepath, mode);
	if(!file_fd)
		return -1;

	fseek(file_fd, 0, SEEK_END);
	filesize = ftell(file_fd);
	rewind();

	return 0;
}

int CFile::open(const u8 * mem, int size)
{
	close();

	mem_file = mem;
	filesize = size;

	return 0;
}

void CFile::close()
{
	if(file_fd)
		fclose(file_fd);

	file_fd = NULL;
	mem_file = NULL;
	filesize = 0;
	Pos = 0;
}

int CFile::read(u8 * ptr, size_t size)
{
	if(file_fd)
	{
		int ret = fread(ptr, 1, size, file_fd);
		if(ret > 0)
			Pos += ret;
		return ret;
	}

	int readsize = size;

	if(readsize > (long int) filesize-Pos)
		readsize = filesize-Pos;

	if(readsize <= 0)
		return readsize;

	if(mem_file != NULL)
	{
		memcpy(ptr, mem_file+Pos, readsize);
		Pos += readsize;
		return readsize;
	}

	return -1;
}

int CFile::write(const u8 * ptr, size_t size)
{
/*
	if(size < 0)
		return size;
*/
	if(file_fd)
	{
		int ret = fwrite(ptr, 1, size, file_fd);
		if(ret > 0)
			Pos += ret;
		return ret;
	}

	return -1;
}

int CFile::seek(long int offset, int origin)
{
	int ret = 0;

	if(origin == SEEK_SET)
		Pos = offset;
	else if(origin == SEEK_CUR)
		Pos += offset;
	else if(origin == SEEK_END)
		Pos = filesize+offset;
	if(Pos < 0)
	{
		Pos = 0;
		return -1;
	}

	if(file_fd)
		ret = fseek(file_fd, Pos, SEEK_SET);

	if(mem_file != NULL && Pos > (long int)filesize)
	{
		Pos = filesize;
		return -1;
	}

	return ret;
}

