#include <common/memfile.hpp>

bool MemFile::createBuffer(DWORD lengthBuffer)
{
	destroyBuffer();
	mhGlobalBuffer=::GlobalAlloc(GMEM_FIXED,lengthBuffer);
	if(!mhGlobalBuffer)return false;
	mlpBuffer=(UHUGE*)::GlobalLock(mhGlobalBuffer);
	mlpBufferPointer=mlpBuffer;
	mBufferLength=lengthBuffer;
  return true;
} 

bool MemFile::destroyBuffer(void)
{
	if(!mhGlobalBuffer)return false;
  ::GlobalUnlock(mhGlobalBuffer);
	::GlobalFree(mhGlobalBuffer);
	mlpBuffer=mlpBufferPointer=0;
  mhGlobalBuffer=0;
	mlpBufferPointer=0;
	mIsDirty=false;
	mBufferLength=0;
	mMaxExtent=0;
  return true;
}

bool MemFile::rewind(void)
{
	if(!isOkay())return false;
	mlpBufferPointer=mlpBuffer;
  return true;
}

DWORD MemFile::read(char *lpBuffer,DWORD lengthData)
{
	BYTE byteValue;
	int bytesRead;

  bytesRead=0;
	if(!isOkay())return bytesRead;
	for(;bytesRead<lengthData;bytesRead++)
	{
		if(!read(byteValue))break;
    *(lpBuffer++)=byteValue;
	}
  return bytesRead;
}

DWORD MemFile::read(char *lpBuffer,DWORD lengthData,int stopChar)
{
	BYTE tempChar;
	int bytesRead;

  bytesRead=0;
	for(;bytesRead<lengthData-1;bytesRead++)
	{
		if(!read(tempChar))break;
		if(tempChar==stopChar)break;
		*(lpBuffer++)=tempChar;
	}
  *(lpBuffer)=0;
	return bytesRead;
}

bool MemFile::write(DWORD value)        
{
	WORD wordValue;

  if(!isOkay())return false;
	if(BigEndian==mByteOrder)
	{
		WORD hiWord(HIWORD(value));
		WORD loWord(LOWORD(value));

		value=((DWORD)mIntelData.intelData(loWord))<<16;
		value|=mIntelData.intelData(hiWord);
		write((char*)&value,sizeof(value));
		return true;
	}
  wordValue=(WORD)(value&0xFFFF);            
	write(wordValue);													 
	wordValue=(WORD)(value>>16);							 
  write(wordValue);
  return true;
}

bool MemFile::write(char *lpBuffer,DWORD lengthData)
{
  if(!isOkay())return FALSE;
	if(!lengthData)return TRUE;
	for(DWORD index=0;index<lengthData;index++)if(!write((BYTE)(*(lpBuffer++))))return FALSE;
	return TRUE;
}

bool MemFile::seek(LONG seekOffset,SeekFrom seekFrom)
{
	bool returnCode(false);

	if(!isOkay())return returnCode;
	switch(seekFrom)
	{
		case SeekBeginning :
			if(0>seekOffset)break;
			if(seekOffset>mMaxExtent)break;
			mlpBufferPointer=mlpBuffer+seekOffset;
			returnCode=true;
      break;
		case SeekCurrent :
			if(mlpBufferPointer+seekOffset<mlpBuffer)break;
			if(mlpBufferPointer+seekOffset>mlpBuffer+mBufferLength)break;
			mlpBufferPointer+=seekOffset;
      returnCode=true;
      break;
	}
  return returnCode;
}

bool MemFile::flushBuffer(void)
{
	OFSTRUCT ofStruct;
  HFILE hOutputFile;

	if(!isOkay()||!mMaxExtent||mPathFileName.isNull())return false;
	if(HFILE_ERROR==(hOutputFile=::OpenFile(mPathFileName,&ofStruct,OF_WRITE|OF_CREATE)))return false;
	if(-1==::_hwrite(hOutputFile,(LPCSTR)mlpBuffer,mMaxExtent))return false;
	::_lclose(hOutputFile);
  mIsDirty=false;
  return true;
}

DWORD MemFile::captureBuffer(GlobalData<BYTE> &memoryBuffer,bool clearDirty)
{
	if(!isOkay()||!mMaxExtent)return FALSE;
  memoryBuffer.size(mMaxExtent);
	for(DWORD itemIndex=0;itemIndex<mMaxExtent;itemIndex++)
		memoryBuffer[itemIndex]=*(mlpBuffer+itemIndex);
	mIsDirty=!clearDirty;
	return mMaxExtent;	
}

DWORD MemFile::getLine(String &lineString)
{
	String lineBuffer;
	BYTE charByte;
  DWORD bytesRead(0);

	while(TRUE)
	{
		if(!read(charByte))break;
    bytesRead++;
		if(CarriageReturn==charByte)
		{
			if(!read(charByte))break;
      bytesRead++;
			if(LineFeed==charByte)
			{
				lineString=lineBuffer;
				return TRUE;
			}
		}
		else if(LineFeed==charByte)
		{
		  lineString=lineBuffer;
			return TRUE;
		}
		else if(NullChar==charByte)
		{
			lineString=lineBuffer;
      return TRUE;
    }
		else lineBuffer+=charByte;
	}
	lineString=lineBuffer;
	return bytesRead;
}

