diff -r 000000000000 -r c8caa15ef882 simpleengine/engine/src/simplepublisher.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/simpleengine/engine/src/simplepublisher.cpp Tue Feb 02 01:05:17 2010 +0200 @@ -0,0 +1,496 @@ +/* +* Copyright (c) 2006 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: Simple Engine +* +*/ + + + + +// INCLUDE FILES + +#include +#include + +// own simple +#include "msimpleconnection.h" +#include "simpleconnection.h" +#include "simplecommon.h" +#include "simpleenginerequest.h" +#include "msimpledocument.h" +#include "msimplepublishobserver.h" +#include "msimpleetagobserver.h" +#include "simplepublisher.h" + + +#include "simplesipconnection.h" + +#ifdef _DEBUG +#include "simpledebugutils.h" +#endif + +const TInt KSimpleExpandSize = 512; + +// ================= MEMBER FUNCTIONS ======================= +// + +// ---------------------------------------------------------- +// CSimplePublisher::CSimplePublisher +// ---------------------------------------------------------- +// +CSimplePublisher::CSimplePublisher( + MSimpleConnection& aConn, + MSimplePublishObserver& aObserver ) +: CSimpleClient( aConn ), + iPublished( EFalse ), + iObserver( aObserver ), iBuffer(NULL), iETagObserver( NULL ) + { + } + +// ---------------------------------------------------------- +// CSimplePublisher::~CSimplePublisher +// ---------------------------------------------------------- +// +CSimplePublisher::~CSimplePublisher() + { +#ifdef _DEBUG + TSimpleLogger::Log(_L("Publisher: Destructor this=%d" ), (TInt)this ); +#endif + delete iBuffer; + delete iETag; + } + +// ---------------------------------------------------------- +// CSimplePublisher::ConstructL +// ---------------------------------------------------------- +// +void CSimplePublisher::ConstructL() + { + BaseConstructL(); + iBuffer = CBufFlat::NewL(KSimpleExpandSize); + } + +// ---------------------------------------------------------- +// CSimplePublisher::NewL +// ---------------------------------------------------------- +// +CSimplePublisher* CSimplePublisher::NewL( + MSimpleConnection& aConn, + MSimplePublishObserver& aObserver ) + { + CSimplePublisher* self = new (ELeave) CSimplePublisher( + aConn, aObserver ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); +#ifdef _DEBUG + TSimpleLogger::Log(_L("Publisher: NewL this=%d" ), (TInt)self ); +#endif + return self; + } + +// ---------------------------------------------------------- +// CSimplePublisher::SIPStatus +// ---------------------------------------------------------- +// +TUint CSimplePublisher::SIPStatus() + { + return DoSIPStatus(); + } + +// ---------------------------------------------------------- +// CSimplePublisher::SIPRetryAfter +// ---------------------------------------------------------- +// +TUint CSimplePublisher::SIPRetryAfter() + { + return DoRetryAfter(); + } + +// ---------------------------------------------------------- +// CSimplePublisher::Connection +// ---------------------------------------------------------- +// +const MSimpleConnection& CSimplePublisher::Connection() + { + return iConn; + } + +// ---------------------------------------------------------- +// CSimplePublisher::StartPublishL +// ---------------------------------------------------------- +// +TInt CSimplePublisher::StartPublishL( MSimpleDocument& aDocument, + TBool aRefresh ) + { + + IncreaseOpId(); + +#ifdef _DEBUG + TSimpleLogger::Log(_L("Publisher: StartPublishL opid=%d" ), iOpId ); +#endif + + if ( iRequest != MSimpleEngineRequest::ENone ) + { + User::Leave( KErrInUse ); + } + + return DoStartPublishL( aDocument, aRefresh, KNullDesC8 ); + } + +// ---------------------------------------------------------- +// CSimplePublisher::ContinuePublishL +// ---------------------------------------------------------- +// +TInt CSimplePublisher::ContinuePublishL( MSimpleDocument& aDocument, + TBool aRefresh, const TDesC8& aETag ) + { + + IncreaseOpId(); + +#ifdef _DEBUG + TBuf<100> myETag; + myETag.Copy( aETag ); + TSimpleLogger::Log(_L("Publisher: ContinuePublishL opid=%d ETag=%S" ), iOpId, &myETag ); +#endif + + return DoStartPublishL( aDocument, aRefresh, aETag ); + + } + +// ---------------------------------------------------------- +// CSimplePublisher::ModifyPublishL +// ---------------------------------------------------------- +// +TInt CSimplePublisher::ModifyPublishL( MSimpleDocument& aDocument ) + { + +#ifdef _DEBUG + TSimpleLogger::Log(_L("Publisher: ModifyPublishL opid=%d" ), iOpId ); +#endif + + // use the old opid and request + CSimpleEngineRequest* req = SearchRequests( iOpId ); + if ( !req ) + { + User::Leave( KErrNotFound ); + } + req->ModifyType( MSimpleEngineRequest::EPublishModify ); + + // add request data + StreamDocumentL( *req, aDocument ); + + // Set MIME type of the request + RPointerArray contents; + CleanupClosePushL( contents ); + aDocument.GetDirectContentsL( contents ); + if ( contents.Count() ) + { + req->SetRequestContentTypeL( KSimpleMultipartType ); + } + else + { + req->SetRequestContentTypeL( KSimpleDocumentType ); + } + CleanupStack::PopAndDestroy( &contents ); + + // send a request to engine DLL + SendReqL( *req ); + + iRequest = MSimpleEngineRequest::EPublishModify; + iSipStatus = 0; + return iOpId; + } + +// ---------------------------------------------------------- +// CSimplePublisher::StopPublishL +// ---------------------------------------------------------- +// +TInt CSimplePublisher::StopPublishL() + { + +#ifdef _DEBUG + TSimpleLogger::Log(_L("Publisher: StopPublishL opid=%d" ), iOpId ); +#endif + + // use the old opid and request + CSimpleEngineRequest* req = SearchRequests( iOpId ); + if ( !req ) + { + User::Leave( KErrNotFound ); + } + req->ModifyType( MSimpleEngineRequest::EStopPublish ); + + // send a request to engine DLL + SendReqL( *req ); + + iRequest = MSimpleEngineRequest::EStopPublish; + iPublished = EFalse; + iSipStatus = 0; + return iOpId; + } + +// ---------------------------------------------------------- +// CSimplePublisher::StopPublishL +// ---------------------------------------------------------- +// +TInt CSimplePublisher::StopPublishL( const TDesC8& aETag ) + { + +#ifdef _DEBUG + TBuf<100> myETag; + myETag.Copy( aETag ); + TSimpleLogger::Log(_L("Publisher: StopPublishL opid=%d ETag=%S" ), iOpId, &myETag ); +#endif + + // use the old opid and request + CSimpleEngineRequest* req = SearchRequests( iOpId ); + + if ( iRequest != MSimpleEngineRequest::ENone && !req ) + { + User::Leave( KErrNotFound ); + } + else if ( !req ) + { + IncreaseOpId(); + // create a new request when starting from scratch + req = CSimpleEngineRequest::NewL( + *this, MSimpleEngineRequest::EStopPublish, iOpId ); + iRequestList.AddLast( *req ); + } + + req->ModifyType( MSimpleEngineRequest::EStopPublish ); + req->SetETagL( aETag ); + + // send a request to engine DLL + SendReqL( *req ); + + iRequest = MSimpleEngineRequest::EStopPublish; + iPublished = EFalse; + iSipStatus = 0; + return iOpId; + } + +// ---------------------------------------------------------- +// CSimplePublisher::SIPETag +// ---------------------------------------------------------- +TPtrC8 CSimplePublisher::SIPETag() + { + return iETag ? iETag->Des() : TPtrC8(); + } + +// ---------------------------------------------------------- +// CSimplePublisher::SetSIPETagObserver +// ---------------------------------------------------------- +void CSimplePublisher::SetSIPETagObserver( MSimpleETagObserver* aObs ) + { + iETagObserver = aObs; + } + +// ---------------------------------------------------------- +// CSimplePublisher::Close +// ---------------------------------------------------------- +// +void CSimplePublisher::Close( ) + { + delete this; + } + +// ---------------------------------------------------------- +// CSimplePublisher::Complete +// ---------------------------------------------------------- +// +void CSimplePublisher::Complete( + TInt aOpId, TInt aStatus, MSimpleEngineRequest& aReq ) + { +#ifdef _DEBUG + TSimpleLogger::Log(_L("Publisher: Complete opid=%d, status=%d" ), + aOpId, aStatus ); +#endif + + MSimpleEngineRequest::TSimpleRequest origRequest = iRequest; + TBool myTerminated( EFalse ); + + GetSIPStatus( aOpId ); + + // Allocate ETag when needed and call callback + if ( SIPETag().CompareF( aReq.ETag() )) + { + delete iETag; + iETag = NULL; + TRAPD( errMem, iETag = aReq.ETag().AllocL() ); + if ( iETagObserver && !errMem ) + { + TRAP_IGNORE( iETagObserver->NewETagL( iETag->Des() )); + } + } + + if ( aReq.ResponseMethod() == MSimpleEngineRequest:: EStatusETag ) + { + // If only ETag was updated then all is done this time. + return; + } + + // Reset data buffer + iBuffer->Reset(); + + // Set the member to point to stack variable + TBool destroyed( EFalse ); + iDestroyedPtr = &destroyed; + + if ( !aStatus && origRequest == MSimpleEngineRequest::EStartPublish ) + { + iPublished = ETrue; + } + + // Select the right callback method + if ( iPublished && + origRequest == MSimpleEngineRequest::EStartPublish && + aStatus ) + { +#ifdef _DEBUG + TSimpleLogger::Log(_L("Publisher: call PublishTerminatedL opid=%d" ), aOpId ); +#endif + myTerminated = ETrue; + TRAP_IGNORE( iObserver.PublishTerminatedL( aOpId )); + // Check whether an application has called destructor in callback method. + // Destructor will handle deletion of all the open requests. + if ( destroyed ) + { + return; + } + } + else + { + // If modify fails then it does not always mean the whole + // publish is failed. +#ifdef _DEBUG + TSimpleLogger::Log(_L("Publisher: call PublishReqCompleteL opid=%d status=%d" ), + aOpId, aStatus ); +#endif + TRAP_IGNORE( iObserver.PublishReqCompleteL( aOpId, aStatus ) ); + // Check whether an application has called destructor in callback method. + // Destructor will handle deletion of all the open requests. + if ( destroyed ) + { + return; + } + if ( aStatus == KErrCompletion || aStatus == KErrDisconnected ) + { + myTerminated = ETrue; + // KErrCompletion error code is used when publication is terminated. + TRAP_IGNORE( iObserver.PublishTerminatedL( aOpId ) ); + // Check whether an application has called destructor in callback method. + // Destructor will handle deletion of all the open requests. + if ( destroyed ) + { + return; + } + } + } + + // Delete a request when not needed anymore. + if (( aStatus != KErrNone && origRequest == MSimpleEngineRequest::EStartPublish ) || + origRequest == MSimpleEngineRequest::EStopPublish || + myTerminated ) + { + iRequest = MSimpleEngineRequest::ENone; + iPublished = EFalse; + + // delete corresponding request from another DLL too. + aReq.ModifyType( MSimpleEngineRequest::EDestroy ); + TRAP_IGNORE( SendReqL( aReq )); + // delete request from this DLL. + aReq.Destroy(); + } + + // Set iRequest back to EStartPublish after Modify request. + // This helps to handle error situations above. + else if ( origRequest == MSimpleEngineRequest::EPublishModify ) + { + iRequest = MSimpleEngineRequest::EStartPublish; + aReq.ModifyType( MSimpleEngineRequest::EStartPublish ); + } + + iDestroyedPtr = NULL; + } + +// ---------------------------------------------------------- +// CSimplePublisher::StreamDocumentL +// ---------------------------------------------------------- +// +void CSimplePublisher::StreamDocumentL( + CSimpleEngineRequest& aReq, + MSimpleDocument& aDocument ) + { + // add request data + // externalize the document a stream + iBuffer->Reset(); + RBufWriteStream stream( *iBuffer ); + stream.Open( *iBuffer ); + aDocument.ExternalizeL( stream ); + stream.Close(); + aReq.SetRequestData( iBuffer->Ptr(0) ); + } + +// ---------------------------------------------------------- +// CSimplePublisher::DoStartPublishL +// ---------------------------------------------------------- +// +TInt CSimplePublisher::DoStartPublishL( MSimpleDocument& aDocument, + TBool aRefresh, const TDesC8& aETag ) + { + if ( iRequest != MSimpleEngineRequest::ENone ) + { + User::Leave( KErrInUse ); + } + + CSimpleEngineRequest* req = CSimpleEngineRequest::NewL( + *this, MSimpleEngineRequest::EStartPublish, iOpId ); + CleanupStack::PushL( req ); + req->SetRefresh( aRefresh ); + // add remote uri + const TDesC8* p8 = aDocument.EntityURI(); + req->SetRemoteURIL( *p8 ); + // set ETag + req->SetETagL( aETag ); + + // add request data + StreamDocumentL( *req, aDocument ); + + // Set MIME type of the request + RPointerArray contents; + CleanupClosePushL( contents ); + aDocument.GetDirectContentsL( contents ); + if ( contents.Count() ) + { + req->SetRequestContentTypeL( KSimpleMultipartType ); + } + else + { + req->SetRequestContentTypeL( KSimpleDocumentType ); + } + CleanupStack::PopAndDestroy( &contents ); + + // send a request to engine DLL + SendReqL( *req ); + iRequestList.AddLast( *req ); + CleanupStack::Pop( req ); + + iRequest = MSimpleEngineRequest::EStartPublish; + iSipStatus = 0; + return iOpId; + } + +