adaptationlayer/dataport/dataport_csy/src/dpdatabuffer.cpp
changeset 0 63b37f68c1ce
child 5 8ccc39f9d787
--- /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