// BinaryFile.cpp: implementation of the CBinaryFile class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "aplPacket.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////


CBinaryFile::CBinaryFile(bool bANSI /*= true*/) : m_bANSI(bANSI)
{
}

bool CBinaryFile::Read(CString &str)
{
	UINT32 str_len;
	Read(str_len);
	DWORD pos, len;
	pos=(DWORD)GetPosition();
	len=(DWORD)GetLength();
	if(str_len>(int)(len-pos)) return false;

#ifdef _UNICODE
	if (m_bANSI)
	{
		// переводим из ANSI-строки в Unicode
		char *c_buf = new char[str_len];
		Read(c_buf, str_len);
		CaplStringAdapter sAdapter(c_buf);
		str = (LPCWSTR)sAdapter;
		delete[] c_buf;
	}
	else
	{
		LPWSTR buf = str.GetBuffer(str_len);
		if(!Read(buf, str_len*sizeof(TCHAR))) return false;
		buf[str_len]=_T('\0');
		str.ReleaseBuffer();
	}
#else
	LPSTR buf = str.GetBuffer(str_len);
	if(!Read(buf, str_len)) return false;
	buf[str_len]='\0';
	str.ReleaseBuffer();
#endif

	return true;
}

bool CBinaryFile::Read(UINT32 &i)
{
	if(!CBinaryFile::Read(&i, sizeof(UINT32))) return false;
	return true;
}


bool CBinaryFile::Read(TCHAR& c)
{
	if(!CBinaryFile::Read(&c, sizeof(TCHAR))) return false;

	return true;
}

BYTE CBinaryFile::Read()
{
	BYTE b = 0; 
	CBinaryFile::Read(&b, 1);
	return b;
}

void CBinaryFile::Write(CString str)
{
#ifdef _UNICODE
	if (m_bANSI)
	{
		// переводим строку в ANSI
		CaplStringAdapter sAdapter(str);
		LPCSTR pBufANSI = (LPCSTR)sAdapter;
		Write((UINT32)(str.GetLength()+1));
		Write((BYTE*)pBufANSI, str.GetLength()+1);
	}
	else
	{
		Write((UINT32)(str.GetLength()+1));
		Write((LPCWSTR)str, (str.GetLength()+1)*sizeof(TCHAR));
	}
#else
	Write((UINT32)(str.GetLength()+1));
	Write(str, str.GetLength()+1);
#endif
}

void CBinaryFile::Write(UINT32 i)	{CBinaryFile::Write(&i, sizeof(UINT32));}
void CBinaryFile::Write(char c)		{CBinaryFile::Write(&c, sizeof(char));}
void CBinaryFile::Write(wchar_t wc)	{CBinaryFile::Write(&wc, sizeof(wchar_t));}


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

bool CBinaryFile::WriteFromFile(LPCTSTR sFileName)
{
	if(0==sFileName) return false;
	if(_T('\0')==sFileName[0]) return false;

	CFile InFile;
	if(!InFile.Open(LPCTSTR(sFileName),CFile::modeRead|CFile::typeBinary)) return false;
	DWORD flen=(DWORD)InFile.GetLength();

	//int iDataBufSize=4*1024*1024;
	int iDataBufSize=aplGetOptimalBufSize();
	char *pDataBuf=new char[iDataBufSize];
	
	CString msg=APL_T("Запись из временного файла... \n\n(%s)");
	msg.Replace(_T("%s"), sFileName);
	long wdlg=aplStartWaitDlg(msg);

	while(true)
	{
		int iReadSize=InFile.Read(pDataBuf,iDataBufSize);
		if(iReadSize<=0) break;
		Write(pDataBuf, iReadSize);
		if(iReadSize<iDataBufSize) break; // Конец файла
	}
	aplEndWaitDlg(wdlg);

	InFile.Close();
	delete pDataBuf; pDataBuf=0;

	return true;
}

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

bool CBinaryFile::WriteToFile(LPCTSTR sFileName, UINT nCount)  // Записывает файл из текущего файла
{
	if(0==sFileName) return false;
	if(_T('\0')==sFileName[0]) return false;

	CFile OutFile;
	if(!OutFile.Open(LPCTSTR(sFileName),CFile::modeCreate|CFile::modeWrite|CFile::typeBinary)) return false;

	UINT iDataBufSize=aplGetOptimalBufSize();
	if(nCount<iDataBufSize) iDataBufSize=nCount;

	char *pDataBuf=new char[iDataBufSize];

	// !!! Читаем не до конца. Объем доступных данных больше чем нам надо !!!

	CString msg=APL_T("Запись временного файла... \n\n(%s)");
	msg.Replace(_T("%s"), sFileName);
	long wdlg=aplStartWaitDlg(msg);

	while(true)
	{
		if(nCount<iDataBufSize) iDataBufSize=nCount;

		int iReadSize=Read(pDataBuf,iDataBufSize);
		if(0==iReadSize) break;
		OutFile.Write(pDataBuf, iReadSize);

		nCount-=iReadSize;
		if(0==nCount) break; // Конец файла
	}
	aplEndWaitDlg(wdlg);

	delete pDataBuf; pDataBuf=0;
	OutFile.Flush();
	OutFile.Close();
	return true;
}



