// SocketCommandHandler.cpp
//
// Copyright (c) 2010 Accenture. All rights reserved.
// This component and the accompanying materials are made available
// under the terms of the "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Accenture - Initial contribution
//
#include "Misc.h"
#include "stdafx.h"
#include "console_host.h"
#include "SocketCommandHandler.h"
#include "DynamicBuffer.h"
const int KInitialBufferLength = 1;
CSocketCommandReader* CSocketCommandReader::New(CClientSocket& aSocket, MSocketCommandHandler& aHandler)
{
std::auto_ptr<CSocketCommandReader> self(new(EThrow) CSocketCommandReader(aSocket, aHandler));
self->Construct();
return self.release();
}
CSocketCommandReader::~CSocketCommandReader()
{
delete iSocket;
delete iReadBuf;
}
void CSocketCommandReader::ChangeHandler(MSocketCommandHandler& aHandler)
{
iHandler = &aHandler;
}
void CSocketCommandReader::ReadCommand()
{
ASSERT(iState == EIdle);
iState = EReadingHeader;
QueueRead();
}
void CSocketCommandReader::SendResponse(char* aMessage, int aLength)
{
iSocket->Write(aMessage, aLength);
}
CClientSocket& CSocketCommandReader::ReleaseSocket()
{
CClientSocket* socket = iSocket;
iSocket = NULL;
return *socket;
}
CClientSocket& CSocketCommandReader::Socket() const
{
ASSERT(iSocket);
return *iSocket;
}
CSocketCommandReader::CSocketCommandReader(CClientSocket& aSocket, MSocketCommandHandler& aHandler)
: iSocket(&aSocket), iHandler(&aHandler), iState(EIdle)
{
}
void CSocketCommandReader::Construct()
{
iReadBuf = CDynamicReadBuffer::New(KInitialBufferLength);
iSocket->SetClosureObserver(this);
}
void CSocketCommandReader::QueueRead()
{
switch (iState)
{
case EReadingHeader:
{
iSocket->Read((char*)&iPacketHeader, sizeof(TPacketHeader), *this);
break;
}
case EReadingBody:
{
iSocket->Read(iReadBuf->Buffer(iPacketHeader.iSize + 2), iPacketHeader.iSize, *this); // + 2 for string terminator.
break;
}
default:
{
ASSERT(FALSE);
}
}
}
void CSocketCommandReader::SocketReadComplete()
{
switch (iState)
{
case EReadingHeader:
{
if (iPacketHeader.iSize > 0)
{
iState = EReadingBody;
QueueRead();
}
else
{
// Empty body.
iState = EIdle;
iHandler->HandleSocketCommand(iPacketHeader.iType, NULL, 0, *this);
}
break;
}
case EReadingBody:
{
iState = EIdle;
*(TCHAR*)((char*)iReadBuf->Buffer() + iPacketHeader.iSize) = 0; // Add terminator.
iHandler->HandleSocketCommand(iPacketHeader.iType, iReadBuf->Buffer(), iPacketHeader.iSize, *this);
break;
}
default:
{
ASSERT(FALSE);
}
}
}
void CSocketCommandReader::HandleSocketClosure(CSocket& /*aSocket*/)
{
iHandler->HandleSocketClosure(*this);
}