diff -r 000000000000 -r ba25891c3a9e ncdengine/provider/server/src/ncdnodecontentinfoimpl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ncdengine/provider/server/src/ncdnodecontentinfoimpl.cpp Thu Dec 17 08:51:10 2009 +0200 @@ -0,0 +1,412 @@ +/* +* Copyright (c) 2006-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: Implements CNcdNodeContentInfo class +* +*/ + + +#include "ncdnodecontentinfoimpl.h" +#include "catalogssession.h" +#include "catalogsbasemessage.h" +#include "ncdnodefunctionids.h" +#include "ncdnodeclassids.h" +#include "catalogsconstants.h" +#include "ncd_pp_dataentity.h" +#include "ncd_pp_dataentitycontent.h" +#include "ncd_cp_query.h" +#include "ncditempurpose.h" +#include "catalogsutils.h" +#include "ncderrors.h" +#include "ncdproviderutils.h" +#include "ncdinstallationservice.h" +#include "ncdpurchasedetails.h" + +#include "catalogsdebug.h" + +CNcdNodeContentInfo::CNcdNodeContentInfo( NcdNodeClassIds::TNcdNodeClassId aClassId ) +: CNcdCommunicable(), + iClassId( aClassId ) + { + } + +void CNcdNodeContentInfo::ConstructL() + { + iMimeType = KNullDesC().AllocL(); + iVersion = KNullDesC().AllocL(); + + } + + +CNcdNodeContentInfo* CNcdNodeContentInfo::NewL() + { + CNcdNodeContentInfo* self = + CNcdNodeContentInfo::NewLC(); + CleanupStack::Pop( self ); + return self; + } + +CNcdNodeContentInfo* CNcdNodeContentInfo::NewLC() + { + CNcdNodeContentInfo* self = + new( ELeave ) CNcdNodeContentInfo( + NcdNodeClassIds::ENcdNodeContentInfoClassId ); + CleanupClosePushL( *self ); + self->ConstructL(); + return self; + } + + +CNcdNodeContentInfo::~CNcdNodeContentInfo() + { + DLTRACEIN(("")); + + delete iMimeType; + iMimeType = NULL; + + delete iVersion; + iVersion = NULL; + + DLTRACEOUT(("")); + } + +NcdNodeClassIds::TNcdNodeClassId CNcdNodeContentInfo::ClassId() const + { + return iClassId; + } + +TUint CNcdNodeContentInfo::Purpose() const + { + return iPurpose; + } + +const TDesC& CNcdNodeContentInfo::MimeType() const + { + return *iMimeType; + } + +const TUid& CNcdNodeContentInfo::Uid() const + { + return iUid; + } + +const TDesC& CNcdNodeContentInfo::Version() const + { + return *iVersion; + } + +TInt CNcdNodeContentInfo::TotalContentSize() const + { + return iSize; + } + + +// Internalization from the protocol + +void CNcdNodeContentInfo::InternalizeL( + MNcdPreminetProtocolDataEntity& aData ) + { + DLTRACEIN(("")); + + if ( ! aData.DownloadableContent() ) + { + DLERROR(("No content data present")); + // Content info should not be internalized if there is no content info + // available. + DASSERT( EFalse ); + // Content data not present. + User::Leave( KErrNotFound ); + } + + iPurpose = 0; + + delete iMimeType; + iMimeType = NULL; + + iUid = TUid::Null(); + + delete iVersion; + iVersion = NULL; + + // Construct purpose. + TInt purposeCount = aData.DownloadableContent()->ContentPurposeCount(); + for ( TInt i = 0; i < purposeCount; i++ ) + { + const TDesC& purpose = + aData.DownloadableContent()->ContentPurposeL( i ); + + // Notice that the content purpose does not need to be case insensitive. + // According to the specification the purposes should be given in all + // lower case characters. So, the Compare function should be used here, + // which is much faster than using of CompareF function. + if ( purpose.Compare( KNcdContentPurposeMusic ) == 0 ) + { + iPurpose |= ENcdItemPurposeMusic; + } + else if ( purpose.Compare( KNcdContentPurposeRingtone ) == 0 ) + { + iPurpose |= ENcdItemPurposeRingtone; + } + else if ( purpose.Compare( KNcdContentPurposeWallpaper ) == 0 ) + { + iPurpose |= ENcdItemPurposeWallpaper; + } + else if ( purpose.Compare( KNcdContentPurposeVideo ) == 0 ) + { + iPurpose |= ENcdItemPurposeVideo; + } + else if ( purpose.Compare( KNcdContentPurposeTheme ) == 0 ) + { + iPurpose |= ENcdItemPurposeTheme; + } + else if ( purpose.Compare( KNcdContentPurposeApplication ) == 0 ) + { + iPurpose |= ENcdItemPurposeApplication; + } + else if ( purpose.Compare( KNcdContentPurposeHtmlPage ) == 0 ) + { + iPurpose |= ENcdItemPurposeHtmlPage; + } + else if ( purpose.Compare( KNcdContentPurposeGame ) == 0 ) + { + iPurpose |= ENcdItemPurposeGame; + } + else if ( purpose.Compare( KNcdContentPurposeScreensaver ) == 0 ) + { + iPurpose |= ENcdItemPurposeScreensaver; + } + else if ( purpose.Compare( KNcdContentPurposeStream ) == 0 ) + { + iPurpose |= ENcdItemPurposeStream; + } + else + { + iPurpose |= ENcdItemPurposeUnknown; + } + } + + iMimeType = aData.DownloadableContent()->Mime().AllocL(); + + if ( iPurpose & ENcdItemPurposeApplication ) + { + TInt uid = 0; + TRAPD( err, uid = DesHexToIntL( aData.DownloadableContent()->Id() ) ); + if( err != KErrNone ) + { + DLERROR(( _L("DownloadableContent()->Id() was not valid hex, using ZERO: %S"), + &aData.DownloadableContent()->Id() )); + iUid.iUid = 0; + } + else + { + iUid.iUid = uid; + } + } + + iVersion = aData.DownloadableContent()->Version().AllocL(); + iSize = aData.DownloadableContent()->Size(); + + DLTRACEOUT(("")); + } + + +// Internalization from and externalization to the database + +void CNcdNodeContentInfo::ExternalizeL( RWriteStream& aStream ) + { + DLTRACEIN(("")); + + aStream.WriteInt32L( ClassId() ); + + aStream.WriteUint16L( iPurpose ); + ExternalizeDesL( *iMimeType, aStream ); + aStream.WriteInt32L( iUid.iUid ); + ExternalizeDesL( *iVersion, aStream ); + aStream.WriteInt32L( iSize ); + + DLTRACEOUT(("")); + } + + +void CNcdNodeContentInfo::InternalizeL( RReadStream& aStream ) + { + DLTRACEIN(("")); + + // Read the class id first because it is set to the stream in internalize + // function and it is not read from the stream anywhere else. + TInt classId( aStream.ReadInt32L() ); + if ( classId != ClassId() ) + { + DLTRACE(("Wrong class id")); + DASSERT( EFalse ); + // Leave because the stream does not match this class object + User::Leave( KErrCorrupt ); + } + + iPurpose = aStream.ReadUint16L(); + InternalizeDesL( iMimeType, aStream ); + iUid.iUid = aStream.ReadInt32L(); + InternalizeDesL( iVersion, aStream ); + iSize = aStream.ReadInt32L(); + + DLTRACEOUT(("")); + } + + +void CNcdNodeContentInfo::InternalizeL( const MNcdPurchaseDetails& aDetails ) + { + DLTRACEIN(("")); + iPurpose = aDetails.ItemPurpose(); + iSize = aDetails.TotalContentSize(); + iUid.iUid = aDetails.AttributeInt32( + MNcdPurchaseDetails::EPurchaseAttributeContentUid ); + AssignDesL( iVersion, aDetails.Version() ); + AssignDesL( iMimeType, aDetails.AttributeString( + MNcdPurchaseDetails::EPurchaseAttributeContentMimeType ) ); + } + + +void CNcdNodeContentInfo::ReceiveMessage( MCatalogsBaseMessage* aMessage, + TInt aFunctionNumber ) + { + DLTRACEIN(("")); + + DASSERT( aMessage ); + + // Now, we can be sure that rest of the time iMessage exists. + // This member variable is set for the CounterPartLost function. + iMessage = aMessage; + + TInt trapError( KErrNone ); + + // Check which function is called by the proxy side object. + // Function number are located in ncdnodefunctinoids.h file. + switch( aFunctionNumber ) + { + case NcdNodeFunctionIds::ENcdInternalize: + // Internalize the proxy side according to the data + // of this object. + TRAP( trapError, InternalizeRequestL( *aMessage ) ); + break; + + case NcdNodeFunctionIds::ENcdRelease: + // The proxy does not want to use this object anymore. + // So, release the handle from the session. + ReleaseRequest( *aMessage ); + break; + + default: + DLERROR(("Unidentified function request")); + DASSERT( EFalse ); + break; + } + + if ( trapError != KErrNone ) + { + // Because something went wrong, the complete has not been + // yet called for the message. + // So, inform the client about the error if the + // message is still available. + aMessage->CompleteAndRelease( trapError ); + } + + // Because the message should not be used after this, set it NULL. + // So, CounterPartLost function will know that no messages are + // waiting the response at the moment. + iMessage = NULL; + + DLTRACEOUT(("")); + } + +void CNcdNodeContentInfo::CounterPartLost( const MCatalogsSession& aSession ) + { + // This function may be called whenever -- when the message is waiting + // response or when the message does not exist. + // iMessage may be NULL here, because in the end of the + // ReceiveMessage it is set to NULL. The life time of the message + // ends shortly after CompleteAndRelease is called. + if ( iMessage != NULL ) + { + iMessage->CounterPartLost( aSession ); + } + } + + +void CNcdNodeContentInfo::InternalizeRequestL( MCatalogsBaseMessage& aMessage ) + { + DLTRACEIN(("")); + + CBufBase* buf = CBufFlat::NewL( KBufExpandSize ); + CleanupStack::PushL( buf ); + + RBufWriteStream stream( *buf ); + CleanupClosePushL( stream ); + + + // Include all the necessary node data to the stream + ExternalizeDataForRequestL( stream ); + + + // Commits data to the stream when closing. + CleanupStack::PopAndDestroy( &stream ); + + + // If this leaves, ReceiveMessage will complete the message. + // NOTE: that here we expect that the buffer contains at least + // some data. So, make sure that ExternalizeDataForRequestL inserts + // something to the buffer. + aMessage.CompleteAndReleaseL( buf->Ptr( 0 ), KErrNone ); + + + DLTRACE(("Deleting the buf")); + CleanupStack::PopAndDestroy( buf ); + + DLTRACEOUT(("")); + } + + +void CNcdNodeContentInfo::ExternalizeDataForRequestL( RWriteStream& aStream ) + { + DLTRACEIN(("")); + + if ( IsObsolete() ) + { + DLINFO(("Set as obsolete. This means that server has removed the object.")); + User::Leave( KNcdErrorObsolete ); + } + + ExternalizeL( aStream ); + + DLTRACEOUT(("")); + } + +void CNcdNodeContentInfo::ReleaseRequest( MCatalogsBaseMessage& aMessage ) const + { + DLTRACEIN(("")); + + // Decrease the reference count for this object. + // When the reference count reaches zero, this object will be destroyed + // and removed from the session. + MCatalogsSession& requestSession( aMessage.Session() ); + TInt handle( aMessage.Handle() ); + + // Send complete information back to proxy. + aMessage.CompleteAndRelease( KErrNone ); + + // Remove this object from the session. + requestSession.RemoveObject( handle ); + + DLTRACEOUT(("")); + } + +