/*
	ZBinaryBufferReader.cpp
	Author: Chris Ertel <crertel@762studios.com>, Patrick Baggett <ptbaggett@762studios.com>
	Created: 3/6/2013

	Purpose: 

	Reads a binary stream from memory.

	License:

	TODO

*/

#include <ZUtil/ZBinaryBufferReader.hpp>

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

uint8_t ZBinaryBufferReader::ReadU8()
{
	uint8_t retval = (uint8_t)Data[Offset];

	++Offset;

	return retval;
}

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

uint16_t ZBinaryBufferReader::ReadU16()
{
	uint16_t value;
	memcpy(&value, GetPosition(), sizeof(uint16_t));

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

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

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

uint32_t ZBinaryBufferReader::ReadU32()
{
	uint32_t value;
	memcpy(&value, GetPosition(), sizeof(uint32_t));

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

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

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

uint64_t ZBinaryBufferReader::ReadU64()
{
	uint64_t value;
	memcpy(&value, GetPosition(), sizeof(uint64_t));

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

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

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

void ZBinaryBufferReader::ReadU8Array(uint8_t* ptr, size_t count)
{
	memcpy(ptr, GetPosition(), count);
	Offset += count;
}

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

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

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

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

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

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

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

void* ZBinaryBufferReader::ReadPointer()
{
	uintptr_t value;
	memcpy(&value, GetPosition(), sizeof(uintptr_t));

	if(GetStreamByteOrder() != SST_BYTEORDER_HOST)
	{
		switch(sizeof(uintptr_t))
		{
			case sizeof(uint16_t): value = (uintptr_t)SST_OS_ByteSwap16((uint16_t)value); break;
			case sizeof(uint32_t): value = (uintptr_t)SST_OS_ByteSwap32((uint32_t)value); break;
			case sizeof(uint64_t): value = (uintptr_t)SST_OS_ByteSwap64((uint64_t)value); break;
		}
	}

	Offset += sizeof(uintptr_t);
	return (void*)value;
}

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