#include "StdAfx.h"
#include "CommandPipe.h"
#include "CommandPacket.h"

#define	PACKET_READ_SIZE	(256 * 1024)

CCommandPipe::CCommandPipe(void)
{
	m_hPipe = NULL;
}

CCommandPipe::~CCommandPipe(void)
{
	Close();
}

//////////////////////////////////////////////////////////////////////////////////
//	開始・停止
//////////////////////////////////////////////////////////////////////////////////
/*!
	開始
*/
int CCommandPipe::Connect(CString pipeName)
{
	if(pipeName.Left(2) != "\\\\")
		pipeName = "\\\\.\\pipe\\" + pipeName;

	//	開く
	m_hPipe = ::CreateFile (pipeName,	GENERIC_READ | GENERIC_WRITE, 0, NULL,
							OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	if(m_hPipe == INVALID_HANDLE_VALUE)
		return(-1);

	//	ウェルカムメッセージを待つ
	CBuffer	welcome;
	if(RecvData(welcome))
		return(-1);

	//	メッセージ確認
	if(OnWelcome(welcome))
		return(-1);

	return(0);
}


/*!
	コマンドを送る
*/
int CCommandPipe::SendCommand(CBuffer &send, CBuffer &recv)
{
	//	送信
	if(SendData(send))
		return(-1);

	//	受信
	if(RecvData(recv))
		return(-1);

	return(0);
}


/*!
	閉じる
*/
void CCommandPipe::Close()
{
	SAFE_CLOSE_HANDLE(m_hPipe);
}


/*!
	切断確認
*/
int CCommandPipe::CheckDisconnect()
{
	if(m_hPipe == NULL)
		return(1);

	if(!PeekNamedPipe(m_hPipe, NULL,0,NULL,NULL,NULL))
	{
		Close();
		return(1);
	}

	return(0);
}



//////////////////////////////////////////////////////////////////////////////////
//	送受信
//////////////////////////////////////////////////////////////////////////////////
/*!
	送信
*/
int CCommandPipe::SendData(CBuffer &sendData)
{
	DWORD	sendLen;

	//	送信
	if(!WriteFile(m_hPipe, sendData.GetPtr(), sendData.GetSize(), &sendLen, NULL))
	{
		Close();
		return(-1);
	}
	return(0);
}

/*!
	受信
*/
int CCommandPipe::RecvData(CBuffer &recvData)
{
	DWORD	recvLen;

	//	受信
	int	recved = 0, bufSize = PACKET_READ_SIZE;
	while(1)
	{
		//	読み込み
		recvData.ReSize(bufSize);
		if(!ReadFile(m_hPipe, recvData.GetPtr() + recved, bufSize, &recvLen, NULL))
		{
			//	残りがある？
			if(::GetLastError() == ERROR_MORE_DATA)
			{
				recved += recvLen;
				bufSize *= 2;
				continue;
			}
			else
			{
				Close();
				return(-1);
			}
		}
		break;
	}
	recvData.ReSize(recved + recvLen);

	return(0);
}
