upnpmediaserver/contentdirectoryservice/src/upnpstatehandler.cpp
changeset 0 7f85d04be362
--- /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