diff -r 000000000000 -r f63038272f30 bluetoothengine/bthid/bthidserver/src/socketwriter.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bluetoothengine/bthid/bthidserver/src/socketwriter.cpp Mon Jan 18 20:28:57 2010 +0200 @@ -0,0 +1,180 @@ +/* +* Copyright (c) 2008 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 is the implementation of application class + * +*/ + + +#include "sockets.pan" +#include "socketwriter.h" +#include "socketobserver.h" +#include "timeouttimer.h" + +// ---------------------------------------------------------------------- + +// Initial size of the buffers for data to write +const TInt KWriteBufferInitialSize = 20; + +// 5 seconds socket write time-out +const TInt CSocketWriter::KTimeOut = 5000000; + +CSocketWriter* CSocketWriter::NewL(TUint aSocketID, + MSocketObserver& aObserver) + { + CSocketWriter* self = CSocketWriter::NewLC(aSocketID, aObserver); + CleanupStack::Pop(self); + return self; + } + +CSocketWriter* CSocketWriter::NewLC(TUint aSocketID, + MSocketObserver& aObserver) + { + CSocketWriter* self = new (ELeave) CSocketWriter(aSocketID, aObserver); + CleanupStack::PushL(self); + self->ConstructL(); + return self; + } + +CSocketWriter::CSocketWriter(TUint aSocketID, MSocketObserver& aObserver) : + CActive(EPriorityStandard), iSocketID(aSocketID), iObserver(aObserver) + { + } + +CSocketWriter::~CSocketWriter() + { + Cancel(); + delete iTimer; + delete iWriteBuffer[0]; + delete iWriteBuffer[1]; + } + +void CSocketWriter::DoCancel() + { + // Cancel asynchronous write request + iSocket->CancelWrite(); + + iTimer->Cancel(); + + // Clear the buffers + *iWriteBuffer[0] = KNullDesC8; + *iWriteBuffer[1] = KNullDesC8; + } + +void CSocketWriter::ConstructL() + { + CActiveScheduler::Add(this); + + iTimer = CTimeOutTimer::NewL(CActive::EPriorityStandard, *this); + + iWriteBuffer[0] = HBufC8::NewL(KWriteBufferInitialSize); + iWriteBuffer[1] = HBufC8::NewL(KWriteBufferInitialSize); + iCurrentBuffer = 0; + } + +void CSocketWriter::TimerExpired() + { + Cancel(); + + // Clear the buffers + *iWriteBuffer[0] = KNullDesC8; + *iWriteBuffer[1] = KNullDesC8; + + iObserver.HandleSocketError(iSocketID, EFalse, KErrTimedOut); + } + +void CSocketWriter::RunL() + { + iTimer->Cancel(); + + // Remember the current status + TInt status = iStatus.Int(); + + // Clear the buffer that has been written + *iWriteBuffer[iCurrentBuffer] = KNullDesC8; + + // If the other buffer has data, write it now + if (iWriteBuffer[1 - iCurrentBuffer]->Length() > 0) + { + iCurrentBuffer = 1 - iCurrentBuffer; + DoWrite(); + } + + // Handle status of completed write + if (KErrNone == status) + { + iObserver.HandleWriteComplete(iSocketID); + } + else + { + // Error: pass it up to user interface + iObserver.HandleSocketError(iSocketID, EFalse, status); + } + } + +void CSocketWriter::Initialise(RSocket* aSocket) + { + __ASSERT_ALWAYS(!IsActive(), + User::Panic(KPanicSocketsEngineWrite, ESocketsBadState)); + + iSocket = aSocket; + } + +void CSocketWriter::IssueWriteL(const TDesC8& aData) + { + if (IsActive()) + { + // Put the data in the other buffer + StoreDataL(aData, 1 - iCurrentBuffer); + } + else + { + // Put the data in the current buffer and write immediately + StoreDataL(aData, iCurrentBuffer); + DoWrite(); + } + } + +void CSocketWriter::DoWrite() + { + // If we aren't in the correct state for a write, panic. + __ASSERT_ALWAYS(!IsActive(), + User::Panic(KPanicSocketsEngineWrite, ESocketsBadState)); + + // Initiate actual write + iSocket->Write(*iWriteBuffer[iCurrentBuffer], iStatus); + + // Request timeout + if (!iTimer->IsActive()) + iTimer->After(KTimeOut); + + SetActive(); + } + +void CSocketWriter::StoreDataL(const TDesC8& aData, TInt aBuffer) + { + __ASSERT_ALWAYS(iWriteBuffer[aBuffer]->Length() == 0, + User::Panic(KPanicSocketsEngineWrite, ESocketsBadState)); + + // Reallocate the buffer if it's too small + if (aData.Length() > iWriteBuffer[aBuffer]->Des().MaxLength()) + { + // Make sure we have a new buffer before deleting the old one + HBufC8* newBuffer = HBufC8::NewL(aData.Length()); + + delete iWriteBuffer[aBuffer]; + iWriteBuffer[aBuffer] = newBuffer; + } + + *iWriteBuffer[aBuffer] = aData; + }