--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/upnpmediaserver/contentdirectoryservice/src/upnpstatehandler.cpp Thu Dec 17 08:52:00 2009 +0200
@@ -0,0 +1,305 @@
+/** @file
+* Copyright (c) 2005-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: State handler
+*
+*/
+
+
+// INCLUDES
+#include "upnpstatehandler.h"
+#include "upnpstring.h"
+#include "upnpcontainerupdateid.h"
+#include "upnpcontentdirectory.h"
+#include "upnpcontentdirectoryglobals.h"
+#include "upnpcommonupnplits.h"
+
+
+// -----------------------------------------------------------------------------
+// CUpnpStateHandler::CUpnpStateHandler
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CUpnpStateHandler::CUpnpStateHandler( )
+{
+ iContainerUpdateIdsEvented = EFalse;
+}
+
+
+// -----------------------------------------------------------------------------
+// CUpnpStateHandler::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CUpnpStateHandler::ConstructL( CUpnpContentDirectory* aCd )
+{
+ iContainerUpdateIds.Reset();
+ iCurrentContainerUpdateIds.Reset();
+ iCd=aCd;
+}
+
+// -----------------------------------------------------------------------------
+// CUpnpStateHandler::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CUpnpStateHandler* CUpnpStateHandler::NewL( CUpnpContentDirectory* aCd )
+{
+ CUpnpStateHandler* self = new (ELeave) CUpnpStateHandler( );
+
+ CleanupStack::PushL( self );
+ self->ConstructL( aCd );
+ CleanupStack::Pop( self );
+ return self;
+}
+
+// -----------------------------------------------------------------------------
+// CUpnpStateHandler::~CUpnpStateHandler
+// Destructor
+// -----------------------------------------------------------------------------
+//
+CUpnpStateHandler::~CUpnpStateHandler()
+{
+ // clear tables related to ContainerUpdateIds state variable
+ for( TInt i( 0 ); i < iContainerUpdateIds.Count(); i++ )
+ {
+ delete iContainerUpdateIds[i].iContainerId;
+ }
+ iContainerUpdateIds.Close();
+ //--------------------------
+ for( TInt i( 0 ); i < iCurrentContainerUpdateIds.Count(); i++ )
+ {
+ delete iCurrentContainerUpdateIds[i].iContainerId;
+ }
+ iCurrentContainerUpdateIds.Close();
+ //--------------------------
+}
+
+// -----------------------------------------------------------------------------
+// CUpnpStateHandler::ContainerUpdateIds
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+TInt CUpnpStateHandler::ContainerUpdateId( const TDesC8& aContainerID )
+{
+ if( aContainerID.Compare( KZero ) == 0 )
+ {
+ return iSystemUpdateId;
+ }
+
+ for(TInt i( 0 ); i < iContainerUpdateIds.Count(); i++ )
+ {
+ if( aContainerID.Compare(*(iContainerUpdateIds[i].iContainerId))==0)
+ {
+ return iContainerUpdateIds[i].iUpdateId;
+ }
+ }
+ return 0; //container not found so it is unmodified and updateId is zero.
+}
+
+// -----------------------------------------------------------------------------
+// CUpnpStateHandler::ContainerUpdateIds
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+RArray<TUpnpContainerUpdateId>& CUpnpStateHandler::ContainerUpdateIds( )
+{
+ return iContainerUpdateIds;
+}
+// -----------------------------------------------------------------------------
+// CUpnpStateHandler::IsEnableL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TBool CUpnpStateHandler::IsEnable()
+{
+ if (iCd->SubcribersAmount() > 0) return ETrue;
+ else return EFalse;
+}
+
+// -----------------------------------------------------------------------------
+// CUpnpStateHandler::IncreaseSystemUpdateIdL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CUpnpStateHandler::IncreaseSystemUpdateIdL()
+{
+ if( iSystemUpdateId < KMaxTUint )
+ {
+ iSystemUpdateId++;
+ }
+ else
+ {
+ iSystemUpdateId = 1;
+ }
+ TBuf8<UpnpString::KMaxIntLength> suid;
+ suid.Num( iSystemUpdateId );
+ iCd->SetStateVariableL( KSystemUpdateID, suid );
+ return iSystemUpdateId;
+}
+// -----------------------------------------------------------------------------
+// CUpnpStateHandler::IncreaseContainerUpdateIdL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CUpnpStateHandler::IncreaseContainerUpdateIdL( const TDesC8& aContainerID )
+{
+ // DLNA.ORG_AnyContainer support - 'any container'
+ //mapped into container with id=1
+ HBufC8* properContainerID;
+
+ if( !aContainerID.Compare(KAnyContainerIndicator8) )
+ properContainerID = KOne().AllocLC();
+ else
+ properContainerID = aContainerID.AllocLC();
+
+ // iContainerUpdateIds table serving ---------------
+ TInt updateId( KErrNotFound );
+ TInt i( 0 );
+ for( ; i < iContainerUpdateIds.Count(); i++ )
+ {
+ if( properContainerID->Des().Compare(
+ *(iContainerUpdateIds[i].iContainerId) ) == 0 )
+ {
+ updateId = iContainerUpdateIds[i].iUpdateId;
+ break;
+ }
+ }
+
+ if( KErrNotFound == updateId ) //first touch to this conītainer
+ {
+ TUpnpContainerUpdateId cui;
+
+ cui.iContainerId = properContainerID->AllocL();
+ //First time of modification, thus ID is 1.
+ // No magic (white nor black) used here.
+ cui.iUpdateId = 1;
+ iContainerUpdateIds.Append( cui );
+ updateId = cui.iUpdateId;
+ }
+ else
+ {
+ if( iContainerUpdateIds[i].iUpdateId == KMaxTInt )
+ {
+ iContainerUpdateIds[i].iUpdateId = 1;
+ }
+ else
+ {
+ iContainerUpdateIds[i].iUpdateId++;
+ }
+ updateId = iContainerUpdateIds[i].iUpdateId;
+ }
+
+ // iCurrentContainerUpdateIds table serving ---------------
+ if (IsEnable()) //if any CP subscribed
+ {
+ if(iContainerUpdateIdsEvented)
+ {
+ // clearing iCurrentContainerUpdateIds table after:
+ // 1. sending NOTIFY events, and
+ // 2. 'ContainerUpdateIds' state variable change
+ for( TInt i(0); i < iCurrentContainerUpdateIds.Count(); i++ )
+ {
+ delete iCurrentContainerUpdateIds[i].iContainerId;
+ }
+ iCurrentContainerUpdateIds.Reset();
+
+ iContainerUpdateIdsEvented = EFalse;
+ }
+
+ // finding out whether element should be updated or added
+ TBool isEelementFound = EFalse;
+ TInt j( 0 );
+
+ for( ; j < iCurrentContainerUpdateIds.Count(); j++ )
+ {
+ if( properContainerID->Des().Compare(
+ *(iCurrentContainerUpdateIds[j].iContainerId) ) == 0 )
+ {
+ isEelementFound = ETrue;
+ break;
+ }
+ }
+
+ if(isEelementFound)
+ {
+ iCurrentContainerUpdateIds[j].iUpdateId = updateId;
+ }
+ else
+ {
+ TUpnpContainerUpdateId newEl;
+
+ newEl.iContainerId = properContainerID->AllocL();
+ newEl.iUpdateId = updateId;
+
+ iCurrentContainerUpdateIds.Append(newEl);
+ }
+
+ // preparing new value of 'ContainerUpdateIds' state variable ----
+
+ TInt elCount = iCurrentContainerUpdateIds.Count();
+ TInt totalDescLength = 0;
+
+ for( TInt k = 0; k < elCount; k++ )
+ {
+ totalDescLength = totalDescLength +
+ (iCurrentContainerUpdateIds[k].iContainerId)->Des().Length();
+ }
+
+ totalDescLength = totalDescLength + elCount*(UpnpString::KMaxIntLength)
+ + elCount - 1;// 'elCount-1'-> quantity of commas in the descriptor
+
+ HBufC8* variableValue = HBufC8::NewLC(totalDescLength);
+ TPtr8 pVar = variableValue->Des();
+ pVar.Zero();
+
+ for( TInt k = 0; k < elCount; k++ )
+ {
+ pVar.Append( *(iCurrentContainerUpdateIds[k].iContainerId) );
+ pVar.Append(',');
+ if ((iCurrentContainerUpdateIds[k].iContainerId)->Compare(KZero) == 0)
+ pVar.AppendNum( iSystemUpdateId );
+ else
+ pVar.AppendNum( iCurrentContainerUpdateIds[k].iUpdateId );
+
+ if( k != elCount - 1 ) // last comma not appended
+ pVar.Append(',');
+ }
+
+ //Set new value to be evented
+ iCd->SetStateVariableL( KContainerUpdateIDs, *variableValue );
+
+ CleanupStack::PopAndDestroy( variableValue );
+ }
+ CleanupStack::PopAndDestroy( properContainerID );
+
+ }
+
+// -----------------------------------------------------------------------------
+// CUpnpStateHandler::StateVariableEvented
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CUpnpStateHandler::StateVariableEvented(const TDesC8& aVariableName)
+{
+ /* if( aVariableName.Compare(KContainerUpdateIDs) == 0
+ && (iCd->SubcribersAmount() > 0 )) */
+ if( aVariableName.Compare(KContainerUpdateIDs) == 0)
+ {
+ iContainerUpdateIdsEvented = ETrue;
+ return;
+ }
+}
+
+//end of file