/* $Id$ */

#include <cstring>
#include <cerrno>
#include <unistd.h>
#include "throw.h"
#include "intl.h"
#include "file.h"

CFileBase::CFileBase(): m_fp(NULL)
{
}

CFileBase::~CFileBase()
{
}

void CFileBase::Close()
{
	if (!m_fp)
		return;

	if (fclose(m_fp) == -1)
		Throw(_("Cannot close %s: %s"), m_path.c_str(), strerror(errno));

	m_fp = NULL;
}

CFileRead::~CFileRead()
{
	Close();
}

void CFileRead::Open(const char *path)
{
	m_fp = fopen(path, "rb");
	if (!m_fp)
		Throw(_("Cannot open %s: %s"), path, strerror(errno));

	if (fseek(m_fp, 0L, SEEK_END) == -1)
		Throw(_("Cannot seek %s: %s"), path, strerror(errno));

	long sz(ftell(m_fp));
	if (sz == -1)
		Throw(_("Cannot read position of %s: %s"), path, strerror(errno));

	if (fseek(m_fp, 0L, SEEK_SET) == -1)
		Throw(_("Cannot rewind %s: %s"), path, strerror(errno));

	m_path = path;
	m_size = sz;
}

size_t CFileRead::Size() const
{
	return m_size;
}

size_t CFileRead::Read(void *buf, size_t sz)
{
	size_t rs(fread(buf, 1, sz, m_fp));
	if (rs == sz)
		return rs;

	if (feof(m_fp))
		return rs;

	Throw(_("Cannot read from %s: %s"), m_path.c_str(), strerror(errno));
}

CFileWrite::~CFileWrite()
{
	if (m_fp)
	{
		fclose(m_fp);
		unlink(m_path.c_str());
	}
}

void CFileWrite::Open(const char *path)
{
	m_fp = fopen(path, "wb");
	if (!m_fp)
		Throw(_("Cannot open %s: %s"), path, strerror(errno));

	m_path = path;
}

void CFileWrite::Write(const void *buf, size_t sz)
{
	size_t rs(fwrite(buf, sz, 1, m_fp));
	if (rs != 1)
		Throw(_("Cannot write to %s: %s"), m_path.c_str(), strerror(errno));
}
