#include "stdafx.h"
#include "MemFile.h"

cMemFileToRead::cMemFileToRead()
{
	mPos = 0;
}

cMemFileToRead::~cMemFileToRead()
{
	Close();
}

bool cMemFileToRead::Open( const cString& pathName )
{
	mPos = 0;

	FILE* file = fopen( pathName.Cstr(), "rb" );
	if( file == 0 )
	{
		return false;
	}

	fseek( file, 0, SEEK_END );
	mSize = ftell( file );
	if( mSize == 0 )
	{
		return true;
	}
	else
	{
		fseek( file, 0, SEEK_SET );
	}

	/// 파일을 버퍼에 통째로 읽어 들임
	mBuffer.Resize( mSize );


	if( fread( &mBuffer[0], 1, mSize, file ) < mSize )
	{
		mBuffer.Clear();
		fclose( file );
		assert( 0 && "failed to load file into memory" );
		return false;
	}
	fclose( file );
	return true;
}

int cMemFileToRead::Close()
{
	mPos = 0;
	mBuffer.Clear();
	return cFileToRead::Close();
}

unsigned int cMemFileToRead::Read( void* p, unsigned int bytes )
{
	assert( p );
	assert( mSize > 0 );

	if( bytes == 0 || mPos >= mSize )
	{
		assert(0);
		return 0;
	}
	if( mPos + bytes > mSize )
	{
		bytes = mSize - mPos;
	}
	memcpy( p, &mBuffer[mPos], bytes );
	mPos += bytes;
	return bytes;
}

unsigned int cMemFileToRead::ReadLine( char* p, unsigned int bufferSize )
{
	assert( p );
	assert( mSize > 0 );

	int c;
	unsigned int i = 0;
	char* buffer = (char*)&mBuffer[mPos];

	for( --bufferSize; i < bufferSize; ++mPos, ++i, ++buffer )
	{
		c = *buffer;

		if( mPos >= mSize )
		{
			break;
		}
		if( c == '\n' )
		{
			++mPos;
			break;
		}

		p[i] = (char)c;
	}

	p[i] = 0;
	return i;
}

int cMemFileToRead::Seek( unsigned int offset, int origin )
{
	switch( origin )
	{
	case SEEK_SET:
		break;
	case SEEK_CUR:
		offset += mPos;
		break;
	default:
		assert( 0 );
		return -1;
	}

	if( offset >= mSize )
	{
		offset = mSize - 1;
	}
	mPos = offset;
	return 0;
}

unsigned int cMemFileToRead::Tell() const
{
	return mPos;
}

bool cMemFileToRead::IsEnd() const
{
	return mPos >= mSize;
}

#if defined(_CLIENT) || defined(_MODELVIEW) || defined(REGEN_TOOL) || defined(MAP_EDITOR)
#include "FilePack.h"

cMemFileInPackToRead::cMemFileInPackToRead()
{
}

cMemFileInPackToRead::~cMemFileInPackToRead()
{
	Close();
}

bool cMemFileInPackToRead::Open( cFilePack* pack, int fileIndex )
{
	if( pack == 0 || pack->IsOpened() == false )
	{
		assert( 0 && "zip archive is not opened" );
		return false;
	}
	if( fileIndex < 0 )
	{
		assert( 0 );
		return false;
	}

	/// 압축 저장소에서 파일 열기
	if( pack->OpenFile( fileIndex ) == false )
	{
		assert( 0 && "failed to open file to read in zip" );
		return false;
	}

	/// 파일 크기 얻어옴
	cFileInPackInfo fi;
	if( pack->GetFileInfo( &fi, fileIndex ) == false )
	{
		assert( 0 && "failed to get file info in zip" );
		return false;
	}

	mSize = fi.GetSize();
	if( mSize == 0 )
	{
		assert( 0 && "file size is 0" );
		return false;
	}

	/// 파일을 버퍼에 통째로 읽어 들임
	mBuffer.Resize( mSize );

	if( pack->ReadFile( &mBuffer[0], (unsigned int)mSize ) != mSize )
	{
		mBuffer.Clear();
		pack->CloseFile();
		assert( 0 && "failed to load file in zip into memory" );
		return false;
	}
	pack->CloseFile();
	return true;
}

int cMemFileInPackToRead::Close()
{
	return cMemFileToRead::Close();
}
#endif
