/*
	ZBinaryFileReader.cpp
	Author: Patrick Baggett <ptbaggett@762studios.com>
	Created: 3/6/2013

	Purpose: 

	Reads a binary stream from a SST_File handle. NOTE: On 32-bit platforms, only files up to 4GB are supported.

	License:

	TODO

*/

#include <ZUtil/ZBinaryFileReader.hpp>

/*************************************************************************/

ZBinaryFileReader::ZBinaryFileReader(SST_File handle, SST_ByteOrder bo)
: ZBinaryReader(bo), fp(handle)
{
	uint64_t size64;
	uint64_t offset64;

	SST_OS_GetFilePointer(fp, &offset64);
	size64 = SST_OS_GetFileSize(fp);

	//Downcast (potentially) to size_t
	Size = (size_t)size64;
	Offset = (size_t)offset64;
}

/*************************************************************************/

uint8_t ZBinaryFileReader::ReadU8()
{
	uint8_t retval;

	SST_OS_ReadFile(fp, &retval, sizeof(uint8_t));

	++Offset;

	return retval;
}

/*************************************************************************/

uint16_t ZBinaryFileReader::ReadU16()
{
	uint16_t value;

	SST_OS_ReadFile(fp, &value, sizeof(uint16_t));

	if(GetStreamByteOrder() != SST_BYTEORDER_HOST)
		value = SST_OS_ByteSwap16(value);

	Offset += sizeof(uint16_t);
	return value;
}

/*************************************************************************/

uint32_t ZBinaryFileReader::ReadU32()
{
	uint32_t value;
	SST_OS_ReadFile(fp, &value, sizeof(uint32_t));


	if(GetStreamByteOrder() != SST_BYTEORDER_HOST)
		value = SST_OS_ByteSwap32(value);

	Offset += sizeof(uint32_t);
	return value;
}

/*************************************************************************/

uint64_t ZBinaryFileReader::ReadU64()
{
	uint64_t value;
	SST_OS_ReadFile(fp, &value, sizeof(uint64_t));


	if(GetStreamByteOrder() != SST_BYTEORDER_HOST)
		value = SST_OS_ByteSwap64(value);

	Offset += sizeof(uint64_t);
	return value;
}

/*************************************************************************/

void ZBinaryFileReader::ReadU8Array(uint8_t* ptr, size_t count)
{
	SST_OS_ReadFile(fp, ptr, count);

	Offset += count;
}

/*************************************************************************/

void ZBinaryFileReader::ReadU16Array(uint16_t* ptr, size_t count)
{
	if(GetStreamByteOrder() == SST_BYTEORDER_HOST)
	{
		SST_OS_ReadFile(fp, ptr, sizeof(uint16_t) * count);
		Offset += sizeof(uint16_t) * count;
	}
	else
	{
		for(size_t i=0; i<count; i++)
			ptr[i] = ReadU16();
	}
}

/*************************************************************************/

void ZBinaryFileReader::ReadU32Array(uint32_t* ptr, size_t count)
{
	if(GetStreamByteOrder() == SST_BYTEORDER_HOST)
	{
		SST_OS_ReadFile(fp, ptr, sizeof(uint32_t) * count);
		Offset += sizeof(uint32_t) * count;
	}
	else
	{
		for(size_t i=0; i<count; i++)
			ptr[i] = ReadU32();
	}
}

/*************************************************************************/

void ZBinaryFileReader::ReadU64Array(uint64_t* ptr, size_t count)
{
	if(GetStreamByteOrder() == SST_BYTEORDER_HOST)
	{
		SST_OS_ReadFile(fp, ptr, sizeof(uint64_t) * count);
		Offset += sizeof(uint64_t) * count;
	}
	else
	{
		for(size_t i=0; i<count; i++)
			ptr[i] = ReadU64();
	}
}

/*************************************************************************/

void ZBinaryFileReader::SeekTo(size_t offset)
{
	SST_OS_SeekFile(fp, (int64_t)offset, SST_SEEK_START);
	Offset = offset;
}