--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/adaptationlayer/dataport/dataport_csy/src/dpdataelement.cpp Fri Nov 06 17:28:23 2009 +0000
@@ -0,0 +1,428 @@
+/*
+* 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 "dpdataelement.h" // data element
+#include "dpdatabuffer.h" // base class for rx and tx buffers
+#include "dpdataclient.h" // data client that access buffer
+#include "dpdef.h" // dataport definitions
+#include "dplog.h" // dataport logging
+#include "osttracedefinitions.h"
+#ifdef OST_TRACE_COMPILER_IN_USE
+#include "dpdataelementtraces.h"
+#endif
+
+// EXTERNAL DATA STRUCTURES
+// none
+
+// EXTERNAL FUNCTION PROTOTYPES
+// none
+
+// CONSTANTS
+// none
+
+// MACROS
+// none
+
+// LOCAL CONSTANTS AND MACROS
+// none
+
+// MODULE DATA STRUCTURES
+// none
+
+// LOCAL FUNCTION PROTOTYPES
+// none
+
+// FORWARD DECLARATIONS
+// none
+
+// ============================= LOCAL FUNCTIONS ===============================
+
+// none
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CDpDataElement::CDpDataElement
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CDpDataElement::CDpDataElement(
+ CDpDataBuffer& aDataBuffer,
+ TDataElementType aType ) :
+ iDB( aDataBuffer ),
+ iType( aType ),
+ iSize( 0 ),
+ iState( EDeFree )
+ {
+ OstTrace0( TRACE_NORMAL, CDPDATAELEMENT_CDPDATAELEMENT, "CDpDataElement::CDpDataElement" );
+ LOGM("CDpDataElement::CDpDataElement");
+ }
+
+// -----------------------------------------------------------------------------
+// CDpDataElement::~CDpDataElement
+// Destructor
+// -----------------------------------------------------------------------------
+//
+CDpDataElement::~CDpDataElement()
+ {
+ OstTrace0( TRACE_NORMAL, DUP1_CDPDATAELEMENT_CDPDATAELEMENT, "CDpDataElement::~CDpDataElement" );
+ LOGM("CDpDataElement::~CDpDataElement");
+ }
+
+// -----------------------------------------------------------------------------
+// CDpDataElement::Reserve
+// This method reserves an data element of requested length
+// from the buffer. aTail is not used when reserving write
+// element, it is used only in read operations.
+// -----------------------------------------------------------------------------
+//
+TInt CDpDataElement::Reserve(
+ const TInt aSize,
+ TPtr8& aDes,
+ TPtr8& aTail,
+ TBool aOverrideMRS )
+ {
+ OstTrace0( TRACE_NORMAL, CDPDATAELEMENT_RESERVE, "CDpDataElement::Reserve" );
+ LOGM("CDpDataElement::Reserve");
+
+ TInt ret( KErrNone );
+
+ // Wrong size
+ if ( ( !aOverrideMRS ) && ( aSize > iDB.iMaxReservationSize || 0 >= aSize ) )
+ {
+ ret = KErrArgument;
+ }
+ else if ( aOverrideMRS && ( aSize > iDB.Size() || 0 >= aSize ) )
+ {
+ ret = KErrArgument;
+ }
+ // Already reserved
+ else if ( EDeFree != iState )
+ {
+ // This can happen e.g. when client makes a null read.
+ LOG(" CDpDataElement::Reserve - FAILED");
+ OstTrace0( TRACE_NORMAL, DUP1_CDPDATAELEMENT_RESERVE, "CDpDataElement:: Reserve - FAILED" );
+
+ ret = KErrGeneral;
+ }
+ else
+ {
+ switch ( iType )
+ {
+ case EDeRead:
+ {
+ ret = HandleReadTypeReserve( aSize, aDes, aTail );
+ break;
+ }
+ case EDeWrite:
+ {
+ ret = HandleWriteTypeReserve( aSize, aDes );
+ break;
+ }
+ default:
+ {
+ // This should never happen.
+ ret = KErrGeneral;
+ }
+ }
+ }
+
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// CDpDataElement::Release
+// This method releases the data element. When a reserved data
+// element has been used it has to be released before it can be
+// reserved again. If x bytes has been reserved but only y has
+// been used, y has to be given in parameter (0 <= y <= x).
+// -----------------------------------------------------------------------------
+//
+TInt CDpDataElement::Release(
+ const TInt aUsedLength )
+ {
+ OstTrace0( TRACE_NORMAL, CDPDATAELEMENT_RELEASE, "CDpDataElement::Release" );
+ LOGM("CDpDataElement::Release");
+
+ TInt ret( KErrNone );
+
+ // Already reserved
+ if ( EDeReserved != iState )
+ {
+ LOG(" DP:DataElement::Release - FAIL, not reserved");
+ OstTrace0( TRACE_NORMAL, DUP1_CDPDATAELEMENT_RELEASE, "CDpDataElement:: Release - FAIL, not reserved" );
+
+ ret = KErrGeneral;
+ }
+ // Wrong length
+ else if ( aUsedLength > iSize || 0 > aUsedLength )
+ {
+ LOG(" DP:DataElement::Release - FAIL, wrong length");
+ OstTrace0( TRACE_NORMAL, DUP2_CDPDATAELEMENT_RELEASE, "CDpDataElement:: Release - FAIL, wrong length" );
+
+ ret = KErrGeneral;
+ }
+ else
+ {
+ switch ( iType )
+ {
+ case CDpDataElement::EDeRead:
+ {
+ if ( 0 != iDB.iTailWhenWrappedAround )
+ {
+ LOG(" DP:DataElement::Release - iTailWhenWrappedAround != 0 ");
+ OstTrace0( TRACE_NORMAL, DUP3_CDPDATAELEMENT_RELEASE, "CDpDataElement:: Release - iTailWhenWrappedAround != 0 " );
+
+ TInt tailsize( iDB.iEnd - iDB.iTailWhenWrappedAround );
+
+ if ( tailsize <= aUsedLength )
+ {
+ if ( 0 < tailsize )
+ {
+ TPtr8 taildesc(
+ reinterpret_cast<unsigned char*>( &iDB.iBuf->
+ Des()[iDB.iTailWhenWrappedAround] ),
+ tailsize,
+ tailsize );
+ // Fill released space with FILLCHAR.
+ taildesc.Fill( KDpFillChar );
+ }
+ //no else
+
+ TPtr8 tmp(
+ reinterpret_cast<unsigned char*>( &iDB.iBuf->
+ Des()[iDB.iTail] ),
+ ( aUsedLength - tailsize ),
+ ( aUsedLength - tailsize ) );
+ // Fill released space with FILLCHAR.
+ tmp.Fill( KDpFillChar );
+ iDB.iTailWhenWrappedAround = 0;
+ iDB.iTail += ( aUsedLength - tailsize );
+ iDB.iEnd = iDB.iHead;
+ }
+ else
+ {
+ // tailsize>aUsedLength
+ TPtr8 taildesc(
+ reinterpret_cast<unsigned char*>( &iDB.iBuf->
+ Des()[iDB.iTailWhenWrappedAround] ),
+ aUsedLength,
+ aUsedLength );
+ // Fill released space with FILLCHAR.
+ taildesc.Fill( KDpFillChar );
+ iDB.iTail += iDB.iTailWhenWrappedAround + aUsedLength;
+ iDB.iTailWhenWrappedAround = 0;
+ }
+ }
+ else
+ {
+ TInt index( iDB.iTail );
+ iDB.iTail += aUsedLength;
+ TInt freeSize( aUsedLength );
+
+ TPtr8 tmp(
+ reinterpret_cast<unsigned char*>( &iDB.iBuf->
+ Des()[index] ),
+ freeSize,
+ freeSize );
+ // Fill released space with FILLCHAR.
+ tmp.Fill( KDpFillChar );
+ }
+
+ iState = EDeFree;
+ if ( iDB.iIsWriterWaiting && iDB.iWE.iSize <= iDB.FreeBytes() )
+ {
+ iDB.iIsWriterWaiting = EFalse;
+ // Signal waiting writer.
+ iDB.iWriter->ReleaseNotify();
+ }
+ //no else
+ break;
+ }
+ case CDpDataElement::EDeWrite:
+ {
+ iDB.iHead += aUsedLength;
+
+ if ( iDB.iEnd < iDB.iHead )
+ {
+ iDB.iEnd = iDB.iHead;
+ }
+ //no else
+ iState = EDeFree;
+ if ( iDB.iIsReaderWaiting &&
+ iDB.iReader &&
+ iDB.iRE.iSize <= iDB.UsedBytes() )
+ {
+ iDB.iIsReaderWaiting = EFalse;
+ // Signal waiting reader.
+ iDB.iReader->ReleaseNotify();
+ }
+ //no else
+ }
+ break;
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// CDpDataElement::HandleReadTypeReserve
+// This method handles reserve operation for read type element.
+// -----------------------------------------------------------------------------
+//
+TInt CDpDataElement::HandleReadTypeReserve(
+ const TInt aSize,
+ TPtr8 &aDes,
+ TPtr8 &aTail )
+ {
+ OstTrace0( TRACE_NORMAL, CDPDATAELEMENT_HANDLEREADTYPERESERVE, "CDpDataElement::HandleReadTypeReserve" );
+ LOGM("CDpDataElement::HandleReadTypeReserve");
+
+ TInt ret( KErrNone );
+ iSize = aSize;
+
+ // is there enough data
+ if ( aSize > iDB.UsedBytes() )
+ {
+ // can't have both waiting
+ if ( iDB.iIsWriterWaiting && iDB.iIsReaderWaiting)
+ {
+ LOG(" DP:CDpDataElement::Reserve - Fail:both waiting");
+ OstTrace0( TRACE_NORMAL, DUP1_CDPDATAELEMENT_HANDLEREADTYPERESERVE, "CDpDataElement:: - Fail: both waiting" );
+
+ ret = KErrGeneral;
+ }
+ else
+ {
+ iDB.iIsReaderWaiting = ETrue;
+ // have to wait
+ ret = KErrNotReady;
+ }
+ }
+ else
+ {
+ iState = EDeReserved;
+ if ( ( iDB.iTail + aSize ) > iDB.iEnd )
+ {
+ // set des
+ TInt tailSize( iDB.iEnd-iDB.iTail );
+
+ if ( tailSize > 0 )
+ {
+ aDes.Set(
+ reinterpret_cast<unsigned char*>(
+ &iDB.iBuf->Des()[iDB.iTail] ),
+ tailSize,
+ tailSize );
+ }
+ //no else
+
+ // set tail
+ aTail.Set(
+ reinterpret_cast<unsigned char*>( &iDB.iBuf->Des()[0] ),
+ ( aSize - tailSize ),
+ ( aSize - tailSize ) );
+ iDB.iTailWhenWrappedAround = iDB.iTail;
+ iDB.iTail = 0;
+ }
+ else
+ {
+ // in one piece, set des
+ aDes.Set(
+ reinterpret_cast<unsigned char*>( &iDB.iBuf->
+ Des()[iDB.iTail] ),
+ iSize,
+ iSize );
+ }
+ }
+
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// CDpDataElement::HandleWriteTypeReserve
+// This method handles reserve operation for write type element.
+// -----------------------------------------------------------------------------
+//
+TInt CDpDataElement::HandleWriteTypeReserve(
+ const TInt aSize,
+ TPtr8 &aDes )
+ {
+ OstTrace0( TRACE_NORMAL, CDPDATAELEMENT_HANDLEWRITETYPERESERVE, "CDpDataElement::HandleWriteTypeReserve" );
+ LOGM("CDpDataElement::HandleWriteTypeReserve");
+
+ TInt ret( KErrNone );
+ iSize = aSize;
+
+ if ( iDB.iHead > iDB.iTreshold )
+ {
+ iDB.iHead = 0;
+ }
+ // no else
+
+ // There is not enough free space
+ if ( aSize > iDB.FreeBytes() )
+ {
+ OstTrace1( TRACE_NORMAL, DUP1_CDPDATAELEMENT_HANDLEWRITETYPERESERVE, "CDpDataElement:: aSize: %d", aSize );
+ OstTrace1( TRACE_NORMAL, DUP2_CDPDATAELEMENT_HANDLEWRITETYPERESERVE, "CDpDataElement:: iDB.FreeBytes: %d", iDB.FreeBytes() );
+
+ LOG1(" CDpDataElement::HandleWriteTypeReserve, aSize = %d",
+ aSize );
+ LOG1(" CDpDataElement::HandleWriteTypeReserve, iDB.FreeBytes = %d",
+ iDB.FreeBytes() );
+
+ // Cannot have both waiting.
+ if ( iDB.iIsReaderWaiting )
+ {
+ LOG(" ERROR, CDpDataElement::HandleWriteTypeReserve, Both waiting");
+ OstTrace0( TRACE_NORMAL, DUP3_CDPDATAELEMENT_HANDLEWRITETYPERESERVE, "ERROR, CDpDataElement::HandleWriteTypeReserve, Both waiting" );
+
+ ret = KErrGeneral;
+ }
+ else
+ {
+ iDB.iIsWriterWaiting = ETrue;
+ // Have to wait.
+ ret = KErrNotReady;
+ }
+ }
+ else
+ {
+ iState = EDeReserved;
+ // In one piece, set des
+ aDes.Set( reinterpret_cast<unsigned char*>(
+ &iDB.iBuf->Des()[iDB.iHead] ), 0, iSize );
+ }
+
+ return ret;
+ }
+
+// ========================== OTHER EXPORTED FUNCTIONS =========================
+
+// none
+
+
+// End of File