//////////////////////////////////////////////////////////////////////////////
//
// Asura_Mem.cpp
//
// Copyright (c) 2006 Rebellion. All rights reserved.
//
// Description:
//
//     wrappers for stdlib memory functions
//
//////////////////////////////////////////////////////////////////////////////

// I N C L U D E S ///////////////////////////////////////////////////////////

#include "Core/Asura.h"

// This file's header.
#include "Core/Memory/Asura_Mem.h"

#include "Debugging/Asura_Assert.h"


#if defined(ASURA_SUPPORT_COMMAND_CONSOLE) && defined(ASURA_DEBUG_VARIABLE_SYSTEM)
bool	Asura_Mem::s_bEnablePrefetch	= true;
#endif	//defined(ASURA_SUPPORT_COMMAND_CONSOLE) && defined(ASURA_DEBUG_VARIABLE_SYSTEM)

#if _DEBUG && defined(ASURA_ASSERT)

void Asura_Mem::Check_Compare(const void* pMem1, const void* pMem2, size_t uBytes)
{
	// check for NULL ptrs
	if (uBytes)
	{
		Asura_Assert(pMem1, "invalid memcmp ptr");
		Asura_Assert(pMem2, "invalid memcmp ptr");
	}

	// arbitrary check on num bytes (less than 128 MB)
	Asura_Assert(uBytes < 128 * 1024 * 1024, "suspiciously-large number of bytes to compare");
}

void Asura_Mem::Check_Copy(void* pDest, const void* pSrc, size_t uBytes)
{
	// check for NULL ptrs
	if (uBytes)
	{
		Asura_Assert(pDest, "invalid memcpy ptr");
		Asura_Assert(pSrc, "invalid memcpy ptr");
	}

	// check they don't overlap
	const char* pcSrc = reinterpret_cast<const char*>(pSrc);
	const char* pcDest = reinterpret_cast<const char*>(pDest);

	Asura_Assert( (pcDest + uBytes <= pcSrc) || (pcSrc + uBytes <= pDest), "memcpy regions overlap");

	// arbitrary check on num bytes (less than 128 MB)
	Asura_Assert(uBytes < 128 * 1024 * 1024, "suspiciously-large number of bytes to copy");
}

void Asura_Mem::Check_SafeCopy(void* pDest, const void* pSrc, size_t uBytes)
{
	// check for NULL ptrs
	if (uBytes)
	{
		Asura_Assert(pDest, "invalid safe memcpy ptr");
		Asura_Assert(pSrc, "invalid safe memcpy ptr");
	}

	// check they don't overlap
	const char* pcSrc = reinterpret_cast<const char*>(pSrc);
	const char* pcDest = reinterpret_cast<const char*>(pDest);

	Asura_Assert( (pcDest + uBytes <= pcSrc) || (pcSrc + uBytes <= pDest), "safe memcpy regions overlap");

	// arbitrary check on num bytes (less than 128 MB)
	Asura_Assert(uBytes < 128 * 1024 * 1024, "suspiciously-large number of bytes to safe copy");
}

void Asura_Mem::Check_Move(void* pDest, const void* pSrc, size_t uBytes)
{
	// check for NULL ptrs
	if (uBytes)
	{
		Asura_Assert(pDest, "invalid memmove ptr");
		Asura_Assert(pSrc, "invalid memmove ptr");
	}

	// arbitrary check on num bytes (less than 128 MB)
	Asura_Assert(uBytes < 128 * 1024 * 1024, "suspiciously-large number of bytes to move");
}

void Asura_Mem::Check_Set(void* pMem, int iChar, size_t uCount)
{
	if (uCount)
	{
		Asura_Assert(pMem, "invalid memset ptr");
	}
	else
	{
		Asura_Assertf(!pMem, ("attempting to memset 0 bytes - did you mean to set"
			" %d bytes to 0 rather than to set 0 bytes to %d?", iChar, iChar));
	}
	Asura_Assert(iChar >= 0 && iChar < 256, "invalid memset value");

	// arbitrary check on num bytes (less than 128 MB)
	Asura_Assert(uCount < 128 * 1024 * 1024, "suspiciously-large number of bytes to set");
}

#endif // #if _DEBUG && defined(ASURA_ASSERT)


/// End of file. ///
