--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/convergedcallengine/spsettings/src/spsbufferedpublisher.cpp Tue Feb 02 01:11:09 2010 +0200
@@ -0,0 +1,241 @@
+/*
+* Copyright (c) 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: Logic for bufferred publish and subcribe notifier
+*
+*/
+
+#include <e32property.h>
+#include "spdefaultvalues.h"
+
+#include "spsbufferedpublisher.h"
+
+const TUint32 KRealGlobalIndex = 0;
+_LIT( KSemaphore, "CSpsBufferedPublisher" );
+
+// ======== LOCAL FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// ?description
+// ---------------------------------------------------------------------------
+//
+CSpsBufferedPublisher* CSpsBufferedPublisher::NewL( TUid aCategory, TUint aKey )
+ {
+ CSpsBufferedPublisher* self = new (ELeave) CSpsBufferedPublisher( aCategory, aKey );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+// ?description
+// ---------------------------------------------------------------------------
+//
+CSpsBufferedPublisher::CSpsBufferedPublisher( TUid aCategory, TUint aKey ):
+ iCategory( aCategory ),
+ iKey( aKey ),
+ iIndex( KErrNotReady )
+ {
+
+ }
+
+// ---------------------------------------------------------------------------
+// ?description
+// ---------------------------------------------------------------------------
+//
+CSpsBufferedPublisher::~CSpsBufferedPublisher()
+ {
+
+ }
+
+// ---------------------------------------------------------------------------
+// ?description
+// ---------------------------------------------------------------------------
+//
+void CSpsBufferedPublisher::ConstructL()
+ {
+ static _LIT_SECURITY_POLICY_PASS( KAllowAllPolicy );
+
+ TInt err = RProperty::Define(
+ iCategory, iKey,
+ RProperty::EByteArray,
+ KAllowAllPolicy, KAllowAllPolicy,
+ RProperty::KMaxPropertySize );
+
+ if( !err )
+ {
+ TBuf8<RProperty::KMaxPropertySize> data;
+ data.FillZ( data.MaxLength() );
+ User::LeaveIfError( RProperty::Set( iCategory, iKey, data ) );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// ?description
+// ---------------------------------------------------------------------------
+//
+void CSpsBufferedPublisher::SetL( TUid aCategory, TUint aKey, TUint32 aData )
+ {
+ RSemaphore wait;
+ TInt err = wait.OpenGlobal( KSemaphore );
+
+ if ( err )
+ {
+ User::LeaveIfError( wait.CreateGlobal( KSemaphore, 1 ) );
+ }
+
+ wait.Wait();
+ TCleanupItem cleanup( CSpsBufferedPublisher::SignalAndCloseSemaphore, &wait );
+ CleanupStack::PushL( cleanup );
+
+ TBuf8<RProperty::KMaxPropertySize> data;
+ User::LeaveIfError(
+ RProperty::Get( aCategory, aKey, data ) );
+
+ // Increment index
+ GlobalIndex( data )++;
+
+ if( Base( data, GlobalIndex( data ) ) == GlobalIndex( data ) )
+ {
+ // Skip index if real index is same as KRealGlobalIndex
+ GlobalIndex( data )++;
+ }
+
+ // Write data to index
+ At( data, GlobalIndex( data ) ) = aData;
+
+ User::LeaveIfError(
+ RProperty::Set( aCategory, aKey, data ) );
+
+ CleanupStack::PopAndDestroy(); // wait
+ }
+
+// ---------------------------------------------------------------------------
+// ?description
+// ---------------------------------------------------------------------------
+//
+void CSpsBufferedPublisher::GetL( RArray<TUint32>& aData )
+ {
+ User::LeaveIfError( iIndex );
+
+ TBuf8<RProperty::KMaxPropertySize> data;
+ User::LeaveIfError(
+ RProperty::Get( iCategory, iKey, data ) );
+
+ const TUint32 lastModified = GlobalIndex( data );
+ const TUint32 indexDifference = lastModified - iIndex;
+ if( Max( data ) < indexDifference )
+ {
+ // If some of data is missed
+ iIndex = lastModified - Max( data );
+ }
+
+ // Start reading
+ while( lastModified != iIndex )
+ {
+ iIndex++;
+
+ if( Base( data, iIndex ) == iIndex )
+ {
+ // Skip index if real index is same as KRealGlobalIndex
+ iIndex++;
+ }
+
+ aData.Append( At(data, iIndex) );
+ }
+
+ }
+
+// ---------------------------------------------------------------------------
+// ?description
+// ---------------------------------------------------------------------------
+//
+void CSpsBufferedPublisher::Start()
+ {
+ if( KErrNone > iIndex )
+ {
+ TBuf8<RProperty::KMaxPropertySize> data;
+ RProperty::Get( iCategory, iKey, data );
+ if( data.Length() )
+ {
+ // When no error occurs
+ iIndex = GlobalIndex( data );
+ }
+ else
+ {
+ iIndex = 0;
+ }
+ }
+
+ }
+
+// ---------------------------------------------------------------------------
+// ?description
+// ---------------------------------------------------------------------------
+//
+void CSpsBufferedPublisher::Stop()
+ {
+ iIndex = KErrNotReady;
+ }
+
+// ---------------------------------------------------------------------------
+// ?description
+// ---------------------------------------------------------------------------
+//
+void CSpsBufferedPublisher::SignalAndCloseSemaphore( TAny* aPtr )
+ {
+ RSemaphore* wait = (RSemaphore*)aPtr;
+ wait->Signal();
+ wait->Close();
+ }
+
+// ---------------------------------------------------------------------------
+// ?description
+// ---------------------------------------------------------------------------
+//
+TUint32& CSpsBufferedPublisher::At( TDes8& aData, TInt aIndex )
+ {
+ const TUint32 baseIndex = Base( aData, aIndex );
+ TUint32 realIndex = aIndex - baseIndex;
+ ASSERT( KRealGlobalIndex != realIndex ); // Check if global index is not used
+ return (TUint32&)aData[ realIndex * sizeof(TUint32) ];
+ }
+
+// ---------------------------------------------------------------------------
+// ?description
+// ---------------------------------------------------------------------------
+//
+TUint CSpsBufferedPublisher::Max( TDesC8& aData )
+ {
+ return ( aData.Length() / sizeof(TUint32) );
+ }
+
+// ---------------------------------------------------------------------------
+// ?description
+// ---------------------------------------------------------------------------
+//
+TInt32 CSpsBufferedPublisher::Base( TDesC8& aData, TInt aIndex )
+ {
+ const TInt max = Max( aData );
+ return ( max * (TUint32)( aIndex / max ) );
+ }
+
+// ---------------------------------------------------------------------------
+// ?description
+// ---------------------------------------------------------------------------
+//
+TUint32& CSpsBufferedPublisher::GlobalIndex( TDes8& aData )
+ {
+ return (TUint32&)aData[ KRealGlobalIndex ];
+ }