adaptationlayer/dataport/dataport_csy/src/dpdataelement.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 #include "dpdataelement.h" // data element
       
    21 #include "dpdatabuffer.h"  // base class for rx and tx buffers
       
    22 #include "dpdataclient.h"  // data client that access buffer
       
    23 #include "dpdef.h"         // dataport definitions
       
    24 #include "dplog.h"         // dataport logging
       
    25 #include "osttracedefinitions.h"
       
    26 #ifdef OST_TRACE_COMPILER_IN_USE
       
    27 #include "dpdataelementtraces.h"
       
    28 #endif
       
    29 
       
    30 // EXTERNAL DATA STRUCTURES
       
    31 // none
       
    32 
       
    33 // EXTERNAL FUNCTION PROTOTYPES
       
    34 // none
       
    35 
       
    36 // CONSTANTS
       
    37 // none
       
    38 
       
    39 // MACROS
       
    40 // none
       
    41 
       
    42 // LOCAL CONSTANTS AND MACROS
       
    43 // none
       
    44 
       
    45 // MODULE DATA STRUCTURES
       
    46 // none
       
    47 
       
    48 // LOCAL FUNCTION PROTOTYPES
       
    49 // none
       
    50 
       
    51 // FORWARD DECLARATIONS
       
    52 // none
       
    53 
       
    54 // ============================= LOCAL FUNCTIONS ===============================
       
    55 
       
    56 // none
       
    57 
       
    58 
       
    59 // ============================ MEMBER FUNCTIONS ===============================
       
    60 
       
    61 // -----------------------------------------------------------------------------
       
    62 // CDpDataElement::CDpDataElement
       
    63 // C++ default constructor can NOT contain any code, that
       
    64 // might leave.
       
    65 // -----------------------------------------------------------------------------
       
    66 //
       
    67 CDpDataElement::CDpDataElement(
       
    68     CDpDataBuffer& aDataBuffer,
       
    69     TDataElementType aType ) :
       
    70     iDB( aDataBuffer ),
       
    71     iType( aType ),
       
    72     iSize( 0 ),
       
    73     iState( EDeFree )
       
    74     {
       
    75     OstTrace0( TRACE_NORMAL, CDPDATAELEMENT_CDPDATAELEMENT, "CDpDataElement::CDpDataElement" );
       
    76     LOGM("CDpDataElement::CDpDataElement");
       
    77     }
       
    78 
       
    79 // -----------------------------------------------------------------------------
       
    80 // CDpDataElement::~CDpDataElement
       
    81 // Destructor
       
    82 // -----------------------------------------------------------------------------
       
    83 //
       
    84 CDpDataElement::~CDpDataElement()
       
    85     {
       
    86     OstTrace0( TRACE_NORMAL, DUP1_CDPDATAELEMENT_CDPDATAELEMENT, "CDpDataElement::~CDpDataElement" );
       
    87     LOGM("CDpDataElement::~CDpDataElement");
       
    88     }
       
    89 
       
    90 // -----------------------------------------------------------------------------
       
    91 // CDpDataElement::Reserve
       
    92 // This method reserves an data element of requested length
       
    93 // from the buffer. aTail is not used when reserving write
       
    94 // element, it is used only in read operations.
       
    95 // -----------------------------------------------------------------------------
       
    96 //
       
    97 TInt CDpDataElement::Reserve(
       
    98     const TInt aSize,
       
    99     TPtr8& aDes,
       
   100     TPtr8& aTail,
       
   101     TBool aOverrideMRS )
       
   102     {
       
   103     OstTrace0( TRACE_NORMAL, CDPDATAELEMENT_RESERVE, "CDpDataElement::Reserve" );
       
   104     LOGM("CDpDataElement::Reserve");
       
   105 
       
   106     TInt ret( KErrNone );
       
   107 
       
   108     // Wrong size
       
   109     if ( ( !aOverrideMRS ) && ( aSize > iDB.iMaxReservationSize || 0 >= aSize ) )
       
   110         {
       
   111         ret = KErrArgument;
       
   112         }
       
   113     else if ( aOverrideMRS && ( aSize > iDB.Size() || 0 >= aSize ) )
       
   114         {
       
   115         ret = KErrArgument;
       
   116         }
       
   117     // Already reserved
       
   118     else if ( EDeFree != iState )
       
   119         {
       
   120         // This can happen e.g. when client makes a null read.
       
   121         LOG("  CDpDataElement::Reserve - FAILED");
       
   122         OstTrace0( TRACE_NORMAL, DUP1_CDPDATAELEMENT_RESERVE, "CDpDataElement:: Reserve - FAILED" );
       
   123 
       
   124         ret = KErrGeneral;
       
   125         }
       
   126     else
       
   127         {
       
   128         switch ( iType )
       
   129             {
       
   130             case EDeRead:
       
   131                 {
       
   132                 ret = HandleReadTypeReserve( aSize, aDes, aTail );
       
   133                 break;
       
   134                 }
       
   135             case EDeWrite:
       
   136                 {
       
   137                 ret = HandleWriteTypeReserve( aSize, aDes );
       
   138                 break;
       
   139                 }
       
   140             default:
       
   141                 {
       
   142                 // This should never happen.
       
   143                 ret = KErrGeneral;
       
   144                 }
       
   145             }
       
   146         }
       
   147 
       
   148     return ret;
       
   149     }
       
   150 
       
   151 // -----------------------------------------------------------------------------
       
   152 // CDpDataElement::Release
       
   153 // This method releases the data element. When a reserved data
       
   154 // element has been used it has to be released before it can be
       
   155 // reserved again. If x bytes has been reserved but only y has
       
   156 // been used, y has to be given in parameter (0 <= y <= x).
       
   157 // -----------------------------------------------------------------------------
       
   158 //
       
   159 TInt CDpDataElement::Release(
       
   160     const TInt aUsedLength )
       
   161     {
       
   162     OstTrace0( TRACE_NORMAL, CDPDATAELEMENT_RELEASE, "CDpDataElement::Release" );
       
   163     LOGM("CDpDataElement::Release");
       
   164 
       
   165     TInt ret( KErrNone );
       
   166 
       
   167     // Already reserved
       
   168     if ( EDeReserved != iState )
       
   169         {
       
   170         LOG("  DP:DataElement::Release - FAIL, not reserved");
       
   171         OstTrace0( TRACE_NORMAL, DUP1_CDPDATAELEMENT_RELEASE, "CDpDataElement:: Release - FAIL, not reserved" );
       
   172 
       
   173         ret = KErrGeneral;
       
   174         }
       
   175     // Wrong length
       
   176     else if ( aUsedLength > iSize || 0 > aUsedLength )
       
   177         {
       
   178         LOG("  DP:DataElement::Release - FAIL, wrong length");
       
   179         OstTrace0( TRACE_NORMAL, DUP2_CDPDATAELEMENT_RELEASE, "CDpDataElement:: Release - FAIL, wrong length" );
       
   180 
       
   181         ret = KErrGeneral;
       
   182         }
       
   183     else
       
   184         {
       
   185         switch ( iType )
       
   186             {
       
   187             case CDpDataElement::EDeRead:
       
   188                 {
       
   189                 if ( 0 != iDB.iTailWhenWrappedAround )
       
   190                     {
       
   191                     LOG("  DP:DataElement::Release - iTailWhenWrappedAround != 0 ");
       
   192                     OstTrace0( TRACE_NORMAL, DUP3_CDPDATAELEMENT_RELEASE, "CDpDataElement:: Release - iTailWhenWrappedAround != 0 " );
       
   193 
       
   194                     TInt tailsize( iDB.iEnd - iDB.iTailWhenWrappedAround );
       
   195 
       
   196                     if ( tailsize <= aUsedLength )
       
   197                         {
       
   198                         if ( 0 < tailsize )
       
   199                             {
       
   200                             TPtr8 taildesc(
       
   201                                 reinterpret_cast<unsigned char*>( &iDB.iBuf->
       
   202                                     Des()[iDB.iTailWhenWrappedAround] ),
       
   203                                 tailsize,
       
   204                                 tailsize );
       
   205                             // Fill released space with FILLCHAR.
       
   206                             taildesc.Fill( KDpFillChar );
       
   207                             }
       
   208                         //no else
       
   209 
       
   210                         TPtr8 tmp(
       
   211                             reinterpret_cast<unsigned char*>( &iDB.iBuf->
       
   212                                 Des()[iDB.iTail] ),
       
   213                             ( aUsedLength - tailsize ),
       
   214                             ( aUsedLength - tailsize ) );
       
   215                         // Fill released space with FILLCHAR.
       
   216                         tmp.Fill( KDpFillChar );
       
   217                         iDB.iTailWhenWrappedAround = 0;
       
   218                         iDB.iTail += ( aUsedLength - tailsize );
       
   219                         iDB.iEnd = iDB.iHead;
       
   220                         }
       
   221                     else
       
   222                         {
       
   223                         // tailsize>aUsedLength
       
   224                         TPtr8 taildesc(
       
   225                             reinterpret_cast<unsigned char*>( &iDB.iBuf->
       
   226                                 Des()[iDB.iTailWhenWrappedAround] ),
       
   227                             aUsedLength,
       
   228                             aUsedLength );
       
   229                         // Fill released space with FILLCHAR.
       
   230                         taildesc.Fill( KDpFillChar );
       
   231                         iDB.iTail += iDB.iTailWhenWrappedAround + aUsedLength;
       
   232                         iDB.iTailWhenWrappedAround = 0;
       
   233                         }
       
   234                     }
       
   235                 else
       
   236                     {
       
   237                     TInt index( iDB.iTail );
       
   238                     iDB.iTail += aUsedLength;
       
   239                     TInt freeSize( aUsedLength );
       
   240 
       
   241                     TPtr8 tmp(
       
   242                         reinterpret_cast<unsigned char*>( &iDB.iBuf->
       
   243                             Des()[index] ),
       
   244                         freeSize,
       
   245                         freeSize );
       
   246                     // Fill released space with FILLCHAR.
       
   247                     tmp.Fill( KDpFillChar );
       
   248                     }
       
   249 
       
   250                 iState = EDeFree;
       
   251                 if ( iDB.iIsWriterWaiting && iDB.iWE.iSize <= iDB.FreeBytes() )
       
   252                     {
       
   253                     iDB.iIsWriterWaiting = EFalse;
       
   254                     // Signal waiting writer.
       
   255                     iDB.iWriter->ReleaseNotify();
       
   256                     }
       
   257                 //no else
       
   258                 break;
       
   259                 }
       
   260             case CDpDataElement::EDeWrite:
       
   261                 {
       
   262                 iDB.iHead += aUsedLength;
       
   263 
       
   264                 if ( iDB.iEnd < iDB.iHead )
       
   265                     {
       
   266                     iDB.iEnd = iDB.iHead;
       
   267                     }
       
   268                 //no else
       
   269                 iState = EDeFree;
       
   270                 if ( iDB.iIsReaderWaiting &&
       
   271                      iDB.iReader &&
       
   272                      iDB.iRE.iSize <= iDB.UsedBytes() )
       
   273                     {
       
   274                     iDB.iIsReaderWaiting = EFalse;
       
   275                     // Signal waiting reader.
       
   276                     iDB.iReader->ReleaseNotify();
       
   277                     }
       
   278                 //no else
       
   279                 }
       
   280                 break;
       
   281             default:
       
   282                 {
       
   283                 break;
       
   284                 }
       
   285             }
       
   286         }
       
   287 
       
   288     return ret;
       
   289     }
       
   290 
       
   291 // -----------------------------------------------------------------------------
       
   292 // CDpDataElement::HandleReadTypeReserve
       
   293 // This method handles reserve operation for read type element.
       
   294 // -----------------------------------------------------------------------------
       
   295 //
       
   296 TInt CDpDataElement::HandleReadTypeReserve(
       
   297     const TInt aSize,
       
   298     TPtr8 &aDes,
       
   299     TPtr8 &aTail )
       
   300     {
       
   301     OstTrace0( TRACE_NORMAL, CDPDATAELEMENT_HANDLEREADTYPERESERVE, "CDpDataElement::HandleReadTypeReserve" );
       
   302     LOGM("CDpDataElement::HandleReadTypeReserve");
       
   303 
       
   304     TInt ret( KErrNone );
       
   305     iSize = aSize;
       
   306 
       
   307     // is there enough data
       
   308     if ( aSize > iDB.UsedBytes() )
       
   309         {
       
   310         // can't have both waiting
       
   311         if ( iDB.iIsWriterWaiting && iDB.iIsReaderWaiting)
       
   312             {
       
   313             LOG("  DP:CDpDataElement::Reserve - Fail:both waiting");
       
   314             OstTrace0( TRACE_NORMAL, DUP1_CDPDATAELEMENT_HANDLEREADTYPERESERVE, "CDpDataElement:: - Fail: both waiting" );
       
   315 
       
   316             ret = KErrGeneral;
       
   317             }
       
   318         else
       
   319             {
       
   320             iDB.iIsReaderWaiting = ETrue;
       
   321             // have to wait
       
   322             ret = KErrNotReady;
       
   323             }
       
   324         }
       
   325     else
       
   326         {
       
   327         iState = EDeReserved;
       
   328         if ( ( iDB.iTail + aSize ) > iDB.iEnd )
       
   329             {
       
   330             // set des
       
   331             TInt tailSize( iDB.iEnd-iDB.iTail );
       
   332 
       
   333             if ( tailSize > 0 )
       
   334                 {
       
   335                 aDes.Set(
       
   336                     reinterpret_cast<unsigned char*>(
       
   337                         &iDB.iBuf->Des()[iDB.iTail] ),
       
   338                     tailSize,
       
   339                     tailSize );
       
   340                 }
       
   341             //no else
       
   342 
       
   343             // set tail
       
   344             aTail.Set(
       
   345                 reinterpret_cast<unsigned char*>( &iDB.iBuf->Des()[0] ),
       
   346                 ( aSize - tailSize ),
       
   347                 ( aSize - tailSize ) );
       
   348             iDB.iTailWhenWrappedAround = iDB.iTail;
       
   349             iDB.iTail = 0;
       
   350             }
       
   351         else
       
   352             {
       
   353             // in one piece, set des
       
   354             aDes.Set(
       
   355                 reinterpret_cast<unsigned char*>( &iDB.iBuf->
       
   356                     Des()[iDB.iTail] ),
       
   357                 iSize,
       
   358                 iSize );
       
   359             }
       
   360         }
       
   361 
       
   362     return ret;
       
   363     }
       
   364 
       
   365 // -----------------------------------------------------------------------------
       
   366 // CDpDataElement::HandleWriteTypeReserve
       
   367 // This method handles reserve operation for write type element.
       
   368 // -----------------------------------------------------------------------------
       
   369 //
       
   370 TInt CDpDataElement::HandleWriteTypeReserve(
       
   371     const TInt aSize,
       
   372     TPtr8 &aDes )
       
   373     {
       
   374     OstTrace0( TRACE_NORMAL, CDPDATAELEMENT_HANDLEWRITETYPERESERVE, "CDpDataElement::HandleWriteTypeReserve" );
       
   375     LOGM("CDpDataElement::HandleWriteTypeReserve");
       
   376 
       
   377     TInt ret( KErrNone );
       
   378     iSize = aSize;
       
   379 
       
   380     if ( iDB.iHead > iDB.iTreshold )
       
   381         {
       
   382         iDB.iHead = 0;
       
   383         }
       
   384     // no else
       
   385 
       
   386     // There is not enough free space
       
   387     if ( aSize > iDB.FreeBytes() )
       
   388         {
       
   389         OstTrace1( TRACE_NORMAL, DUP1_CDPDATAELEMENT_HANDLEWRITETYPERESERVE, "CDpDataElement:: aSize: %d", aSize );
       
   390         OstTrace1( TRACE_NORMAL, DUP2_CDPDATAELEMENT_HANDLEWRITETYPERESERVE, "CDpDataElement:: iDB.FreeBytes: %d", iDB.FreeBytes() );
       
   391 
       
   392         LOG1("  CDpDataElement::HandleWriteTypeReserve, aSize = %d",
       
   393             aSize );
       
   394         LOG1("  CDpDataElement::HandleWriteTypeReserve, iDB.FreeBytes = %d",
       
   395             iDB.FreeBytes() );
       
   396 
       
   397         // Cannot have both waiting.
       
   398         if ( iDB.iIsReaderWaiting )
       
   399             {
       
   400             LOG("  ERROR, CDpDataElement::HandleWriteTypeReserve, Both waiting");
       
   401             OstTrace0( TRACE_NORMAL, DUP3_CDPDATAELEMENT_HANDLEWRITETYPERESERVE, "ERROR, CDpDataElement::HandleWriteTypeReserve, Both waiting" );
       
   402 
       
   403             ret = KErrGeneral;
       
   404             }
       
   405         else
       
   406             {
       
   407             iDB.iIsWriterWaiting = ETrue;
       
   408             // Have to wait.
       
   409             ret = KErrNotReady;
       
   410             }
       
   411         }
       
   412     else
       
   413         {
       
   414         iState = EDeReserved;
       
   415         // In one piece, set des
       
   416         aDes.Set( reinterpret_cast<unsigned char*>(
       
   417             &iDB.iBuf->Des()[iDB.iHead] ), 0, iSize );
       
   418         }
       
   419 
       
   420     return ret;
       
   421     }
       
   422 
       
   423 // ========================== OTHER EXPORTED FUNCTIONS =========================
       
   424 
       
   425 // none
       
   426 
       
   427 
       
   428 //  End of File