--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ncdengine/provider/server/src/ncdnodeiconimpl.cpp Thu Dec 17 08:51:10 2009 +0200
@@ -0,0 +1,474 @@
+/*
+* 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: Implements CNcdNodeIcon class
+*
+*/
+
+
+#include "ncdnodeiconimpl.h"
+#include "catalogssession.h"
+#include "catalogsbasemessage.h"
+#include "ncdnodemanager.h"
+#include "ncdnodemetadataimpl.h"
+#include "ncdnodefunctionids.h"
+#include "ncdnodeclassids.h"
+#include "ncd_pp_icon.h"
+#include "catalogsconstants.h"
+#include "ncd_pp_dataentity.h"
+#include "ncd_cp_query.h"
+#include "catalogsutils.h"
+#include "catalogsdebug.h"
+#include "ncdnodeidentifier.h"
+#include "ncderrors.h"
+#include "ncdutils.h"
+
+
+_LIT( KNcdPurchaseDetailsIconIdPrefix, "*PD_1c0n*");
+
+CNcdNodeIcon* CNcdNodeIcon::NewL(
+ CNcdNodeManager& aNodeManager,
+ const CNcdNodeMetaData& aParentMetaData,
+ TBool aUsePurchaseDetailsIcon )
+ {
+ CNcdNodeIcon* self =
+ CNcdNodeIcon::NewLC( aNodeManager, aParentMetaData,
+ aUsePurchaseDetailsIcon );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+CNcdNodeIcon* CNcdNodeIcon::NewLC(
+ CNcdNodeManager& aNodeManager,
+ const CNcdNodeMetaData& aParentMetaData,
+ TBool aUsePurchaseDetailsIcon )
+ {
+ CNcdNodeIcon* self =
+ new( ELeave ) CNcdNodeIcon(
+ NcdNodeClassIds::ENcdNodeIconClassId,
+ aNodeManager,
+ aParentMetaData,
+ aUsePurchaseDetailsIcon );
+ CleanupClosePushL( *self );
+ self->ConstructL();
+ return self;
+ }
+
+
+CNcdNodeIcon::CNcdNodeIcon(
+ NcdNodeClassIds::TNcdNodeClassId aClassId,
+ CNcdNodeManager& aNodeManager,
+ const CNcdNodeMetaData& aParentMetaData,
+ TBool aUsePurchaseDetailsIcon )
+ : CNcdCommunicable(),
+ iNodeManager( aNodeManager ),
+ iParentMetaData( aParentMetaData ),
+ iClassId( aClassId ),
+ iIconDataReady ( ETrue ),
+ iUsePurchaseDetailsIcon( aUsePurchaseDetailsIcon )
+ {
+ }
+
+void CNcdNodeIcon::ConstructL()
+ {
+ iDataBlock = KNullDesC().AllocL();
+ if( iUsePurchaseDetailsIcon )
+ {
+ iIconId = HBufC::NewL( KNcdPurchaseDetailsIconIdPrefix().Length() +
+ iParentMetaData.Identifier().NodeId().Length() +
+ iParentMetaData.Identifier().NodeNameSpace().Length() );
+ iIconId->Des().Append( KNcdPurchaseDetailsIconIdPrefix );
+ iIconId->Des().Append( iParentMetaData.Identifier().NodeId() );
+ iIconId->Des().Append( iParentMetaData.Identifier().NodeNameSpace() );
+ }
+ else
+ {
+ iIconId = KNullDesC().AllocL();
+ }
+ iUri = KNullDesC().AllocL();
+ }
+
+CNcdNodeIcon::~CNcdNodeIcon()
+ {
+ DLTRACEIN((""));
+
+ // Delete member variables here
+
+ delete iDataBlock;
+ iDataBlock = NULL;
+
+ delete iIconId;
+ iIconId = NULL;
+
+ delete iUri;
+ iUri = NULL;
+
+ DLTRACEOUT((""));
+ }
+
+NcdNodeClassIds::TNcdNodeClassId CNcdNodeIcon::ClassId() const
+ {
+ return iClassId;
+ }
+
+
+// Internalization from the protocol
+
+void CNcdNodeIcon::InternalizeL( MNcdPreminetProtocolDataEntity& aData )
+ {
+ DLTRACEIN((""));
+
+ iUsePurchaseDetailsIcon = EFalse;
+ if ( ! aData.Icon() )
+ {
+ // Icon data not present.
+ User::Leave( KErrNotFound );
+ }
+
+ // First create the new values
+
+ HBufC* tmpDataBlock = aData.Icon()->DataBlock().AllocLC();
+ DLINFO((_L("datablock: %S"), tmpDataBlock));
+
+ HBufC* tmpId = aData.Icon()->Id().AllocLC();
+ DLINFO((_L("id: %S"), tmpId));
+
+ HBufC* tmpUri = aData.Icon()->Uri().AllocLC();
+ DLINFO((_L("uri: %S"), tmpUri));
+
+
+ // Now, that we are sure we have correctly created new values and the
+ // code cannot leave here, set the tmp values to the member variables.
+
+ delete iUri;
+ iUri = tmpUri;
+ CleanupStack::Pop( tmpUri );
+
+ delete iIconId;
+ iIconId = tmpId;
+ CleanupStack::Pop( tmpId );
+
+ delete iDataBlock;
+ iDataBlock = tmpDataBlock;
+ CleanupStack::Pop( tmpDataBlock );
+
+ // If icon data is obtained inline, save the data to database
+ if ( aData.Icon()->Data() != KNullDesC8 )
+ {
+ CNcdNodeIdentifier* iconIdentifier =
+ CNcdNodeIdentifier::NewLC( iParentMetaData.Identifier().NodeNameSpace(),
+ *iIconId,
+ Uri(),
+ iParentMetaData.Identifier().ClientUid() );
+
+ iNodeManager.DbSaveIconDataL( *iconIdentifier,
+ aData.Icon()->Data() );
+
+ CleanupStack::PopAndDestroy( iconIdentifier );
+ }
+
+ DLTRACEOUT((""));
+ }
+
+
+// Internalization from and externalization to the database
+
+void CNcdNodeIcon::ExternalizeL( RWriteStream& aStream )
+ {
+ DLTRACEIN((""));
+
+ // Set all the membervariable values to the stream. So,
+ // that the stream may be used later to create a new
+ // object.
+
+ // First insert data that the creator of this class object will use to
+ // create this class object. Class id informs what class object
+ // will be created.
+
+ aStream.WriteInt32L( iClassId );
+
+
+ // Write the data that will be used when internalize function
+ // is called. catalogsutils.h contains good internalize and
+ // externalize functions.
+ // Make sure that this matches to the order that is used
+ // when this stream is internalized.
+
+ ExternalizeDesL( *iDataBlock, aStream );
+ ExternalizeDesL( *iIconId, aStream );
+ ExternalizeDesL( *iUri, aStream );
+ aStream.WriteInt32L( iUsePurchaseDetailsIcon );
+
+ DLTRACEOUT((""));
+ }
+
+
+void CNcdNodeIcon::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() )
+ {
+ DLERROR(("Wrong class id"));
+ DASSERT( EFalse );
+ // Leave because the stream does not match this class object
+ User::Leave( KErrCorrupt );
+ }
+
+ InternalizeDesL( iDataBlock, aStream );
+ InternalizeDesL( iIconId, aStream );
+ InternalizeDesL( iUri, aStream );
+ iUsePurchaseDetailsIcon = aStream.ReadInt32L();
+
+ DLTRACEOUT((""));
+ }
+
+
+
+void CNcdNodeIcon::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::ENcdIconData:
+ // Get icon data.
+ TRAP( trapError, IconDataRequestL( *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 CNcdNodeIcon::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 );
+ }
+ }
+
+const TDesC& CNcdNodeIcon::DataBlock() const
+ {
+ DASSERT( iDataBlock );
+ return *iDataBlock;
+ }
+
+const TDesC& CNcdNodeIcon::IconId() const
+ {
+ DASSERT( iIconId );
+ return *iIconId;
+ }
+
+void CNcdNodeIcon::SetIconIdL( const TDesC& aIconId )
+ {
+ HBufC* newId = aIconId.AllocL();
+ delete iIconId;
+ iIconId = newId;
+ }
+
+const TDesC& CNcdNodeIcon::Uri() const
+ {
+ DASSERT( iUri );
+ return *iUri;
+ }
+
+void CNcdNodeIcon::SetUriL( const TDesC& aUri )
+ {
+ HBufC* newUri = aUri.AllocL();
+ delete iUri;
+ iUri = newUri;
+ }
+
+TBool CNcdNodeIcon::IconDataReady() const
+ {
+ return iIconDataReady;
+ }
+
+void CNcdNodeIcon::SetIconDataReady( TBool aValue )
+ {
+ iIconDataReady = aValue;
+ }
+
+
+void CNcdNodeIcon::InternalizeRequestL( MCatalogsBaseMessage& aMessage ) const
+ {
+ DLTRACEIN((""));
+
+ CBufBase* buf = CBufFlat::NewL( KBufExpandSize );
+ CleanupStack::PushL( buf );
+
+ RBufWriteStream stream( *buf );
+ CleanupClosePushL( stream );
+
+
+ // Include all the necessary 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 );
+
+
+ DLINFO(("Deleting the buf"));
+ CleanupStack::PopAndDestroy( buf );
+
+ DLTRACEOUT((""));
+ }
+
+
+void CNcdNodeIcon::ExternalizeDataForRequestL( RWriteStream& aStream ) const
+ {
+ DLTRACEIN((""));
+
+ if ( IsObsolete() )
+ {
+ DLINFO(("Set as obsolete. This means that server has removed the object."));
+ User::Leave( KNcdErrorObsolete );
+ }
+
+ // Icon existed. So, insert info that meta data was found.
+ aStream.WriteInt32L( ClassId() );
+
+ // Add additional content to the stream.
+ // Make sure that this matches to the order that is used in the proxy
+ // side when this stream is internalized.
+ // NOTE: Be careful with the 8- and 16-bit descriptors. Remember to check
+ // if the proxy wants the data in 16 or 8 bits?
+
+ ExternalizeDesL( *iIconId, aStream );
+
+ DLTRACEOUT((""));
+ }
+
+void CNcdNodeIcon::IconDataRequestL( MCatalogsBaseMessage& aMessage ) const
+ {
+ DLTRACEIN((""));
+
+ // If this leaves, ReceiveMessage will complete the message.
+
+ if ( ! iIconId )
+ {
+ User::Leave( KErrNotFound );
+ }
+
+ HBufC8* icon = IconDataL();
+ CleanupStack::PushL( icon );
+
+ aMessage.CompleteAndReleaseL( *icon, KErrNone );
+
+ CleanupStack::PopAndDestroy( icon );
+
+ DLTRACEOUT((""));
+ }
+
+void CNcdNodeIcon::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((""));
+ }
+
+HBufC8* CNcdNodeIcon::IconDataL() const
+ {
+ if( iUsePurchaseDetailsIcon )
+ {
+ // Get purchase details with icon.
+ CNcdPurchaseDetails* purchaseDetails =
+ iParentMetaData.PurchaseDetailsLC( ETrue );
+ HBufC8* iconData = purchaseDetails->GetIconData();
+ CleanupStack::PopAndDestroy( purchaseDetails );
+ return iconData;
+ }
+ else
+ {
+ CNcdNodeIdentifier* iconIdentifier =
+ CNcdNodeIdentifier::NewLC( iParentMetaData.Identifier().NodeNameSpace(),
+ *iIconId,
+ Uri(),
+ iParentMetaData.Identifier().ClientUid() );
+ HBufC8* icon = iNodeManager.DbIconDataLC( *iconIdentifier );
+ CleanupStack::Pop( icon );
+ CleanupStack::PopAndDestroy( iconIdentifier );
+ return icon;
+ }
+ }