diff -r 000000000000 -r b16258d2340f applayerprotocols/telnetengine/SRC/IOBUFFER.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/applayerprotocols/telnetengine/SRC/IOBUFFER.CPP Tue Feb 02 01:09:52 2010 +0200 @@ -0,0 +1,250 @@ +// Copyright (c) 2003-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: +// Telnet Protocol API +// CIOBufferControl implementation +// +// + +/** + @file +*/ + +#include "IOBUFFER.H" +#include "ACTIVEIO.H" +#include "TELDEBUG.H" + +CIOBufferControl::CIOBufferControl() +/** +Constructor +*/ + { + } + +CIOBufferControl::~CIOBufferControl() +/** +Destructor +*/ + { + Reset(); + __FLOG_STATIC(KTelnetLoggingCompnt(),KTelnetLoggingTag(),_L("CIOBufferControl::D'Tor")); + } + +CIOBufferControl* CIOBufferControl::NewL(MIONotifier* aNotifier) + { + CIOBufferControl* self = new(ELeave) CIOBufferControl; + CleanupStack::PushL(self); + self->ConstructL(aNotifier); + CleanupStack::Pop(); + return self; + } + +void CIOBufferControl::ConstructL(MIONotifier* aNotifier) + { + iNotifier = aNotifier; + + iWriter = NULL; + iReader = NULL; + + iQueueIndex = 0; + iLiveIndex = 0; + + iUrgent = NULL; + iWriteBuffers[0] = NULL; + iWriteBuffers[1] = NULL; + } + +TInt CIOBufferControl::WriteUrgent(HBufC8* aBuffer) +/** +Caller requests to send data as TCP urgent +*/ + { + TInt err = KErrNone; + // Check to see if write is already outstanding + if(iLiveIndex == iQueueIndex) + { + // No write outstanding + // Just set the live index to point to the heap buffer + iWriteBuffers[iLiveIndex] = aBuffer; + // Make indexes different so if the next write call comes before completion of this one + // then it can append to the queue buffer + (iLiveIndex == 0) ? (iQueueIndex = 1) : (iQueueIndex = 0); + iWriter->IssueUrgentWrite(*(iWriteBuffers[iLiveIndex])); + err = KErrNone; + } + else + { + // Check for existing queued urgent + if(iUrgent) + // DON'T permit queued urgents + err = KErrInUse; + else + { + // Data will be sent on next write completion + iUrgent = aBuffer; + err = KErrNone; + } + } + return(err); + } + +TInt CIOBufferControl::Write(HBufC8* aBuffer) +/** +Writes issued into this object send it to the active writer +Ownership of the buffer is transferred +*/ + { + TInt ret = KErrNone; + + TPtr8 ptr = aBuffer->Des(); + + // iLiveIndex = iQueueIndex means there are no outstanding writes on the socket + if(iLiveIndex == iQueueIndex) + { + iWriteBuffers[iLiveIndex] = aBuffer; + // Make indexes different so if the next write call comes before completion of this one + // then it can append to the queue buffer + (iLiveIndex == 0) ? (iQueueIndex = 1) : (iQueueIndex = 0); + iWriter->IssueWrite(*(iWriteBuffers[iLiveIndex])); + } + else + { + __FLOG_STATIC(KTelnetLoggingCompnt(),KTelnetLoggingTag(),_L("CIOBufferControl() Write Queue")); + // There is already a buffer loaded on the socket + if(iWriteBuffers[iQueueIndex]) + // Append this data to the iQueueIndex buffer + // Overflow check first + { + HBufC8* qBuf = iWriteBuffers[iQueueIndex]; + TPtr8 qPtr = qBuf->Des(); + if((qPtr.MaxLength() - qPtr.Length()) < ptr.Length()) + // Not enough room to append + { + qBuf = iWriteBuffers[iQueueIndex]->ReAlloc(qPtr.Length() + ptr.Length()); + if(qBuf==NULL) + return KErrNoMemory; //Return error and don't take ownership of aBuffer + iWriteBuffers[iQueueIndex] = qBuf; + qPtr = qBuf->Des(); + } + qPtr.Append(ptr); + delete aBuffer; + } + else + // Nothing queued just assign the pointer + // Data will be sent on next write completion + { + iWriteBuffers[iQueueIndex] = aBuffer; + } + } + return(ret); + } + + +TInt CIOBufferControl::Read(TDes8& aBuffer) + { + return(iReader->IssueRead(aBuffer)); + } + +void CIOBufferControl::SetWriter(CActiveWriter* aWriter) + { + iWriter = aWriter; + } + +void CIOBufferControl::SetReader(CActiveReader* aReader) + { + iReader = aReader; + } + + +// MIONotifier + +void CIOBufferControl::Event(TInt aEvent,TInt aEventCode) + { + iNotifier->Event(aEvent,aEventCode); + } + +void CIOBufferControl::WriteComplete() +/** +Normal asynchronous completion to a write request to the active writer +The data we transmitted will always be pointed to by iLiveIndex +On completion there could be Urgent or ordinary data queued +Submit any queued urgent first +*/ + { + // Free the HBufC8* we loaded for transmit the last time + delete iWriteBuffers[iLiveIndex]; + iWriteBuffers[iLiveIndex] = NULL; + // First check to see if we have any urgent data queued + if(iUrgent) + { + // Urgent data queued, move the urgent pointer to the live index + iWriteBuffers[iLiveIndex] = iUrgent; + // Free the pointer + iUrgent = NULL; + // Send the queued urgent data + iWriter->IssueUrgentWrite(*(iWriteBuffers[iLiveIndex])); + } + else if(iWriteBuffers[iQueueIndex]) + // Check to see if any data is on the normal queue + { + // Data queued + // Swap the indexes + iLiveIndex = iQueueIndex; + (iLiveIndex == 0) ? (iQueueIndex = 1) : (iQueueIndex = 0); + // Issue the next write + __FLOG_STATIC(KTelnetLoggingCompnt(),KTelnetLoggingTag(),_L("CIOBufferControl() WriteComplete() Write Queue Data")); + iWriter->IssueWrite(*(iWriteBuffers[iLiveIndex])); + // complete the write + } + else + { + // No data queued, set the transmitter empty condition + iLiveIndex = iQueueIndex; + } + iNotifier->WriteComplete(); + } + +void CIOBufferControl::WriteError(TInt aError) +/** +Write completion with an error, just pass the code up in a notification +*/ + { + Reset(); + iNotifier->WriteError(aError); + } + +void CIOBufferControl::ReadCompleteL() + { + iNotifier->ReadCompleteL(); + } + +void CIOBufferControl::ReadComplete(TInt aError) + { + Reset(); + iNotifier->ReadComplete(aError); + } + +void CIOBufferControl::Reset() + { + delete iWriteBuffers[0]; + delete iWriteBuffers[1]; + delete iUrgent; + + iUrgent = NULL; + iWriteBuffers[0] = NULL; + iWriteBuffers[1] = NULL; + + iQueueIndex = iLiveIndex = 0; + iWriter = NULL; + iReader = NULL; + }