diff -r 000000000000 -r ba25891c3a9e ncdengine/provider/client/src/ncdsubscriptiongroupproxy.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ncdengine/provider/client/src/ncdsubscriptiongroupproxy.cpp Thu Dec 17 08:51:10 2009 +0200 @@ -0,0 +1,465 @@ +/* +* 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: Contains CNcdSubscriptionGroupProxy class implementation +* +*/ + + +#include "ncdsubscriptiongroupproxy.h" + +#include "ncdsubscriptionproxy.h" +#include "catalogsclientserver.h" +#include "ncdnodeidentifier.h" +#include "ncdnodefunctionids.h" +#include "ncdnodeclassids.h" +#include "catalogsutils.h" +#include "catalogsconstants.h" +#include "ncdnodeidentifier.h" + +#include "catalogsdebug.h" + +// ======== PUBLIC MEMBER FUNCTIONS ======== + +CNcdSubscriptionGroupProxy::CNcdSubscriptionGroupProxy( + MCatalogsClientServer& aSession, + TInt aHandle, + CNcdOperationManagerProxy& aOperationManager, + CNcdNodeManagerProxy& aNodeManager ) + : CNcdBaseProxy( aSession, aHandle ), + iOperationManager( aOperationManager ), + iNodeManager( aNodeManager ) + { + } + + +void CNcdSubscriptionGroupProxy::ConstructL() + { + // Is it ok if internalization fails here? + // Earlier comment: Do not let the internalization leave here. + // This object may be reinternalized later. + InternalizeL(); + } + + +CNcdSubscriptionGroupProxy* CNcdSubscriptionGroupProxy::NewL( + MCatalogsClientServer& aSession, + TInt aHandle, + CNcdOperationManagerProxy& aOperationManager, + CNcdNodeManagerProxy& aNodeManager ) + { + CNcdSubscriptionGroupProxy* self = + CNcdSubscriptionGroupProxy::NewLC( aSession, + aHandle, + aOperationManager, + aNodeManager ); + CleanupStack::Pop( self ); + return self; + } + +CNcdSubscriptionGroupProxy* CNcdSubscriptionGroupProxy::NewLC( + MCatalogsClientServer& aSession, + TInt aHandle, + CNcdOperationManagerProxy& aOperationManager, + CNcdNodeManagerProxy& aNodeManager ) + { + CNcdSubscriptionGroupProxy* self = + new( ELeave ) CNcdSubscriptionGroupProxy( aSession, + aHandle, + aOperationManager, + aNodeManager ); + CleanupStack::PushL( self ); + self->ConstructL(); + return self; + } + + +CNcdSubscriptionGroupProxy::~CNcdSubscriptionGroupProxy() + { + DeleteSubscriptions(); + + delete iOriginNodeIdentifier; + } + + +void CNcdSubscriptionGroupProxy::InternalizeL() + { + DLTRACEIN(("")); + + // Request all the purchase option ids from server side. + CDesCArray* poIds = RequestPurchaseOptionIdsL(); + CleanupStack::PushL( poIds ); + + // Delete the subscriptions that don't exist in the server side. + DeleteMissingSubscriptions( *poIds ); + + TRAPD( err, + { + // Reinternalize the existing subscriptions. + for ( TInt i = 0; i < iSubscriptions.Count(); i++ ) + { + iSubscriptions[i]->InternalizeL(); + } + + // Remove the existing subscriptions from the array. + for ( TInt i = poIds->Count() - 1 ; i >= 0; i-- ) + { + if ( Subscription( (*poIds)[i] ) != NULL ) + { + poIds->Delete( i ); + } + } + + // Internalize the group with the new subscriptions. + InternalizeL( *poIds ); + }); + + CleanupStack::PopAndDestroy( poIds ); + + if ( err != KErrNone ) + { + DLINFO((( "Internalize error: %d" ), err )); + DeleteSubscriptions(); + User::Leave( err ); + } + + DLTRACEOUT(("")); + } + +const RPointerArray& + CNcdSubscriptionGroupProxy::Subscriptions() + { + return iSubscriptions; + } + +CNcdSubscriptionProxy* CNcdSubscriptionGroupProxy::Subscription( + const TDesC& aPurchaseOptionId ) + { + DLTRACEIN(("")); + // Search for the subscriptions + + TInt subscriptionCount( iSubscriptions.Count() ); + TInt subscriptionIndexer( 0 ); + while ( subscriptionIndexer < subscriptionCount ) + { + + TDesC& subscriptionPurchaseOptionId = + iSubscriptions[subscriptionIndexer]->PurchaseOptionId(); + + if ( aPurchaseOptionId == subscriptionPurchaseOptionId ) + { + DLTRACEOUT(("Found.")); + return iSubscriptions[subscriptionIndexer]; + } + + ++subscriptionIndexer; + } + + DLTRACEOUT(("Did not find.")); + return NULL; + } + +const CNcdNodeIdentifier& CNcdSubscriptionGroupProxy::Identifier() const + { + return *iOriginNodeIdentifier; + } + +const TDesC& CNcdSubscriptionGroupProxy::EntityId() const + { + return iOriginNodeIdentifier->NodeId(); + } + +const TDesC& CNcdSubscriptionGroupProxy::Namespace() const + { + return iOriginNodeIdentifier->NodeNameSpace(); + } + +const TDesC& CNcdSubscriptionGroupProxy::ServerUri() const + { + return iOriginNodeIdentifier->ServerUri(); + } + +// --------------------------------------------------------------------------- +// Icon data is not stored on the proxies. It is retrieved from the server +// side every time the data is requested. +// --------------------------------------------------------------------------- +// +HBufC8* CNcdSubscriptionGroupProxy::IconL() const + { + HBufC8* icon( RequestIconDataL() ); + return icon; + } + +CNcdOperationManagerProxy& + CNcdSubscriptionGroupProxy::OperationManager() const + { + return iOperationManager; + } + + +// Other functions + + +void CNcdSubscriptionGroupProxy::InternalizeDataL( RReadStream& aStream ) + { + DLTRACEIN(("")); + + if ( !iOriginNodeIdentifier ) + { + iOriginNodeIdentifier = CNcdNodeIdentifier::NewL(); + } + iOriginNodeIdentifier->InternalizeL( aStream ); + + DLTRACE(( _L(" Internalizing subscriptiongroup info in proxy, EntityId: %S, Namespace: %S, server uri: %S"), + &iOriginNodeIdentifier->NodeId(), + &iOriginNodeIdentifier->NodeNameSpace(), + &iOriginNodeIdentifier->ServerUri() )); + + TInt handleAmount( 0 ); + handleAmount = aStream.ReadInt32L(); + + DLTRACE(( "Amount of subscription handles received: %d", + handleAmount )); + + TInt tmpProxyHandle( -1 ); // handle of a proxy read from stream + + // temporary pointer to subscription that is going to be + // added to subscriptions-array + CNcdSubscriptionProxy* tmpSubscription( NULL ); + + // In error handling, objects with received handles + // should be released from the server side session + // if proxies for them cannot be created. + + TInt handleIndex( 0 ); + while ( handleIndex < handleAmount ) + { + tmpProxyHandle = aStream.ReadInt32L(); + + DLTRACE(( "Received subscription handle: %i", + tmpProxyHandle )); + + tmpSubscription = CNcdSubscriptionProxy::NewL( + ClientServerSession(), + tmpProxyHandle, + OperationManager(), + iNodeManager, + *this ); + + + TRAPD( addError, iSubscriptions.AppendL( tmpSubscription ) ); + if ( addError != KErrNone ) + { + delete tmpSubscription; + User::Leave( addError ); + } + + tmpSubscription->InternalAddRef(); + + ++handleIndex; + } + + DLTRACEOUT(("")); + } + +void CNcdSubscriptionGroupProxy::DeleteSubscriptions() + { + + // If references to subscriptions are left, set it obsolete. + + TInt subscriptionsCount( iSubscriptions.Count() ); + TInt subscriptionsIndexer( 0 ); + while ( subscriptionsIndexer < subscriptionsCount ) + { + DeleteSubscription( iSubscriptions[subscriptionsIndexer] ); + ++subscriptionsIndexer; + } + + iSubscriptions.Reset(); + } + +CDesCArray* CNcdSubscriptionGroupProxy::RequestPurchaseOptionIdsL() const + { + DLTRACEIN(("")); + + HBufC8* data( NULL ); + + // Because we do not know the exact size of the data, use + // the alloc method, which creates the buffer of the right size + // and sets the pointer to point to the created buffer. + User::LeaveIfError( + ClientServerSession(). + SendSyncAlloc( NcdNodeFunctionIds::ENcdPurchaseOptionIds, + KNullDesC8, + data, + Handle(), + 0 ) ); + + if ( data == NULL ) + { + DLERROR(("")); + User::Leave( KErrNotFound ); + } + + CleanupStack::PushL( data ); + + // Read the data from the stream and create the array + RDesReadStream stream( *data ); + CleanupClosePushL( stream ); + + CDesCArray* poIds = new( ELeave ) CDesCArrayFlat( 5 ); + CleanupStack::PushL( poIds ); + + TInt idCount = stream.ReadInt32L(); + for ( TInt i = 0; i < idCount; i++ ) + { + HBufC* id( NULL ); + InternalizeDesL( id, stream ); + CleanupStack::PushL( id ); + poIds->AppendL( *id ); + CleanupStack::PopAndDestroy( id ); + } + + CleanupStack::Pop( poIds ); + CleanupStack::PopAndDestroy( &stream ); + CleanupStack::PopAndDestroy( data ); + + return poIds; + } + +void CNcdSubscriptionGroupProxy::DeleteMissingSubscriptions( + const CDesCArray& aPurchaseOptionIds ) + { + DLTRACEIN(("")); + + for ( TInt i = iSubscriptions.Count() - 1; i >= 0; i-- ) + { + TInt pos( 0 ); + if ( aPurchaseOptionIds.Find( iSubscriptions[i]->PurchaseOptionId(), pos ) + != 0 ) + { + DeleteSubscription( iSubscriptions[i] ); + iSubscriptions.Remove( i ); + } + } + } + +void CNcdSubscriptionGroupProxy::DeleteSubscription( + CNcdSubscriptionProxy* aSubscription ) + { + if ( aSubscription->TotalRefCount() > 1 ) + { + aSubscription->SetObsolete(); + } + aSubscription->InternalRelease(); + } + +void CNcdSubscriptionGroupProxy::InternalizeL( + const CDesCArray& aPurchaseOptionIds ) + { + DLTRACEIN(("")); + + CBufBase* buf = CBufFlat::NewL( KBufExpandSize ); + CleanupStack::PushL( buf ); + + RBufWriteStream writeStream( *buf ); + CleanupClosePushL( writeStream ); + + writeStream.WriteInt32L( aPurchaseOptionIds.Count() ); + for ( TInt i = 0; i < aPurchaseOptionIds.Count(); i++ ) + { + ExternalizeDesL( aPurchaseOptionIds[i], writeStream ); + } + + HBufC8* outputData = HBufC8::NewL( buf->Size() ); + outputData->Des().Copy( buf->Ptr( 0 ) ); + + CleanupStack::PopAndDestroy( &writeStream ); + CleanupStack::PopAndDestroy( buf ); + + CleanupStack::PushL( outputData ); + + HBufC8* inputData( NULL ); + + // Because we do not know the exact size of the data, use + // the alloc method, which creates the buffer of the right size + // and sets the pointer to point to the created buffer. + User::LeaveIfError( + ClientServerSession(). + SendSyncAlloc( NcdNodeFunctionIds::ENcdInternalize, + *outputData, + inputData, + Handle(), + 0 ) ); + + if ( inputData == NULL ) + { + DLERROR(("")); + User::Leave( KErrNotFound ); + } + + CleanupStack::PopAndDestroy( outputData ); + CleanupStack::PushL( inputData ); + + // Read the data from the stream and create the array + RDesReadStream stream( *inputData ); + CleanupClosePushL( stream ); + + InternalizeDataL( stream ); + + CleanupStack::PopAndDestroy( &stream ); + CleanupStack::PopAndDestroy( inputData ); + } + + +HBufC8* CNcdSubscriptionGroupProxy::RequestIconDataL() const + { + DLTRACEIN(("")); + + HBufC8* data( NULL ); + + // Because we do not know the exact size of the data, use + // the alloc method, which creates the buffer of the right size + // and sets the pointer to point to the created buffer. + // Get the icon data from the subscription group implementation + // on the server side. + User::LeaveIfError( + ClientServerSession(). + SendSyncAlloc( NcdNodeFunctionIds::ENcdSubscriptionIconData, + KNullDesC8, + data, + Handle(), + 0 ) ); + + if ( data == NULL ) + { + DLERROR(("")); + User::Leave( KErrNotFound ); + } + + CleanupStack::PushL( data ); + + // Read the data from the stream and insert it to variables + RDesReadStream stream( *data ); + CleanupClosePushL( stream ); + + HBufC8* iconData( NULL ); + InternalizeDesL( iconData, stream ); + + // Closes the stream + CleanupStack::PopAndDestroy( &stream ); + CleanupStack::PopAndDestroy( data ); + + DLTRACEOUT(("")); + return iconData; + }