diff -r 000000000000 -r 7f85d04be362 upnpmediaserver/contentdirectoryservice/src/upnpstatehandler.cpp --- /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& 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 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