ncdengine/provider/server/src/ncdnodeiconimpl.cpp
changeset 0 ba25891c3a9e
--- /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;
+        }
+    }