serialserver/packetloopbackcsy/src/LoopbackQueue.cpp
changeset 0 dfb7c4ff071f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/serialserver/packetloopbackcsy/src/LoopbackQueue.cpp	Thu Dec 17 09:22:25 2009 +0200
@@ -0,0 +1,350 @@
+// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "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:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// This file implements a loopback driver for use with the ETel Regression test harness.  This
+// driver supports up to 100 virtual port connections, from port 501 to 600
+// directory exists.  The log file is named loopback.
+// 
+//
+
+/**
+ @file
+ @note	This driver will create a log file in the Logs\ETel directory if the Logs\ETel
+*/
+
+#include "LoopbackQueue.h"
+#include "LoopbackConfig.h"
+
+CTPtr8Queue* CTPtr8Queue::NewL(TInt aBufferLength, TInt aQueueLength)
+	{
+	CTPtr8Queue* me = new(ELeave) CTPtr8Queue(aQueueLength);
+	CleanupStack::PushL(me);
+	me->ConstructL(aBufferLength, aQueueLength);
+	CleanupStack::Pop(me);
+	return me;
+	}
+	
+CTPtr8Queue::CTPtr8Queue(TInt aQueueLength) : iFirstBuffer(0), iNextBuffer(0), iQueueFull(EFalse), 
+	iDescriptors(aQueueLength)
+	{}
+	
+void CTPtr8Queue::ConstructL(TInt aBufferLength, TInt aQueueLength)
+	{
+	HBufC8* buffer = HBufC8::NewL(aBufferLength*aQueueLength);
+	// don't push onto the cleanup stack, as we are assigning to member variable here
+	iBuffer = buffer;
+	TPtr8 tmp = buffer->Des();
+	tmp.AppendFill('C', aBufferLength*aQueueLength);
+	for (TInt i = 0; i < aQueueLength; i++)
+		{
+		TUint8& startChar = tmp[i*aBufferLength];
+		TPtr8 nextElement = TPtr8(&startChar, aBufferLength);
+		iDescriptors.AppendL(nextElement);
+		}
+	}
+	
+CTPtr8Queue::~CTPtr8Queue()
+	{
+	delete iBuffer;
+	}
+	
+void CTPtr8Queue::Clear()
+	{
+	iFirstBuffer = iNextBuffer = 0;
+	iQueueFull = EFalse;
+	}
+	
+TBool CTPtr8Queue::IsEmpty() const
+	{
+	if (iQueueFull)
+		return EFalse;
+	else
+		return iFirstBuffer == iNextBuffer;
+	}
+	
+TBool CTPtr8Queue::QueueLength() const
+	{
+	if (iQueueFull)
+		return iDescriptors.Count();
+	else
+		return Abs(iFirstBuffer - iNextBuffer) % iDescriptors.Count();
+	}
+	
+TBool CTPtr8Queue::IsFull() const
+	{
+	if (iQueueFull)
+		{
+		ASSERT(iFirstBuffer == iNextBuffer);
+		}
+	return iQueueFull;
+	}
+	
+TPtr8& CTPtr8Queue::GetNewBuffer()
+	{
+	ASSERT(!IsFull());
+	TPtr8& ret = iDescriptors[iNextBuffer];
+	iNextBuffer++;
+	if (iNextBuffer >= iDescriptors.Count())
+		iNextBuffer = 0;
+	if (iNextBuffer == iFirstBuffer)
+		iQueueFull = ETrue;
+	return ret;
+	}
+	
+const TPtr8& CTPtr8Queue::PeekFirstBuffer() const
+	{
+	ASSERT(!IsEmpty());
+	return iDescriptors[iFirstBuffer];
+	}
+
+TPtr8& CTPtr8Queue::DequeueFirstBuffer()
+	{
+	ASSERT(!IsEmpty());
+	TPtr8& ret = iDescriptors[iFirstBuffer];
+	iFirstBuffer++;
+	if (iFirstBuffer >= iDescriptors.Count())
+		iFirstBuffer = 0;
+	iQueueFull = EFalse;
+	return ret;
+	}
+
+MLoopbackQueue::~MLoopbackQueue()
+	{}
+	
+CPacketBufferQueue* CPacketBufferQueue::NewL(TInt aBufferLength, TInt aQueueLength)
+	{
+	CPacketBufferQueue* me = new (ELeave)CPacketBufferQueue(aBufferLength);
+	CleanupStack::PushL(me);
+	me->ConstructL(aBufferLength, aQueueLength);
+	CleanupStack::Pop(me);
+	return me;
+	}
+	
+CPacketBufferQueue::CPacketBufferQueue(TInt aBufferLength) : iBufferLength(aBufferLength)
+	{}
+	
+void CPacketBufferQueue::ConstructL(TInt aBufferLength, TInt aQueueLength)
+	{
+	iReadQueue = CTPtr8Queue::NewL(aBufferLength, aQueueLength);
+	iWriteQueue = CTPtr8Queue::NewL(aBufferLength, aQueueLength);
+	}
+	
+CPacketBufferQueue::~CPacketBufferQueue()
+	{
+	delete iReadQueue;
+	delete iWriteQueue;
+	}
+	
+TPtrC8 CPacketBufferQueue::PeekNextReadBuffer(TBool& aCompleteIfBufferNotFull) const
+	{
+	aCompleteIfBufferNotFull = ETrue;
+	return iReadQueue->PeekFirstBuffer();
+	}
+
+void CPacketBufferQueue::DiscardNextReadBuffer()
+	{
+	iReadQueue->DequeueFirstBuffer();
+	}
+
+void CPacketBufferQueue::AppendToReadBuffer(TDesC8& aSrcData)
+	{
+	TPtr8& destBuf = iReadQueue->GetNewBuffer();
+	destBuf.Copy(aSrcData);
+	}
+
+TPtrC8 CPacketBufferQueue::PeekNextWriteBuffer() const
+	{
+	return iWriteQueue->PeekFirstBuffer();
+	}
+
+void CPacketBufferQueue::DiscardNextWriteBuffer()
+	{
+	iWriteQueue->DequeueFirstBuffer();
+	}
+
+TPtr8 CPacketBufferQueue::AppendToWriteBuffer(TInt aLength)
+	{
+	TPtr8& newBuf = iWriteQueue->GetNewBuffer();
+	newBuf.FillZ(aLength);
+	newBuf.LeftTPtr(aLength);
+	return newBuf;
+	}
+
+TBool CPacketBufferQueue::IsReadBufferEmpty() const
+	{
+	return iReadQueue->IsEmpty();
+	}
+
+TBool CPacketBufferQueue::IsWriteBufferEmpty() const
+	{
+	return iWriteQueue->IsEmpty();
+	}
+
+TBool CPacketBufferQueue::IsReadBufferFull(TInt /*aLength*/) const
+	{
+	return iReadQueue->IsFull();
+	}
+
+TBool CPacketBufferQueue::IsWriteBufferFull(TInt /*aLength*/) const
+	{
+	return iWriteQueue->IsFull();
+	}
+
+TInt CPacketBufferQueue::BufferSize() const
+	{
+	return iBufferLength;
+	}
+
+void CPacketBufferQueue::Clear()
+	{
+	iWriteQueue->Clear();
+	iReadQueue->Clear();
+	}
+
+CSerialBufferQueue* CSerialBufferQueue::NewL(TInt aBufferLength, TCommConfigV01* aConfig)
+	{
+	CSerialBufferQueue* me = new (ELeave)CSerialBufferQueue(aBufferLength, aConfig);
+	CleanupStack::PushL(me);
+	me->ConstructL(aBufferLength);
+	CleanupStack::Pop(me);
+	return me;
+	}
+	
+CSerialBufferQueue::CSerialBufferQueue(TInt aBufferLength, TCommConfigV01* aConfig) : 
+	iBufferLength(aBufferLength), iConfig(aConfig), iWriteData(NULL, 0), iReadData(NULL, 0)
+	{}
+	
+void CSerialBufferQueue::ConstructL(TInt aBufferLength)
+	{
+	iReadBuffer = HBufC8::NewL(aBufferLength);
+	iWriteBuffer = HBufC8::NewL(aBufferLength);
+	iReadData.Set(iReadBuffer->Des());
+	iWriteData.Set(iWriteBuffer->Des());
+	}
+	
+CSerialBufferQueue::~CSerialBufferQueue()
+	{
+	delete iReadBuffer;
+	delete iWriteBuffer;
+	}
+	
+TPtrC8 CSerialBufferQueue::NextBuffer(const TPtrC8& aBuffer, TBool& aTerminatorFound) const
+	{
+	// Search for terminator characters
+	TInt len = 0;
+	aTerminatorFound = EFalse;
+	const TText8* terminators = iConfig->iTerminator;
+	TPtrC8 dataToTerminator(aBuffer);
+	for (TInt termNum = 0; termNum < iConfig->iTerminatorCount; ++termNum)
+		{
+		TInt termIndex = dataToTerminator.Locate(terminators[termNum]);
+		if (termIndex >= 0)
+			{
+			// Found the terminator; reduce the length of ptr and search for the next one
+			len = termIndex + 1;
+			dataToTerminator.Set(dataToTerminator.Ptr(), len);
+			aTerminatorFound = ETrue;
+			}
+		}
+	return dataToTerminator;
+	}
+
+TPtrC8 CSerialBufferQueue::PeekNextReadBuffer(TBool& aCompleteIfBufferNotFull) const
+	{
+	// if the terminator is found, we want the requrest completed even if the buffer is not full
+	return NextBuffer(iReadData, aCompleteIfBufferNotFull);
+	}
+
+void CSerialBufferQueue::DiscardNextReadBuffer()
+	{
+	TBool terminatorFound;
+	TPtrC8 dataToTerminator = NextBuffer(iReadData, terminatorFound);
+
+	if (terminatorFound)
+		{
+		TPtrC8 source = iReadData.Right(iReadData.Length()-dataToTerminator.Length());
+		iReadData.Copy(source);
+		}
+	else
+		{
+		iReadData.SetLength(0);
+		}
+	}
+
+void CSerialBufferQueue::AppendToReadBuffer(TDesC8& aSrcData)
+	{
+	ASSERT(aSrcData.Length() < iReadData.MaxLength()-iReadData.Length());
+	iReadData.Append(aSrcData);
+	}
+
+TPtrC8 CSerialBufferQueue::PeekNextWriteBuffer() const
+	{
+	TBool dummy;
+	return NextBuffer(iWriteData, dummy);
+	}
+
+void CSerialBufferQueue::DiscardNextWriteBuffer()
+	{
+	TBool terminatorFound;
+	TPtrC8 dataToTerminator = NextBuffer(iWriteData, terminatorFound);
+	
+	// Delete the write data from the buffer
+	if (terminatorFound)
+		{
+		TPtrC8 source = iWriteData.Right(iWriteData.Length()-dataToTerminator.Length());
+		iWriteData.Copy(source);
+		}
+	else
+		{
+		iWriteData.SetLength(0);
+		}
+	}
+
+TPtr8 CSerialBufferQueue::AppendToWriteBuffer(TInt aLength)
+	{
+	TInt length = iWriteData.Length();
+	ASSERT(aLength < iWriteData.MaxLength()-length);
+	iWriteData.AppendFill('C', aLength);
+	TUint8 *start = &iWriteData[length];
+	return TPtr8(start, aLength, aLength);
+	}
+	
+TBool CSerialBufferQueue::IsReadBufferEmpty() const
+	{
+	return iReadData.Length() == 0;
+	}
+
+TBool CSerialBufferQueue::IsWriteBufferEmpty() const
+	{
+	return iWriteData.Length() == 0;
+	}
+
+TBool CSerialBufferQueue::IsReadBufferFull(TInt aLength) const
+	{
+	return ( aLength > (iReadData.MaxLength()-iReadData.Length()) );
+	}
+
+TBool CSerialBufferQueue::IsWriteBufferFull(TInt aLength) const
+	{
+	return ( aLength > (iWriteData.MaxLength()-iWriteData.Length()) );
+	}
+
+TInt CSerialBufferQueue::BufferSize() const
+	{
+	return iWriteData.MaxLength()-iWriteData.Length();
+	}
+
+void CSerialBufferQueue::Clear()
+	{
+	}
+