// DWBS ------------------------------------------------------------------ DWBS
//
// PLATFORM		: ALL
// PRODUCT		: BIT_DEMON
// VISIBILITY	: PUBLIC
//
// DWBS ------------------------------------------------------------------ DWBS

#include <bdCore/bdStreams/bdStdioStreambuf.h>
#include <bdCore/bdLog/bdLog.h>

bdStdioStreambuf::bdStdioStreambuf()
: m_handle(BD_NULL)
{
}

bdStdioStreambuf::bdStdioStreambuf(FILE *const handle)
: m_handle(handle)
{
	BD_ASSERT(m_handle != BD_NULL, "bdStdioStreambuf has invalid handle.");
}

bdStdioStreambuf::~bdStdioStreambuf()
{
	if (m_handle != BD_NULL)
	{
		flush();
		m_handle = BD_NULL;
	}
}

bdUInt bdStdioStreambuf::bufGetFrom(bdNChar8 *const dest,
									  const bdUInt nbytes)
{
	BD_ASSERT(m_handle != BD_NULL, "bdStdioStreambuf has invalid handle.");
	return static_cast<bdUInt>(::fread(dest, 1, nbytes, m_handle)); 
}

bdUInt bdStdioStreambuf::bufPutTo(bdNChar8 *const src, 
									const bdUInt nbytes)
{
	BD_ASSERT(m_handle != BD_NULL, "bdStdioStreambuf has invalid handle.");
	return static_cast<bdUInt>(::fwrite(src, 1, nbytes, m_handle));
}

bdBool bdStdioStreambuf::bufSeek(const bdInt offset, 
								 const SeekFrom from)
{
	BD_ASSERT(m_handle != BD_NULL, "bdStdioStreambuf has invalid handle.");

	bdInt origin = 0;
	switch(from)
	{
		case BEG:
			origin = SEEK_SET;
			break;
		case CUR:
			origin = SEEK_CUR;
			break;
		case END:
			origin = SEEK_END;
			break;
		default:
		{
			bdBool fail = false;
			BD_ASSERT(fail, "Unknown SeekFrom for bdStdioStreambuf");		
		}
	}

	if (::fseek(m_handle, offset, origin) == 0)
	{
		return true;
	}

	return false;
}

bdBool bdStdioStreambuf::bufTell(bdUInt &offset) const
{
	BD_ASSERT(m_handle != BD_NULL, "bdStdioStreambuf has invalid handle.");
	bdInt success = ::ftell(m_handle);
	if (success != -1)
	{
		offset = static_cast<bdUInt>(success);
		return true;
	}

	return false;
}

void bdStdioStreambuf::bufFlush()
{
	BD_ASSERT(m_handle != BD_NULL, "bdStdioStreambuf has invalid handle.");
	::fflush(m_handle);
}



