plugins/consoles/rcons/server/win32/SocketCommandHandler.cpp
changeset 0 7f656887cf89
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/consoles/rcons/server/win32/SocketCommandHandler.cpp	Wed Jun 23 15:52:26 2010 +0100
@@ -0,0 +1,133 @@
+// 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);
+	}