radioengine/utils/src/cradioenginelogger.cpp
branchRCL_3
changeset 20 93c594350b9a
parent 19 cce62ebc198e
equal deleted inserted replaced
19:cce62ebc198e 20:93c594350b9a
     1 /*
       
     2 * Copyright (c) 2009 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 "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 // User includes
       
    19 #include "cradioenginelogger.h"
       
    20 #include "cradioenginetls.h"
       
    21 
       
    22 // ======== MEMBER FUNCTIONS ========
       
    23 
       
    24 // ---------------------------------------------------------------------------
       
    25 // Return the logger instance.
       
    26 // ---------------------------------------------------------------------------
       
    27 //
       
    28 EXPORT_C MRadioEngineLogger* MRadioEngineLogger::Logger()
       
    29     {
       
    30     return CRadioEngineTls::Logger();
       
    31     }
       
    32 
       
    33 #ifdef LOGGING_ENABLED
       
    34 
       
    35 #include <bautils.h>
       
    36 
       
    37 // Indentation
       
    38 _LIT( KLogSpace,    "                                " ); // 32 empty spaces
       
    39 const TInt KMaxIndent = 32;
       
    40 
       
    41 /**
       
    42  * Timestamp formatter string
       
    43  */
       
    44 _LIT8( KTimestampFormat, "%02d.%02d.%4d %02d:%02d:%02d.%05d" );
       
    45 
       
    46 /**
       
    47  * Timestamp separator string
       
    48  */
       
    49 _LIT8( KTimestampSeparator, " " );
       
    50 
       
    51 // Memory card path. Has to contain directory ( \\) or BaflUtils::PathExists fails
       
    52 _LIT( KMemoryCard, "E:\\" );
       
    53 
       
    54 _LIT( KLogEnter,     "\\ %S" );
       
    55 _LIT( KLogExit,      "/ %S" );
       
    56 _LIT8( KLogLine,     "| " );
       
    57 _LIT( KLogLeave,     "#+ %S: LEAVE!" );
       
    58 _LIT( KLogExitRet,   "/ %S, Returning " );
       
    59 
       
    60 _LIT8( KNewLine, "\r\n" );
       
    61 _LIT8( KHexFormat, "ptr: 0x%X" );
       
    62 
       
    63 
       
    64 // ======== MEMBER FUNCTIONS ========
       
    65 
       
    66 // ---------------------------------------------------------------------------
       
    67 //
       
    68 // ---------------------------------------------------------------------------
       
    69 //
       
    70 CRadioEngineLogger* CRadioEngineLogger::NewL( RFs& aFs )
       
    71     {
       
    72     CRadioEngineLogger* self = new (ELeave) CRadioEngineLogger( aFs );
       
    73     CleanupStack::PushL( self );
       
    74     self->ConstructL();
       
    75     CleanupStack::Pop( self );
       
    76     return self;
       
    77     }
       
    78 
       
    79 // ---------------------------------------------------------------------------
       
    80 //
       
    81 // ---------------------------------------------------------------------------
       
    82 //
       
    83 CRadioEngineLogger::CRadioEngineLogger( RFs& aFs )
       
    84     : iFs( aFs )
       
    85     {
       
    86     }
       
    87 
       
    88 // ---------------------------------------------------------------------------
       
    89 //
       
    90 // ---------------------------------------------------------------------------
       
    91 //
       
    92 void CRadioEngineLogger::ConstructL()
       
    93     {
       
    94     if ( KLogFile().FindF( KMemoryCard ) == 0 )
       
    95         {
       
    96         TBool readOnly = EFalse;
       
    97 
       
    98         // Returns KErrPathNotFound if memory card is not present
       
    99         TInt err = BaflUtils::DiskIsReadOnly( iFs, KMemoryCard, readOnly );
       
   100         if ( err || readOnly )
       
   101             {
       
   102             // Log file path points to the memory card and the card is not
       
   103             // present or is read only => change the drive to C:
       
   104             TFileName fileName( _L( "C:" ) );
       
   105             TParsePtrC parse( KLogFile );
       
   106             fileName.Append( parse.Path() );
       
   107             fileName.Append( parse.NameAndExt() );
       
   108             iFileName = fileName.AllocL();
       
   109             }
       
   110         }
       
   111 
       
   112     if ( !iFileName )
       
   113         {
       
   114         iFileName = KLogFile().AllocL();
       
   115         }
       
   116 
       
   117     BaflUtils::EnsurePathExistsL( iFs, *iFileName );
       
   118 
       
   119     User::LeaveIfError( Dll::SetTls( this ) );
       
   120     }
       
   121 
       
   122 // ---------------------------------------------------------------------------
       
   123 //
       
   124 // ---------------------------------------------------------------------------
       
   125 //
       
   126 CRadioEngineLogger::~CRadioEngineLogger()
       
   127     {
       
   128     iFile.Close();
       
   129     delete iFileName;
       
   130     }
       
   131 
       
   132 // ---------------------------------------------------------------------------
       
   133 // Clear the log by deleting the logfile.
       
   134 // ---------------------------------------------------------------------------
       
   135 //
       
   136 MRadioEngineLogger& CRadioEngineLogger::ClearLog()
       
   137     {
       
   138     if ( BaflUtils::FileExists( iFs, *iFileName ) )
       
   139         {
       
   140         // Returned error code ignored intentionally because there is no way
       
   141         // to report an error
       
   142         BaflUtils::DeleteFile( iFs, *iFileName );
       
   143         }
       
   144 
       
   145     return *this;
       
   146     }
       
   147 
       
   148 // ---------------------------------------------------------------------------
       
   149 // Adds a 8-bit string to log line
       
   150 // ---------------------------------------------------------------------------
       
   151 //
       
   152 MRadioEngineLogger& CRadioEngineLogger::Add( const TDesC8& aMsg )
       
   153     {
       
   154     AddDesC<TPtrC8, TDesC8>( aMsg );
       
   155     return *this;
       
   156     }
       
   157 
       
   158 // ---------------------------------------------------------------------------
       
   159 // Adds a 16-bit string to log line
       
   160 // ---------------------------------------------------------------------------
       
   161 //
       
   162 MRadioEngineLogger& CRadioEngineLogger::Add( const TDesC& aMsg )
       
   163     {
       
   164     // Note! No character conversion is performed while going from 16-bit
       
   165     // descriptor to 8-bit descriptor. This is considered acceptable in a
       
   166     // debugging utility
       
   167     AddDesC<TPtrC, TDesC>( aMsg );
       
   168     return *this;
       
   169     }
       
   170 
       
   171 // ---------------------------------------------------------------------------
       
   172 // Adds a TInt to log line
       
   173 // ---------------------------------------------------------------------------
       
   174 //
       
   175 MRadioEngineLogger& CRadioEngineLogger::Add( TInt aInt )
       
   176     {
       
   177     TBuf8<20> buf8;
       
   178     buf8.Num( aInt );
       
   179     Add( buf8 );
       
   180     return *this;
       
   181     }
       
   182 
       
   183 // ---------------------------------------------------------------------------
       
   184 // Adds a TReal to log line
       
   185 // ---------------------------------------------------------------------------
       
   186 //
       
   187 MRadioEngineLogger& CRadioEngineLogger::Add( const TReal& aReal )
       
   188     {
       
   189     TBuf8<20> buf8;
       
   190     buf8.Format( _L8( "%f" ), aReal );
       
   191     Add( buf8 );
       
   192     return *this;
       
   193     }
       
   194 
       
   195 // ---------------------------------------------------------------------------
       
   196 // Adds a c-style string to log line
       
   197 // ---------------------------------------------------------------------------
       
   198 //
       
   199 MRadioEngineLogger& CRadioEngineLogger::Add( const char* aText )
       
   200     {
       
   201     Add( TPtrC8( reinterpret_cast<const TText8*>( aText ) ) );
       
   202     return *this;
       
   203     }
       
   204 
       
   205 // ---------------------------------------------------------------------------
       
   206 // Adds a pointer value to log line
       
   207 // ---------------------------------------------------------------------------
       
   208 //
       
   209 MRadioEngineLogger& CRadioEngineLogger::Add( const TAny* aPtr )
       
   210     {
       
   211     TBuf8<20> buf8;
       
   212     buf8.Format( KHexFormat, aPtr );
       
   213     Add( buf8 );
       
   214     return *this;
       
   215     }
       
   216 
       
   217 // ---------------------------------------------------------------------------
       
   218 // Adds a timestamp of current time to log line
       
   219 // ---------------------------------------------------------------------------
       
   220 //
       
   221 MRadioEngineLogger& CRadioEngineLogger::Add( const TTime& aTime )
       
   222     {
       
   223     TTimestamp timestamp;
       
   224     ParseTimestamp( aTime, timestamp );
       
   225     Add( timestamp );
       
   226     return *this;
       
   227     }
       
   228 
       
   229 // ---------------------------------------------------------------------------
       
   230 // Adds a timestamp of current time to log line
       
   231 // ---------------------------------------------------------------------------
       
   232 //
       
   233 MRadioEngineLogger& CRadioEngineLogger::AddTimestamp()
       
   234     {
       
   235     TTime now;
       
   236     now.HomeTime();
       
   237     return Add( now );
       
   238     }
       
   239 
       
   240 // ---------------------------------------------------------------------------
       
   241 // Adds a formatted string to log line
       
   242 // ---------------------------------------------------------------------------
       
   243 //
       
   244 MRadioEngineLogger& CRadioEngineLogger::AddFormat( TRefByValue<const TDesC> aFmt, ... )
       
   245     {
       
   246     VA_LIST list;
       
   247     VA_START( list, aFmt );
       
   248 
       
   249     TBuf<KLogBufferLength> buf16;
       
   250 
       
   251     // Calls Overflow() if it doesn't fit
       
   252     buf16.AppendFormatList( aFmt, list, this );
       
   253 
       
   254     VA_END( list );
       
   255 
       
   256     Add( buf16 );
       
   257     return *this;
       
   258     }
       
   259 
       
   260 // ---------------------------------------------------------------------------
       
   261 // Adds the line indentation with line prefix to log line
       
   262 // ---------------------------------------------------------------------------
       
   263 //
       
   264 MRadioEngineLogger& CRadioEngineLogger::AddIndent( const TDesC& aMarker )
       
   265     {
       
   266     Add( aMarker );
       
   267     Add( KLogSpace().Mid( 0, iIndent ) );
       
   268     Add( KLogLine() );
       
   269     return *this;
       
   270     }
       
   271 
       
   272 // ---------------------------------------------------------------------------
       
   273 // Adds the line indentation to log line
       
   274 // ---------------------------------------------------------------------------
       
   275 //
       
   276 MRadioEngineLogger& CRadioEngineLogger::AddIndentClear( const TDesC& aMarker )
       
   277     {
       
   278     Add( aMarker );
       
   279     Add( KLogSpace().Mid( 0, iIndent ) );
       
   280     return *this;
       
   281     }
       
   282 
       
   283 // ---------------------------------------------------------------------------
       
   284 // From TDes16Overflow
       
   285 // Handles the overflow from AppendFormatList()
       
   286 // ---------------------------------------------------------------------------
       
   287 //
       
   288 void CRadioEngineLogger::Overflow( TDes16& /*aDes*/ )
       
   289     {
       
   290     // aDes contains the part that did fit in the descriptor, but the part that
       
   291     // didn't is lost. Modifying the descriptor here would modify it in AddFormat(),
       
   292     // but since it gets logged there we only need to add a message about the overflow.
       
   293     Add( _L( "FORMAT OVERFLOW! " ) );
       
   294     }
       
   295 
       
   296 // ---------------------------------------------------------------------------
       
   297 // Increment indentation
       
   298 // ---------------------------------------------------------------------------
       
   299 //
       
   300 MRadioEngineLogger& CRadioEngineLogger::IncIndent()
       
   301     {
       
   302     if ( ++iIndent > KMaxIndent )
       
   303         {
       
   304         iIndent = KMaxIndent;
       
   305         }
       
   306 
       
   307     return *this;
       
   308     }
       
   309 
       
   310 // ---------------------------------------------------------------------------
       
   311 // Decrement indentation
       
   312 // ---------------------------------------------------------------------------
       
   313 //
       
   314 MRadioEngineLogger& CRadioEngineLogger::DecIndent()
       
   315     {
       
   316     if ( --iIndent < 0 )
       
   317         {
       
   318         iIndent = 0;
       
   319         }
       
   320 
       
   321     return *this;
       
   322     }
       
   323 
       
   324 // ---------------------------------------------------------------------------
       
   325 // Commits the log line to file and RDebug and resets internal buffer
       
   326 // ---------------------------------------------------------------------------
       
   327 //
       
   328 MRadioEngineLogger& CRadioEngineLogger::Commit( TBool aNewLine )
       
   329     {
       
   330     // Write log buffer to RDebug
       
   331     RDebug::RawPrint( iBuf8 );
       
   332 
       
   333     // Write log buffer to file
       
   334     TInt err = iFile.Open( iFs, *iFileName, EFileWrite );
       
   335     if ( err )
       
   336         {
       
   337         err = iFile.Create( iFs, *iFileName, EFileWrite );
       
   338         }
       
   339 
       
   340     if ( !err )
       
   341         {
       
   342         TInt unused = 0;
       
   343         if ( iFile.Seek( ESeekEnd, unused ) == KErrNone )
       
   344             {
       
   345             if ( !iTimeStampWritten )
       
   346                 {
       
   347                 // First print a timestamp to log
       
   348                 TTimestamp timestamp;
       
   349                 TTime now;
       
   350                 now.HomeTime();
       
   351                 ParseTimestamp( now, timestamp );
       
   352                 iFile.Write( timestamp );
       
   353                 iFile.Write( KTimestampSeparator );
       
   354                 iTimeStampWritten = ETrue;
       
   355                 }
       
   356 
       
   357             iFile.Write( iBuf8 );
       
   358 
       
   359             if ( aNewLine )
       
   360                 {
       
   361                 iFile.Write( KNewLine );
       
   362                 iTimeStampWritten = EFalse;
       
   363                 }
       
   364             }
       
   365 
       
   366         iFile.Close();
       
   367         }
       
   368 
       
   369     iBuf8.Zero();
       
   370     return *this;
       
   371     }
       
   372 
       
   373 // ---------------------------------------------------------------------------
       
   374 // Returns the amount of characters that still fit in the buffer
       
   375 // ---------------------------------------------------------------------------
       
   376 //
       
   377 TInt CRadioEngineLogger::Available() const
       
   378     {
       
   379     return iBuf8.MaxLength() - iBuf8.Length();
       
   380     }
       
   381 
       
   382 // ---------------------------------------------------------------------------
       
   383 // Templated function to add either 8-bit or 16-bit descriptor to buffer
       
   384 // ---------------------------------------------------------------------------
       
   385 //
       
   386 template<class PTR, class DESC>
       
   387 void CRadioEngineLogger::AddDesC( const DESC& aDesc )
       
   388     {
       
   389     PTR ptr( aDesc );
       
   390     while ( ptr.Length() > Available() )
       
   391         {
       
   392         PTR writePtr = ptr.Left( Available() );
       
   393         iBuf8.Append( writePtr );
       
   394 
       
   395         ptr.Set( ptr.Mid( writePtr.Length() ) );
       
   396         Commit( EFalse );
       
   397         }
       
   398 
       
   399     iBuf8.Append( ptr );
       
   400     }
       
   401 
       
   402 // ---------------------------------------------------------------------------
       
   403 // Parses the timestamp from the given TTime
       
   404 // ---------------------------------------------------------------------------
       
   405 //
       
   406 void CRadioEngineLogger::ParseTimestamp( const TTime& aTime, TTimestamp& aTimestamp )
       
   407     {
       
   408     TDateTime dateTime = aTime.DateTime();
       
   409     aTimestamp.Zero();
       
   410     aTimestamp.Format( KTimestampFormat, dateTime.Day() + 1,
       
   411                                          dateTime.Month() + 1,
       
   412                                          dateTime.Year(),
       
   413                                          dateTime.Hour(),
       
   414                                          dateTime.Minute(),
       
   415                                          dateTime.Second(),
       
   416                                          dateTime.MicroSecond() );
       
   417     }
       
   418 
       
   419 // ---------------------------------------------------------------------------
       
   420 // Constructor. Log method entry
       
   421 // ---------------------------------------------------------------------------
       
   422 //
       
   423 EXPORT_C TRadioMethodLogger::TRadioMethodLogger( const TText* aFunc,
       
   424                                                  const TText* aRetFormat )
       
   425     : iFunc( aFunc )
       
   426     , iRetFormat( aRetFormat )
       
   427     {
       
   428     MRadioEngineLogger* logger = MRadioEngineLogger::Logger();
       
   429     logger->AddIndentClear( KMarkerEngine ).AddFormat( KLogEnter, &iFunc ).Commit();
       
   430     logger->IncIndent();
       
   431     }
       
   432 
       
   433 // ---------------------------------------------------------------------------
       
   434 // Destructor. Log method exit
       
   435 // ---------------------------------------------------------------------------
       
   436 //
       
   437 EXPORT_C TRadioMethodLogger::~TRadioMethodLogger()
       
   438     {
       
   439     MRadioEngineLogger::Logger()->DecIndent();
       
   440 
       
   441     if ( std::uncaught_exception() ) // Leave is an exception
       
   442         {
       
   443         // The function exited with a leave
       
   444         MRadioEngineLogger::Logger()->AddIndentClear( KMarkerEngine ).AddFormat( KLogLeave, &iFunc ).Commit();
       
   445         }
       
   446     else
       
   447         {
       
   448         // The function exited normally
       
   449         if ( iRetFormat.Length() == 0 )
       
   450             {
       
   451             MRadioEngineLogger::Logger()->AddIndentClear( KMarkerEngine ).AddFormat( KLogExit, &iFunc ).Commit();
       
   452             }
       
   453         else
       
   454             {
       
   455             TBuf<100> format( KLogExitRet );
       
   456             format.Append( iRetFormat );
       
   457             #if defined( __WINS__ )
       
   458 
       
   459                 TInt32 retVal = 0;
       
   460                 _asm( mov retVal, ebx );
       
   461                 MRadioEngineLogger::Logger()->AddIndentClear( KMarkerEngine ).AddFormat( format, &iFunc, retVal ).Commit();
       
   462 
       
   463             #else
       
   464 
       
   465                 MRadioEngineLogger::Logger()->AddIndentClear( KMarkerEngine ).AddFormat( KLogExit, &iFunc ).Commit();
       
   466 
       
   467             #endif
       
   468             }
       
   469         }
       
   470     }
       
   471 
       
   472 #else // #ifdef LOGGING_ENABLED
       
   473 
       
   474 // ===========================================================================
       
   475 // Dummy function definitions to keep the exports unchanged when logging is turned off
       
   476 // These can not be used.
       
   477 // ===========================================================================
       
   478 EXPORT_C TRadioMethodLogger::TRadioMethodLogger( const TText*, const TText* ) {}
       
   479 EXPORT_C TRadioMethodLogger::~TRadioMethodLogger() {}
       
   480 
       
   481 #endif // #ifdef LOGGING_ENABLED