diff -r 000000000000 -r 72b543305e3a email/imap4mtm/imaptransporthandler/src/csocketcontroller.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/email/imap4mtm/imaptransporthandler/src/csocketcontroller.cpp Thu Dec 17 08:44:11 2009 +0200 @@ -0,0 +1,235 @@ +// Copyright (c) 2006-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: +// + +#include "csocketcontroller.h" + +#include "csocket.h" +#include "csocketreader.h" +#include "csocketwriter.h" +#include "msocketcontrollerstore.h" +#include "mconnectionprefsprovider.h" +#include "imappaniccodes.h" +#include "imaptransportmanagercommon.h" + +/** +The factory constructor. Ownership of the socket is transferred on calling +the factory constructor. + +@param aSocket The connected socket. +@return A pointer to a fully constructed object. +*/ +CSocketController* CSocketController::NewL(CSocket* aSocket, MConnectionPrefsProvider& aConnectionPrefsProvider) + { + // Ownership of socket has been transferred - place on cleanup stack. + CleanupStack::PushL(aSocket); + + // Transfer ownership of the socket to the socket controller. + CSocketController* self = new (ELeave) CSocketController(aSocket, aConnectionPrefsProvider); + + // Ownership of socket with the socket controller - pop-off the cleanup stack + CleanupStack::Pop(aSocket); + + // Continue with initialisation of the socket controller + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +/** +Destructor. +*/ +CSocketController::~CSocketController() + { + // Clean-up... + delete iSocketReader; + delete iSocketWriter; + delete iSocket; + } + +/** +Constructor. + +@param aStore The socket controller store. +@param aSocket The connected socket. +*/ +CSocketController::CSocketController(CSocket* aSocket, MConnectionPrefsProvider& aConnectionPrefsProvider) +: CBase(), iSocket(aSocket), iConnectionPrefsProvider(aConnectionPrefsProvider) + { + __ASSERT_DEBUG( iSocket, User::Invariant() ); + } + +/** +Second phase constructor. Initialises the object. Ownership of the connected +socket is passed to this class if this function completes. +*/ +void CSocketController::ConstructL() + { + // Create the socket reader and writer + // Writer is created (and added to AS) first so that it has a 'higher priority' in AS. + // Must keep this order since it guarantees that we receive the acknowledgement of data being + // sent out before receiving the response, which is something we rely on. + iSocketWriter = CSocketWriter::NewL(*iSocket, *this); + iSocketReader = CSocketReader::NewL(*iSocket, *this); + } + +/** +Notifier that this object is now owned by the socket controller store. + +@param aStore The socket controller store. +*/ +void CSocketController::NotifyInStore(MSocketControllerStore& aStore) + { + iStore = &aStore; + } + +/** +The access function for the input stream. + +@return The input stream object. +*/ +MInputStream& CSocketController::InputStream() const + { + return *iSocketReader; + } + +/** +The access function for the output stream. + +@return The output stream object. +*/ +MOutputStream& CSocketController::OutputStream() const + { + return *iSocketWriter; + } + +/* + * Methods from MSocketController + */ + +/** +@see MSocketController +*/ +void CSocketController::StreamClosed(TInt aError, MSocketController::TStreamType aStreamType) + { + // Notify the other stream... + switch( aStreamType ) + { + case EInputStream: + { + // The input stream has closed the socket - inform the socket writer + iSocketWriter->SocketClosed(aError); + } break; + case EOutputStream: + { + // The output stream has closed the socket - inform the socket reader + iSocketReader->SocketClosed(aError); + } break; + default: + User::Invariant(); + break; + } + + // Both the input and output streams should be in the Closed state - this + // socket controller is no longer useful. + if( iStore ) + { + // This socket controller is in the socket controller store - need to + // remove it from there. + iStore->SocketControllerShutdown(*this); + + // This object is now ownerless - it should be deleted. + delete this; + } + // This socket controller is not owned by the socket controller store - the + // owner (probably the cleanup stack) will delete it. + } + +/** +@see MSocketController +*/ +void CSocketController::StreamSuspended(MSocketController::TStreamType aSuspendedStream) + { + // Suspend the other stream... + switch( aSuspendedStream ) + { + case EInputStream: + { + // This is not supported yet! + User::Invariant(); + } break; + case EOutputStream: + { + // The output stream has suspended the socket - inform the socket reader + iSocketReader->Suspend(); + } break; + default: + User::Invariant(); + break; + } + } + +/** +@see MSocketController +*/ +void CSocketController::StreamResumed(MSocketController::TStreamType aResumedStream) + { + // Resume the other stream... + switch( aResumedStream ) + { + case EInputStream: + { + // This is not supported yet! + User::Invariant(); + } break; + case EOutputStream: + { + // The output stream has resumed the socket - inform the socket reader + iSocketReader->Resume(); + } break; + default: + User::Invariant(); + break; + } + } + +/** +@see MSocketController +*/ +#ifdef _DEBUG +void CSocketController::ConnectionInfo(TDes8& aRemoteHost, TUint16& aRemotePort, TUint16& aLocalPort) +#else +void CSocketController::ConnectionInfo(TDes8& /*aRemoteHost*/, TUint16& /*aRemotePort*/, TUint16& /*aLocalPort*/) +#endif + { +#ifdef _DEBUG + __ASSERT_DEBUG( aRemoteHost.MaxLength() >= KIpv6MaxAddrSize, User::Invariant() ); + + TInetAddr addr; + iSocket->RemoteName(addr); + + TBuf ip16bit; + addr.Output(ip16bit); + + aRemoteHost.Copy(ip16bit); + aRemotePort = static_cast(addr.Port()); + + TInetAddr local; + iSocket->LocalName(local); + aLocalPort = static_cast(local.Port()); +#else + User::Invariant(); +#endif + }