adaptationlayer/dataport/dataport_csy/src/dpdatabuffer.cpp
changeset 0 63b37f68c1ce
child 5 8ccc39f9d787
equal deleted inserted replaced
-1:000000000000 0:63b37f68c1ce
       
     1 /*
       
     2 * Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 // INCLUDE FILES
       
    22 #include    "dpdef.h"                   // dataport definitions
       
    23 #include    "dpdatabuffer.h"            // base class for rx and tx buffers
       
    24 #include    "dpdataelement.h"           // data elements
       
    25 #include    "dpdataclient.h"            // data client that access buffer
       
    26 #include    "dplog.h"                   // dataport logging
       
    27 #include "osttracedefinitions.h"
       
    28 #ifdef OST_TRACE_COMPILER_IN_USE
       
    29 #include "dpdatabuffertraces.h"
       
    30 #endif
       
    31 
       
    32 // LOCAL FUNCTION PROTOTYPES
       
    33 // none
       
    34 
       
    35 // ==================== LOCAL FUNCTIONS ====================
       
    36 // none
       
    37 
       
    38 // ================= MEMBER FUNCTIONS =======================
       
    39 
       
    40 // ---------------------------------------------------------
       
    41 // CDpDataBuffer::CDpDataBuffer
       
    42 // C++ default constructor.
       
    43 // ---------------------------------------------------------
       
    44 CDpDataBuffer::CDpDataBuffer(
       
    45     const TInt aMaximumReservationSize,
       
    46     const TInt aBufferInitialSize):
       
    47     iRE(*this,CDpDataElement::EDeRead),
       
    48     iWE(*this,CDpDataElement::EDeWrite),
       
    49     iMaxReservationSize( aMaximumReservationSize ),
       
    50     iBufferInitialSize( aBufferInitialSize )
       
    51     {
       
    52     OstTrace0( TRACE_NORMAL, CDPDATABUFFER_CDPDATABUFFER, "CDpDataBuffer::CDpDataBuffer" );
       
    53     LOGM(" CDpDataBuffer::CDpDataBuffer");
       
    54     }
       
    55 
       
    56 // ---------------------------------------------------------
       
    57 // CDpDataBuffer::ConstructL
       
    58 // Symbian 2nd phase constructor.
       
    59 // ---------------------------------------------------------
       
    60 void CDpDataBuffer::ConstructL()
       
    61     {
       
    62     OstTrace0( TRACE_NORMAL, CDPDATABUFFER_CONSTRUCTL, "CDpDataBuffer::ConstructL" );
       
    63     LOGM(" CDpDataBuffer::ConstructL");
       
    64 
       
    65     iBufSize = iBufferInitialSize + iMaxReservationSize;
       
    66 
       
    67     // obey configuration pbs+ebs in design document
       
    68     iBuf=HBufC8::NewL( iBufSize );
       
    69 
       
    70     // length to the max
       
    71     iBuf->Des().SetLength( iBufSize );
       
    72     iBuf->Des().Fill( KDpFillChar );
       
    73 
       
    74     iTreshold = iBufferInitialSize;
       
    75     }
       
    76 
       
    77 // ---------------------------------------------------------
       
    78 // CDpDataBuffer::NewL
       
    79 // Static constructor.
       
    80 // ---------------------------------------------------------
       
    81 CDpDataBuffer* CDpDataBuffer::NewL(
       
    82     const TInt aMaximumReservationSize,
       
    83     const TInt aBufferInitialSize)
       
    84     {
       
    85     OstTrace0( TRACE_NORMAL, CDPDATABUFFER_NEWL, "CDpDataBuffer::NewL" );
       
    86     LOGM(" CDpDataBuffer::NewL");
       
    87 
       
    88     CDpDataBuffer* self = new (ELeave) CDpDataBuffer(
       
    89          aMaximumReservationSize, aBufferInitialSize );
       
    90     CleanupStack::PushL( self );
       
    91     self->ConstructL();
       
    92     CleanupStack::Pop( self );
       
    93     return self;
       
    94     }
       
    95 
       
    96 // ---------------------------------------------------------
       
    97 // CDpDataBuffer::~CDpDataBuffer
       
    98 // Destructor
       
    99 // ---------------------------------------------------------
       
   100 CDpDataBuffer::~CDpDataBuffer()
       
   101     {
       
   102     OstTrace0( TRACE_NORMAL, DUP1_CDPDATABUFFER_CDPDATABUFFER, "CDpDataBuffer::~CDpDataBuffer" );
       
   103     LOGM(" CDpDataBuffer::~CDpDataBuffer");
       
   104 
       
   105     if ( iBuf )
       
   106         {
       
   107         delete iBuf;
       
   108         }
       
   109 
       
   110     iReader = NULL;
       
   111     iWriter = NULL;
       
   112     }
       
   113 
       
   114 // ---------------------------------------------------------
       
   115 // CDpDataBuffer::SetLength
       
   116 // This method sets length of buffer. This is called from
       
   117 // CDpDataPort::SetReceiveBufferLength() method.
       
   118 // ---------------------------------------------------------
       
   119 //
       
   120 TInt CDpDataBuffer::SetLength(
       
   121     const TInt aLen)
       
   122     {
       
   123     OstTrace0( TRACE_NORMAL, CDPDATABUFFER_SETLENGTH, "CDpDataBuffer::SetLength" );
       
   124     LOGM(" CDpDataBuffer::SetLength");
       
   125 
       
   126     //Initialization
       
   127     TInt max( 0 );
       
   128     TInt ret( KErrNone );
       
   129 
       
   130     if ( iHead + iWE.iSize > iEnd )
       
   131         {
       
   132         max = iHead + iWE.iSize;
       
   133         }
       
   134     else
       
   135         {
       
   136         max = iEnd;
       
   137         }
       
   138 
       
   139         OstTraceExt2( TRACE_NORMAL, DUP1_CDPDATABUFFER_SETLENGTH, "CDpDataBuffer:: iHead: %d, iWE.iSize: %d", iHead, iWE.iSize );
       
   140         OstTraceExt2( TRACE_NORMAL, DUP2_CDPDATABUFFER_SETLENGTH, "CDpDataBuffer:: iEnd : %d, aLen     : %d", iEnd, aLen );
       
   141 
       
   142         LOG2("  iHead: %d, \t iWE.iSize: %d", iHead, iWE.iSize );
       
   143         LOG2("  iEnd : %d, \t aLen     : %d", iEnd, aLen );
       
   144 
       
   145     if ( ( max >= ( aLen + iMaxReservationSize ) ) ||
       
   146             ( aLen < 2*iMaxReservationSize ) )
       
   147         {
       
   148         // buffer may be filled further than length
       
   149 
       
   150         OstTrace0( TRACE_NORMAL, DUP3_CDPDATABUFFER_SETLENGTH, "CDpDataBuffer:: ERROR, Client tried to reserve too big or too small Receive Buffer Size" );
       
   151         OstTraceExt2( TRACE_NORMAL, DUP4_CDPDATABUFFER_SETLENGTH, "CDpDataBuffer:: aLen: %d, iMaxReservationSize: %d", aLen, iMaxReservationSize );
       
   152         OstTrace1( TRACE_NORMAL, DUP5_CDPDATABUFFER_SETLENGTH, "CDpDataBuffer:: max: %d", max );
       
   153 
       
   154         LOG("  ERROR, Client tried to reserve too big or too small Receive Buffer Size");
       
   155         LOG2("  aLen: %d, \t iMaxReservationSize: %d", aLen, iMaxReservationSize );
       
   156         LOG1("  max: %d", max );
       
   157 
       
   158         ret = KErrArgument;
       
   159         }
       
   160     else
       
   161         {
       
   162         iBuf->Des().SetLength( max );
       
   163         HBufC8* tmp = NULL;
       
   164 
       
   165         // ReAllocL returns address of the expanded or contracted HBufC descriptor.
       
   166         // ReAllocL() leaves, if there is insufficient memory.
       
   167         TRAP(ret, ( tmp = iBuf->ReAllocL( aLen+iMaxReservationSize ) ));
       
   168 
       
   169         if ( KErrNone == ret )
       
   170             {
       
   171             iBuf=tmp;
       
   172             iBuf->Des().SetLength( aLen + iMaxReservationSize );
       
   173             iBufSize = aLen + iMaxReservationSize;
       
   174             iTreshold = aLen;
       
   175             }
       
   176         }
       
   177 
       
   178     return ret;
       
   179     }
       
   180 
       
   181 // ---------------------------------------------------------
       
   182 // CDpDataBuffer::RegisterDataClient
       
   183 // This method registers data client to the buffer.
       
   184 // ---------------------------------------------------------
       
   185 //
       
   186 TInt CDpDataBuffer::RegisterDataClient(
       
   187     MDpDataClient& aClient )
       
   188     {
       
   189     OstTrace0( TRACE_NORMAL, CDPDATABUFFER_REGISTERDATACLIENT, "CDpDataBuffer::RegisterDataClient" );
       
   190     LOGM(" CDpDataBuffer::RegisterDataClient");
       
   191     TInt ret( KErrNone );
       
   192 
       
   193     switch ( aClient.Role() )
       
   194         {
       
   195         case EDbReader:
       
   196             {
       
   197             if ( iReader )
       
   198                 {
       
   199                 LOG("  CDpDataBuffer::RegisterDataClient, iReader already exists");
       
   200                 OstTrace0( TRACE_NORMAL, DUP1_CDPDATABUFFER_REGISTERDATACLIENT, "CDpDataBuffer:: iReader already exists" );
       
   201 
       
   202                 ret = KErrGeneral;
       
   203                 }
       
   204             else
       
   205                 {
       
   206                 iReader = &aClient;
       
   207                 }
       
   208             break;
       
   209             }
       
   210         case EDbWriter:
       
   211             {
       
   212             if ( iWriter )
       
   213                 {
       
   214                 LOG("  CDpDataBuffer::RegisterDataClient, iWriter already exists");
       
   215                 OstTrace0( TRACE_NORMAL, DUP2_CDPDATABUFFER_REGISTERDATACLIENT, "CDpDataBuffer:: iWriter already exists" );
       
   216 
       
   217                 ret = KErrGeneral;
       
   218                 }
       
   219             else
       
   220                 {
       
   221                 iWriter = &aClient;
       
   222                 }
       
   223             break;
       
   224             }
       
   225         default:
       
   226             {
       
   227             LOG("  CDpDataBuffer::RegisterDataClient, default, return KErrGeneral");
       
   228             OstTrace0( TRACE_NORMAL, DUP3_CDPDATABUFFER_REGISTERDATACLIENT, "CDpDataBuffer:: default, return KErrGeneral" );
       
   229 
       
   230             ret = KErrGeneral;
       
   231             break;
       
   232             }
       
   233         }
       
   234 
       
   235     return ret;
       
   236     }
       
   237 
       
   238 // ---------------------------------------------------------
       
   239 // CDpDataBuffer::UsedBytes
       
   240 // This method gets the amount of used bytes.
       
   241 // Note that when virtual circular buffer has wrapped around
       
   242 // there might be iTailWhenWrappedAround > 0 and therefore we
       
   243 // have to notice that also in calculation. Normally
       
   244 // iTailWhenWrappedAround == 0.
       
   245 //
       
   246 // In other words: When we have data in ebs (enhanced buffer
       
   247 // space) we have to calculate it too. When
       
   248 // iTailWhenWrappedAround>0 iTail==0.
       
   249 //
       
   250 // t     h               twr
       
   251 // |     |              n |
       
   252 // |-------pbs--------|--ebs--|
       
   253 //
       
   254 // ---------------------------------------------------------
       
   255 //
       
   256 TInt CDpDataBuffer::UsedBytes()
       
   257     {
       
   258     OstTrace0( TRACE_NORMAL, CDPDATABUFFER_USEDBYTES, "CDpDataBuffer::UsedBytes" );
       
   259     LOGM(" CDpDataBuffer::UsedBytes");
       
   260     TInt ret( 0 );
       
   261 
       
   262     if ( iHead != iTail  )
       
   263         {
       
   264         if ( iHead > ( iTail + iTailWhenWrappedAround )  )
       
   265             {
       
   266             ret = iHead - iTail;
       
   267             }
       
   268         else
       
   269             {
       
   270             ret = iEnd - iTail - iTailWhenWrappedAround + iHead;
       
   271             }
       
   272         }
       
   273 
       
   274     return ret;
       
   275     }
       
   276 
       
   277 // ---------------------------------------------------------
       
   278 // CDpDataBuffer::FreeBytes
       
   279 // This method gets the amount of free bytes.
       
   280 // ---------------------------------------------------------
       
   281 //
       
   282 TInt CDpDataBuffer::FreeBytes()
       
   283     {
       
   284     OstTrace0( TRACE_NORMAL, CDPDATABUFFER_FREEBYTES, "CDpDataBuffer::FreeBytes" );
       
   285     LOGM(" CDpDataBuffer::FreeBytes");
       
   286 
       
   287     return ( iBufSize - UsedBytes() - iMaxReservationSize );
       
   288     }
       
   289 
       
   290 // ---------------------------------------------------------
       
   291 // CDpDataBuffer::Flush
       
   292 // This method empties the buffer and notifies waiting reader
       
   293 // and writer about the flush.
       
   294 // ---------------------------------------------------------
       
   295 //
       
   296 void CDpDataBuffer::Flush()
       
   297     {
       
   298     OstTrace0( TRACE_NORMAL, CDPDATABUFFER_FLUSH, "CDpDataBuffer::Flush" );
       
   299     LOGM(" CDpDataBuffer::Flush");
       
   300 
       
   301     // throw reader out
       
   302     //signal waiting reader
       
   303     if ( iIsReaderWaiting && iReader )
       
   304         {
       
   305         iReader->FlushNotify();
       
   306         iIsReaderWaiting = EFalse;
       
   307         }
       
   308 
       
   309     // throw writer out
       
   310     //signal waiting writer
       
   311     if ( iIsWriterWaiting && iWriter )
       
   312         {
       
   313         iWriter->FlushNotify();
       
   314         iIsWriterWaiting = EFalse;
       
   315         }
       
   316 
       
   317     // As (currently) data accesses to buffer are synchronous, there can be no
       
   318     // data client accessing the buffer.
       
   319     iEnd = 0;
       
   320     iHead = 0;
       
   321     iTail = 0;
       
   322     iTailWhenWrappedAround = 0;
       
   323 
       
   324     iBuf->Des().Fill( KDpFillChar );
       
   325     }
       
   326 
       
   327 //=============================================================================
       
   328 
       
   329 //  OTHER EXPORTED FUNCTIONS
       
   330 //  none
       
   331 
       
   332 //  End of File