diff -r 000000000000 -r 63b37f68c1ce adaptationlayer/dataport/dataport_csy/src/dpdataelement.cpp --- /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( &iDB.iBuf-> + Des()[iDB.iTailWhenWrappedAround] ), + tailsize, + tailsize ); + // Fill released space with FILLCHAR. + taildesc.Fill( KDpFillChar ); + } + //no else + + TPtr8 tmp( + reinterpret_cast( &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( &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( &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( + &iDB.iBuf->Des()[iDB.iTail] ), + tailSize, + tailSize ); + } + //no else + + // set tail + aTail.Set( + reinterpret_cast( &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( &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( + &iDB.iBuf->Des()[iDB.iHead] ), 0, iSize ); + } + + return ret; + } + +// ========================== OTHER EXPORTED FUNCTIONS ========================= + +// none + + +// End of File