--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/adaptationlayer/dataport/dataport_csy/src/dpdatabuffer.cpp Fri Nov 06 17:28:23 2009 +0000
@@ -0,0 +1,332 @@
+/*
+* Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "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:
+*
+*/
+
+
+
+
+// INCLUDE FILES
+#include "dpdef.h" // dataport definitions
+#include "dpdatabuffer.h" // base class for rx and tx buffers
+#include "dpdataelement.h" // data elements
+#include "dpdataclient.h" // data client that access buffer
+#include "dplog.h" // dataport logging
+#include "osttracedefinitions.h"
+#ifdef OST_TRACE_COMPILER_IN_USE
+#include "dpdatabuffertraces.h"
+#endif
+
+// LOCAL FUNCTION PROTOTYPES
+// none
+
+// ==================== LOCAL FUNCTIONS ====================
+// none
+
+// ================= MEMBER FUNCTIONS =======================
+
+// ---------------------------------------------------------
+// CDpDataBuffer::CDpDataBuffer
+// C++ default constructor.
+// ---------------------------------------------------------
+CDpDataBuffer::CDpDataBuffer(
+ const TInt aMaximumReservationSize,
+ const TInt aBufferInitialSize):
+ iRE(*this,CDpDataElement::EDeRead),
+ iWE(*this,CDpDataElement::EDeWrite),
+ iMaxReservationSize( aMaximumReservationSize ),
+ iBufferInitialSize( aBufferInitialSize )
+ {
+ OstTrace0( TRACE_NORMAL, CDPDATABUFFER_CDPDATABUFFER, "CDpDataBuffer::CDpDataBuffer" );
+ LOGM(" CDpDataBuffer::CDpDataBuffer");
+ }
+
+// ---------------------------------------------------------
+// CDpDataBuffer::ConstructL
+// Symbian 2nd phase constructor.
+// ---------------------------------------------------------
+void CDpDataBuffer::ConstructL()
+ {
+ OstTrace0( TRACE_NORMAL, CDPDATABUFFER_CONSTRUCTL, "CDpDataBuffer::ConstructL" );
+ LOGM(" CDpDataBuffer::ConstructL");
+
+ iBufSize = iBufferInitialSize + iMaxReservationSize;
+
+ // obey configuration pbs+ebs in design document
+ iBuf=HBufC8::NewL( iBufSize );
+
+ // length to the max
+ iBuf->Des().SetLength( iBufSize );
+ iBuf->Des().Fill( KDpFillChar );
+
+ iTreshold = iBufferInitialSize;
+ }
+
+// ---------------------------------------------------------
+// CDpDataBuffer::NewL
+// Static constructor.
+// ---------------------------------------------------------
+CDpDataBuffer* CDpDataBuffer::NewL(
+ const TInt aMaximumReservationSize,
+ const TInt aBufferInitialSize)
+ {
+ OstTrace0( TRACE_NORMAL, CDPDATABUFFER_NEWL, "CDpDataBuffer::NewL" );
+ LOGM(" CDpDataBuffer::NewL");
+
+ CDpDataBuffer* self = new (ELeave) CDpDataBuffer(
+ aMaximumReservationSize, aBufferInitialSize );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// ---------------------------------------------------------
+// CDpDataBuffer::~CDpDataBuffer
+// Destructor
+// ---------------------------------------------------------
+CDpDataBuffer::~CDpDataBuffer()
+ {
+ OstTrace0( TRACE_NORMAL, DUP1_CDPDATABUFFER_CDPDATABUFFER, "CDpDataBuffer::~CDpDataBuffer" );
+ LOGM(" CDpDataBuffer::~CDpDataBuffer");
+
+ if ( iBuf )
+ {
+ delete iBuf;
+ }
+
+ iReader = NULL;
+ iWriter = NULL;
+ }
+
+// ---------------------------------------------------------
+// CDpDataBuffer::SetLength
+// This method sets length of buffer. This is called from
+// CDpDataPort::SetReceiveBufferLength() method.
+// ---------------------------------------------------------
+//
+TInt CDpDataBuffer::SetLength(
+ const TInt aLen)
+ {
+ OstTrace0( TRACE_NORMAL, CDPDATABUFFER_SETLENGTH, "CDpDataBuffer::SetLength" );
+ LOGM(" CDpDataBuffer::SetLength");
+
+ //Initialization
+ TInt max( 0 );
+ TInt ret( KErrNone );
+
+ if ( iHead + iWE.iSize > iEnd )
+ {
+ max = iHead + iWE.iSize;
+ }
+ else
+ {
+ max = iEnd;
+ }
+
+ OstTraceExt2( TRACE_NORMAL, DUP1_CDPDATABUFFER_SETLENGTH, "CDpDataBuffer:: iHead: %d, iWE.iSize: %d", iHead, iWE.iSize );
+ OstTraceExt2( TRACE_NORMAL, DUP2_CDPDATABUFFER_SETLENGTH, "CDpDataBuffer:: iEnd : %d, aLen : %d", iEnd, aLen );
+
+ LOG2(" iHead: %d, \t iWE.iSize: %d", iHead, iWE.iSize );
+ LOG2(" iEnd : %d, \t aLen : %d", iEnd, aLen );
+
+ if ( ( max >= ( aLen + iMaxReservationSize ) ) ||
+ ( aLen < 2*iMaxReservationSize ) )
+ {
+ // buffer may be filled further than length
+
+ OstTrace0( TRACE_NORMAL, DUP3_CDPDATABUFFER_SETLENGTH, "CDpDataBuffer:: ERROR, Client tried to reserve too big or too small Receive Buffer Size" );
+ OstTraceExt2( TRACE_NORMAL, DUP4_CDPDATABUFFER_SETLENGTH, "CDpDataBuffer:: aLen: %d, iMaxReservationSize: %d", aLen, iMaxReservationSize );
+ OstTrace1( TRACE_NORMAL, DUP5_CDPDATABUFFER_SETLENGTH, "CDpDataBuffer:: max: %d", max );
+
+ LOG(" ERROR, Client tried to reserve too big or too small Receive Buffer Size");
+ LOG2(" aLen: %d, \t iMaxReservationSize: %d", aLen, iMaxReservationSize );
+ LOG1(" max: %d", max );
+
+ ret = KErrArgument;
+ }
+ else
+ {
+ iBuf->Des().SetLength( max );
+ HBufC8* tmp = NULL;
+
+ // ReAllocL returns address of the expanded or contracted HBufC descriptor.
+ // ReAllocL() leaves, if there is insufficient memory.
+ TRAP(ret, ( tmp = iBuf->ReAllocL( aLen+iMaxReservationSize ) ));
+
+ if ( KErrNone == ret )
+ {
+ iBuf=tmp;
+ iBuf->Des().SetLength( aLen + iMaxReservationSize );
+ iBufSize = aLen + iMaxReservationSize;
+ iTreshold = aLen;
+ }
+ }
+
+ return ret;
+ }
+
+// ---------------------------------------------------------
+// CDpDataBuffer::RegisterDataClient
+// This method registers data client to the buffer.
+// ---------------------------------------------------------
+//
+TInt CDpDataBuffer::RegisterDataClient(
+ MDpDataClient& aClient )
+ {
+ OstTrace0( TRACE_NORMAL, CDPDATABUFFER_REGISTERDATACLIENT, "CDpDataBuffer::RegisterDataClient" );
+ LOGM(" CDpDataBuffer::RegisterDataClient");
+ TInt ret( KErrNone );
+
+ switch ( aClient.Role() )
+ {
+ case EDbReader:
+ {
+ if ( iReader )
+ {
+ LOG(" CDpDataBuffer::RegisterDataClient, iReader already exists");
+ OstTrace0( TRACE_NORMAL, DUP1_CDPDATABUFFER_REGISTERDATACLIENT, "CDpDataBuffer:: iReader already exists" );
+
+ ret = KErrGeneral;
+ }
+ else
+ {
+ iReader = &aClient;
+ }
+ break;
+ }
+ case EDbWriter:
+ {
+ if ( iWriter )
+ {
+ LOG(" CDpDataBuffer::RegisterDataClient, iWriter already exists");
+ OstTrace0( TRACE_NORMAL, DUP2_CDPDATABUFFER_REGISTERDATACLIENT, "CDpDataBuffer:: iWriter already exists" );
+
+ ret = KErrGeneral;
+ }
+ else
+ {
+ iWriter = &aClient;
+ }
+ break;
+ }
+ default:
+ {
+ LOG(" CDpDataBuffer::RegisterDataClient, default, return KErrGeneral");
+ OstTrace0( TRACE_NORMAL, DUP3_CDPDATABUFFER_REGISTERDATACLIENT, "CDpDataBuffer:: default, return KErrGeneral" );
+
+ ret = KErrGeneral;
+ break;
+ }
+ }
+
+ return ret;
+ }
+
+// ---------------------------------------------------------
+// CDpDataBuffer::UsedBytes
+// This method gets the amount of used bytes.
+// Note that when virtual circular buffer has wrapped around
+// there might be iTailWhenWrappedAround > 0 and therefore we
+// have to notice that also in calculation. Normally
+// iTailWhenWrappedAround == 0.
+//
+// In other words: When we have data in ebs (enhanced buffer
+// space) we have to calculate it too. When
+// iTailWhenWrappedAround>0 iTail==0.
+//
+// t h twr
+// | | n |
+// |-------pbs--------|--ebs--|
+//
+// ---------------------------------------------------------
+//
+TInt CDpDataBuffer::UsedBytes()
+ {
+ OstTrace0( TRACE_NORMAL, CDPDATABUFFER_USEDBYTES, "CDpDataBuffer::UsedBytes" );
+ LOGM(" CDpDataBuffer::UsedBytes");
+ TInt ret( 0 );
+
+ if ( iHead != iTail )
+ {
+ if ( iHead > ( iTail + iTailWhenWrappedAround ) )
+ {
+ ret = iHead - iTail;
+ }
+ else
+ {
+ ret = iEnd - iTail - iTailWhenWrappedAround + iHead;
+ }
+ }
+
+ return ret;
+ }
+
+// ---------------------------------------------------------
+// CDpDataBuffer::FreeBytes
+// This method gets the amount of free bytes.
+// ---------------------------------------------------------
+//
+TInt CDpDataBuffer::FreeBytes()
+ {
+ OstTrace0( TRACE_NORMAL, CDPDATABUFFER_FREEBYTES, "CDpDataBuffer::FreeBytes" );
+ LOGM(" CDpDataBuffer::FreeBytes");
+
+ return ( iBufSize - UsedBytes() - iMaxReservationSize );
+ }
+
+// ---------------------------------------------------------
+// CDpDataBuffer::Flush
+// This method empties the buffer and notifies waiting reader
+// and writer about the flush.
+// ---------------------------------------------------------
+//
+void CDpDataBuffer::Flush()
+ {
+ OstTrace0( TRACE_NORMAL, CDPDATABUFFER_FLUSH, "CDpDataBuffer::Flush" );
+ LOGM(" CDpDataBuffer::Flush");
+
+ // throw reader out
+ //signal waiting reader
+ if ( iIsReaderWaiting && iReader )
+ {
+ iReader->FlushNotify();
+ iIsReaderWaiting = EFalse;
+ }
+
+ // throw writer out
+ //signal waiting writer
+ if ( iIsWriterWaiting && iWriter )
+ {
+ iWriter->FlushNotify();
+ iIsWriterWaiting = EFalse;
+ }
+
+ // As (currently) data accesses to buffer are synchronous, there can be no
+ // data client accessing the buffer.
+ iEnd = 0;
+ iHead = 0;
+ iTail = 0;
+ iTailWhenWrappedAround = 0;
+
+ iBuf->Des().Fill( KDpFillChar );
+ }
+
+//=============================================================================
+
+// OTHER EXPORTED FUNCTIONS
+// none
+
+// End of File