memspy/Engine/Source/Sink/MemSpyEngineOutputSinkFile.cpp
changeset 0 a03f92240627
child 20 ca8a1b6995f6
equal deleted inserted replaced
-1:000000000000 0:a03f92240627
       
     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 #include "MemSpyEngineOutputSinkFile.h"
       
    19 
       
    20 // System includes
       
    21 #include <e32svr.h>
       
    22 
       
    23 // User includes
       
    24 #include <memspy/engine/memspyenginelogger.h>
       
    25 #include <memspy/engine/memspyengineutils.h>
       
    26 
       
    27 // Constants
       
    28 const TInt KMemSpyLineBufferLength = 1024;
       
    29 const TInt KMemSpyFileServerBufferExpandSize = 1024 * 32;
       
    30 
       
    31 // Literal constants
       
    32 _LIT8( KMemSpyCRLF, "\r\n" );
       
    33 
       
    34 
       
    35 CMemSpyEngineOutputSinkFile::CMemSpyEngineOutputSinkFile( CMemSpyEngine& aEngine )
       
    36 :   CMemSpyEngineOutputSink( aEngine )
       
    37     {
       
    38     }
       
    39 
       
    40 
       
    41 CMemSpyEngineOutputSinkFile::~CMemSpyEngineOutputSinkFile()
       
    42     {
       
    43     TRACE( RDebug::Printf( "CMemSpyEngineOutputSinkFile::~CMemSpyEngineOutputSinkFile() - START" ) );
       
    44 
       
    45     TRACE( RDebug::Printf( "CMemSpyEngineOutputSinkFile::~CMemSpyEngineOutputSinkFile() - destroying normal logs..." ) );
       
    46     iLogs.ResetAndDestroy();
       
    47     iLogs.Close();
       
    48 
       
    49     TRACE( RDebug::Printf( "CMemSpyEngineOutputSinkFile::~CMemSpyEngineOutputSinkFile() - destroying limbo logs..." ) );
       
    50     iLogsPendingDestruction.ResetAndDestroy();
       
    51     iLogsPendingDestruction.Close();
       
    52 
       
    53     iFsSession.Close();
       
    54 
       
    55     TRACE( RDebug::Printf( "CMemSpyEngineOutputSinkFile::~CMemSpyEngineOutputSinkFile() - END" ) );
       
    56     }
       
    57 
       
    58 
       
    59 void CMemSpyEngineOutputSinkFile::ConstructL()
       
    60     {
       
    61     TRACE( RDebug::Printf( "CMemSpyEngineOutputSinkFile::ConstructL() - START" ) );
       
    62 
       
    63     BaseConstructL();
       
    64 
       
    65     // Identify the file server process id
       
    66     TRACE( RDebug::Printf( "CMemSpyEngineOutputSinkFile::ConstructL() - identifying f32 process id..." ) );
       
    67     iFileServerProcessId = MemSpyEngineUtils::IdentifyFileServerProcessIdL();
       
    68 
       
    69     // Create the standard output file
       
    70     TRACE( RDebug::Printf( "CMemSpyEngineOutputSinkFile::ConstructL() - connecting to f32..." ) );
       
    71     User::LeaveIfError( iFsSession.Connect() );
       
    72     
       
    73     // Make default log file
       
    74     TRACE( RDebug::Printf( "CMemSpyEngineOutputSinkFile::ConstructL() - preparing default log..." ) );
       
    75     ConstructDefaultLogFileL();
       
    76 
       
    77     TRACE( RDebug::Printf( "CMemSpyEngineOutputSinkFile::ConstructL() - END" ) );
       
    78     }
       
    79 
       
    80 
       
    81 CMemSpyEngineOutputSinkFile* CMemSpyEngineOutputSinkFile::NewL( CMemSpyEngine& aEngine )
       
    82     {
       
    83     CMemSpyEngineOutputSinkFile* self = new(ELeave) CMemSpyEngineOutputSinkFile( aEngine );
       
    84     CleanupStack::PushL( self );
       
    85     self->ConstructL();
       
    86     CleanupStack::Pop( self );
       
    87     return self;
       
    88     }
       
    89 
       
    90 
       
    91 void CMemSpyEngineOutputSinkFile::ProcessSuspendedL( TProcessId aId )
       
    92     {
       
    93     TRACE( RDebug::Print( _L("CMemSpyEngineOutputSinkFile::ProcessSuspendedL() - START - aId: %d, iFileServerSuspended: %d, iFileServerProcessId: %d"), (TUint) aId, iFileServerSuspended, (TUint) iFileServerProcessId ) );
       
    94 
       
    95     iFileServerSuspended = ( (TUint) aId == iFileServerProcessId );
       
    96     if  ( iFileServerSuspended )
       
    97         {
       
    98         const TInt count = iLogs.Count();
       
    99         TRACE( RDebug::Print( _L("CMemSpyEngineOutputSinkFile::ProcessSuspendedL() - enabling buffers for %d logs"), count ) );
       
   100         for( TInt i=0; i<count; i++ )
       
   101             {
       
   102             CMemSpyEngineFileHolder* log = iLogs[i];
       
   103             log->EnableBufferL();
       
   104             }
       
   105         }
       
   106 
       
   107     TRACE( RDebug::Print( _L("CMemSpyEngineOutputSinkFile::ProcessSuspendedL() - END - aId: %d, iFileServerSuspended: %d"), (TUint) aId, iFileServerSuspended ) );
       
   108     }
       
   109 
       
   110 
       
   111 void CMemSpyEngineOutputSinkFile::ProcessResumed( TProcessId aId )
       
   112     {
       
   113     const TBool isF32Process = ( (TUint) aId == iFileServerProcessId );
       
   114     TRACE( RDebug::Print( _L("CMemSpyEngineOutputSinkFile::ProcessResumed() - START - aId: %d, iFileServerSuspended: %d, isF32Process: %d"), (TUint) aId, iFileServerSuspended, isF32Process ) );
       
   115     //
       
   116     if  ( iFileServerSuspended )
       
   117         {
       
   118         __ASSERT_ALWAYS( isF32Process, User::Invariant() );
       
   119 
       
   120         TRAPD( err, DisableAllBuffersAfterFileServerResumedL() );
       
   121         if ( err != KErrNone )
       
   122             {
       
   123             TRACE( RDebug::Printf( "CMemSpyEngineOutputSinkFile::ProcessResumed() - disabled all buffers, completed with err: %d", err ) );
       
   124             }
       
   125 
       
   126         iLogsPendingDestruction.ResetAndDestroy();
       
   127         TRACE( RDebug::Printf( "CMemSpyEngineOutputSinkFile::ProcessResumed() - deleted all pending destruction logs..." ) );
       
   128 
       
   129         // Indicate file server is no longer suspended
       
   130         iFileServerSuspended = EFalse;
       
   131         }
       
   132     
       
   133     TRACE( RDebug::Print( _L("CMemSpyEngineOutputSinkFile::ProcessResumed() - END - aId: %d, iFileServerSuspended: %d, isF32Process: %d"), (TUint) aId, iFileServerSuspended, isF32Process ) );
       
   134     }
       
   135 
       
   136 
       
   137 TMemSpySinkType CMemSpyEngineOutputSinkFile::Type() const
       
   138     {
       
   139     return ESinkTypeFile;
       
   140     }
       
   141 
       
   142 
       
   143 void CMemSpyEngineOutputSinkFile::DataStreamBeginL( const TDesC& aContext, const TDesC& aFolder, const TDesC& aExtension )
       
   144     {
       
   145     DataStreamBeginL( aContext, aFolder, aExtension, ETrue );
       
   146     }
       
   147 
       
   148 
       
   149 void CMemSpyEngineOutputSinkFile::DataStreamBeginL( const TDesC& aContext, const TDesC& aFolder, const TDesC& aExtension, TBool aOverwrite )
       
   150     {
       
   151     DataStreamBeginL( aContext, aFolder, aExtension, aOverwrite, ETrue );
       
   152     }
       
   153 
       
   154 
       
   155 void CMemSpyEngineOutputSinkFile::DataStreamBeginL( const TDesC& aContext, const TDesC& aFolder, const TDesC& aExtension, TBool aOverwrite, TBool aUseTimeStamp )
       
   156     {
       
   157     CMemSpyEngineSinkMetaData* meta = CMemSpyEngineSinkMetaData::NewL( aContext, aFolder, aExtension, aOverwrite, aUseTimeStamp );
       
   158     CleanupStack::PushL( meta );
       
   159 
       
   160     TRACE( RDebug::Printf( "CMemSpyEngineOutputSinkFile::DataStreamBeginL() - START - log count: %d, iFileServerSuspended: %d", iLogs.Count(), iFileServerSuspended ) );
       
   161     //
       
   162     CMemSpyEngineFileHolder* log = NULL;
       
   163     if  ( iFileServerSuspended )
       
   164         {
       
   165         TRACE( RDebug::Printf( "CMemSpyEngineOutputSinkFile::DataStreamBeginL() - F32 SUSPENDED!" ) );
       
   166         log = CMemSpyEngineFileHolder::NewLogToRAML( *this, meta );
       
   167         }
       
   168     else
       
   169         {
       
   170         log = CMemSpyEngineFileHolder::NewL( *this, meta );
       
   171         }
       
   172     //
       
   173     TRACE( RDebug::Printf( "CMemSpyEngineOutputSinkFile::DataStreamBeginL() - log: 0x%08x", log ) );
       
   174     CleanupStack::Pop( meta );
       
   175     CleanupStack::PushL( log );
       
   176     iLogs.AppendL( log );
       
   177     CleanupStack::Pop( log );
       
   178     //
       
   179     TRACE( RDebug::Print( _L("CMemSpyEngineOutputSinkFile::DataStreamBeginL() - END - log count: %d, iFileServerSuspended: %d, fileName: [%S]"), iLogs.Count(), iFileServerSuspended, &log->FileName() ) );
       
   180     }
       
   181 
       
   182 
       
   183 void CMemSpyEngineOutputSinkFile::DataStreamEndL()
       
   184     {
       
   185     const TInt count = iLogs.Count();
       
   186     TRACE( RDebug::Printf( "CMemSpyEngineOutputSinkFile::DataStreamEndL() - count: %d", count ) );
       
   187 
       
   188     __ASSERT_ALWAYS( count > 1, User::Invariant() );
       
   189 
       
   190     CMemSpyEngineFileHolder* headLog = iLogs[ count - 1 ];
       
   191     iLogs.Remove( count - 1 );
       
   192     TRACE( RDebug::Printf( "CMemSpyEngineOutputSinkFile::DataStreamEndL() - headLog: 0x%08x", headLog ) );
       
   193 
       
   194     if  ( headLog->UsingBuffer() )
       
   195         {
       
   196         TRACE( RDebug::Printf( "CMemSpyEngineOutputSinkFile::DataStreamEndL() - headLog is using buffer so doing deferred delete when F32 is not suspended anymore..." ) );
       
   197 
       
   198         // Must save the log until after its safe to resume 
       
   199         // writing to disk.
       
   200         CleanupStack::PushL( headLog );
       
   201         iLogsPendingDestruction.AppendL( headLog );
       
   202         CleanupStack::Pop( headLog );
       
   203         }
       
   204     else
       
   205         {
       
   206         TRACE( RDebug::Printf( "CMemSpyEngineOutputSinkFile::DataStreamEndL() - deleting head log immediately!" ) );
       
   207         delete headLog;
       
   208         }
       
   209 
       
   210     TRACE( RDebug::Printf( "CMemSpyEngineOutputSinkFile::DataStreamEndL() - END" ) );
       
   211     }
       
   212 
       
   213 
       
   214 void CMemSpyEngineOutputSinkFile::DoOutputLineL( const TDesC& aLine )
       
   215     {
       
   216     HeadLog().WriteLineL( aLine );
       
   217     }
       
   218 
       
   219 
       
   220 void CMemSpyEngineOutputSinkFile::DoOutputRawL( const TDesC8& aData )
       
   221     {
       
   222     HeadLog().WriteRawL( aData );
       
   223     }
       
   224 
       
   225 
       
   226 TBool CMemSpyEngineOutputSinkFile::IsPrefixAllowed( const TDesC& /*aPrefix*/ )
       
   227     {
       
   228     // If we are outputting to the main log, then we must allow
       
   229     // the prefix. If we are outputting to a child log, then we don't
       
   230     // need it.
       
   231     return HeadLog().IsMainLog();
       
   232     }
       
   233 
       
   234 
       
   235 void CMemSpyEngineOutputSinkFile::ConstructDefaultLogFileL()
       
   236     {
       
   237     CMemSpyEngineFileHolder* log = CMemSpyEngineFileHolder::NewLC( *this );
       
   238 
       
   239     TRACE( RDebug::Printf( "CMemSpyEngineOutputSinkFile::ConstructDefaultLogFileL() - START - headLog: 0x%08x", log ) );
       
   240     iLogs.AppendL( log );
       
   241     CleanupStack::Pop( log );
       
   242 
       
   243     TRACE( RDebug::Printf( "CMemSpyEngineOutputSinkFile::ConstructDefaultLogFileL() - END - headLog: 0x%08x", log ) );
       
   244     }
       
   245 
       
   246 
       
   247 void CMemSpyEngineOutputSinkFile::DisableAllBuffersAfterFileServerResumedL()
       
   248     {
       
   249     const TInt count = iLogs.Count();
       
   250     const TInt count2 = iLogsPendingDestruction.Count();
       
   251 
       
   252     TRACE( RDebug::Printf( "CMemSpyEngineOutputSinkFile::DisableAllBuffersAfterFileServerResumedL() - START - logs: %d, pending: %d", count, count2 ) );
       
   253 
       
   254     TInt err = KErrNone;
       
   255 
       
   256     // Inform logging object that they should stop logging to RAM. This may cause files
       
   257     // to be opened and data flushed.
       
   258     for( TInt i=0; i<count; i++ )
       
   259         {
       
   260         CMemSpyEngineFileHolder* log = iLogs[ i ];
       
   261         TRACE( RDebug::Print( _L("CMemSpyEngineOutputSinkFile::DisableAllBuffersAfterFileServerResumedL() -  logN[%2d]: 0x%08x, name: %S"), i, log, &log->FileName() ) );
       
   262         TRAP(err, log->DisableBufferL() );
       
   263         if  ( err != KErrNone )
       
   264             {
       
   265             TRACE( RDebug::Printf( "CMemSpyEngineOutputSinkFile::DisableAllBuffersAfterFileServerResumedL() - error whilst closing log: %d", err ) );
       
   266             }
       
   267         }
       
   268 
       
   269     // Finalise any pending destruction log objects. These are log objects
       
   270     // that were created and finalised whilst the file server was suspended.
       
   271     for( TInt ii = count2-1; ii>=0; ii--)
       
   272         {
       
   273         CMemSpyEngineFileHolder* log = iLogsPendingDestruction[ ii ];
       
   274         TRACE( RDebug::Print( _L("CMemSpyEngineOutputSinkFile::DisableAllBuffersAfterFileServerResumedL() - logPD[%2d]: 0x%08x, name: %S"), ii, log, &log->FileName() ) );
       
   275         TRAP(err, log->DisableBufferL() );
       
   276         if  ( err != KErrNone )
       
   277             {
       
   278             TRACE( RDebug::Printf( "CMemSpyEngineOutputSinkFile::DisableAllBuffersAfterFileServerResumedL() - error whilst closing log: %d", err ) );
       
   279             }
       
   280         }
       
   281 
       
   282     TRACE( RDebug::Printf( "CMemSpyEngineOutputSinkFile::DisableAllBuffersAfterFileServerResumedL() - END" ) );
       
   283     }
       
   284 
       
   285 
       
   286 CMemSpyEngineFileHolder& CMemSpyEngineOutputSinkFile::HeadLog() const
       
   287     {
       
   288     // Head log is always the first log
       
   289     const TInt count = iLogs.Count();
       
   290     __ASSERT_ALWAYS( count >= 1, User::Invariant() );
       
   291     CMemSpyEngineFileHolder* headLog = iLogs[ count - 1 ];
       
   292 
       
   293     //TRACE( RDebug::Print( _L("CMemSpyEngineOutputSinkFile::HeadLog() - headLog: 0x%08x %S"), headLog, &headLog->FileName() ) );
       
   294     return *headLog;
       
   295     }
       
   296 
       
   297 
       
   298 
       
   299 
       
   300 
       
   301 
       
   302 
       
   303 
       
   304 
       
   305 
       
   306 
       
   307 
       
   308 
       
   309 
       
   310 
       
   311 
       
   312 
       
   313 
       
   314 
       
   315 
       
   316 
       
   317 
       
   318 
       
   319 
       
   320 
       
   321 
       
   322 
       
   323 
       
   324 
       
   325 
       
   326 
       
   327 
       
   328 
       
   329 
       
   330 
       
   331 
       
   332 
       
   333 
       
   334 
       
   335 CMemSpyEngineFileHolder::CMemSpyEngineFileHolder( CMemSpyEngineOutputSinkFile& aParent, CMemSpyEngineSinkMetaData* aMetaData )
       
   336 :   iParent( aParent ), iMetaData( aMetaData )
       
   337     {
       
   338     }
       
   339 
       
   340 
       
   341 CMemSpyEngineFileHolder::~CMemSpyEngineFileHolder()
       
   342     {
       
   343     TPtrC pFileName( KNullDesC );
       
   344     if  ( iFileName != NULL )
       
   345         {
       
   346         pFileName.Set( *iFileName );
       
   347         }
       
   348     TRACE( RDebug::Print( _L("CMemSpyEngineFileHolder::~CMemSpyEngineFileHolder() - START - this: 0x%08x, iFileName: %S, handle: 0x%08x, iEntireFileBuffer: 0x%08x, iIsMainLog: %d"), this, &pFileName, iFile.SubSessionHandle(), iEntireFileBuffer, iIsMainLog ) );
       
   349 
       
   350     if  ( iEntireFileBuffer || iWorkingBuffer )
       
   351         {
       
   352         // This may actually open the file
       
   353         TRACE( RDebug::Printf( "CMemSpyEngineFileHolder::~CMemSpyEngineFileHolder() - disabling file buffers..." ) );
       
   354         TRAP_IGNORE( DisableBufferL() );
       
   355         }
       
   356 
       
   357     // Now close the file, deleting anything that is empty
       
   358     if  ( iFile.SubSessionHandle() != KNullHandle )
       
   359         {
       
   360         TRACE( RDebug::Printf( "CMemSpyEngineFileHolder::~CMemSpyEngineFileHolder() - flushing file..." ) );
       
   361 
       
   362         // Flush anything that is pending and then check whether 
       
   363         // the file is empty. If so, delete it.
       
   364         iFile.Flush(); // Ignore error
       
   365        
       
   366         // Delete empty files
       
   367         TInt size = 0;
       
   368         TInt err = iFile.Size( size );
       
   369         TRACE( RDebug::Printf( "CMemSpyEngineFileHolder::~CMemSpyEngineFileHolder() - size: %d, err: %d", size, err ) );
       
   370 
       
   371         if  ( err == KErrNone && size == 0 )
       
   372             {
       
   373             // Close the file and get F32 to delete it...
       
   374             TRACE( RDebug::Printf( "CMemSpyEngineFileHolder::~CMemSpyEngineFileHolder() - deleting empty file!" ) );
       
   375             iFile.Close();
       
   376             err = FsSession().Delete( *iFileName );
       
   377             TRACE( RDebug::Printf( "CMemSpyEngineFileHolder::~CMemSpyEngineFileHolder() - delete err: %d", err ) );
       
   378             }
       
   379         }
       
   380     //
       
   381     iFile.Close();
       
   382     //
       
   383     delete iLineBuffer;
       
   384     delete iWorkingBuffer;
       
   385     delete iEntireFileBuffer;
       
   386     TRACE( RDebug::Print( _L("CMemSpyEngineFileHolder::~CMemSpyEngineFileHolder() - END - this: 0x%08x, iFileName: %S, iIsMainLog: %d"), this, &pFileName, iIsMainLog ) );
       
   387     delete iFileName;
       
   388     delete iMetaData;
       
   389     }
       
   390 
       
   391 
       
   392 void CMemSpyEngineFileHolder::CommonConstructL()
       
   393     {
       
   394     if  ( iLineBuffer == NULL )
       
   395         {
       
   396         iLineBuffer = HBufC8::NewL( KMemSpyLineBufferLength );
       
   397         }
       
   398     if  ( iWorkingBuffer == NULL )
       
   399         {
       
   400         iWorkingBuffer = CBufFlat::NewL( KMemSpyFileServerBufferExpandSize );
       
   401         }
       
   402     }
       
   403 
       
   404 
       
   405 void CMemSpyEngineFileHolder::ConstructL()
       
   406     {
       
   407     TRACE( RDebug::Printf( "CMemSpyEngineFileHolder::ConstructL(D) - START" ) );
       
   408     iIsMainLog = ETrue;
       
   409 
       
   410     // Make emtpy meta data
       
   411     ASSERT( !iMetaData );
       
   412     iMetaData = CMemSpyEngineSinkMetaData::NewL( KNullDesC, KNullDesC, KNullDesC, ETrue, ETrue );
       
   413 
       
   414     // Prepare common details
       
   415     CommonConstructL();
       
   416     TRACE( RDebug::Printf( "CMemSpyEngineFileHolder::ConstructL(D) - CommonConstructL() completed okay..." ) );
       
   417 
       
   418     // Construct the default log file.
       
   419     TRACE( RDebug::Printf( "CMemSpyEngineFileHolder::ConstructL(D) - calling OpenFileL()..." ) );
       
   420     OpenFileL();
       
   421     TRACE( RDebug::Printf( "CMemSpyEngineFileHolder::ConstructL(D) - called OpenFileL()" ) );
       
   422 
       
   423     TRACE( RDebug::Printf( "CMemSpyEngineFileHolder::ConstructL(D) - END - iIsMainLog: %d", iIsMainLog ) );
       
   424     }
       
   425 
       
   426 
       
   427 
       
   428 CMemSpyEngineFileHolder* CMemSpyEngineFileHolder::NewLC( CMemSpyEngineOutputSinkFile& aParent )
       
   429     {
       
   430     TRACE( RDebug::Printf( "CMemSpyEngineFileHolder::NewLC() - START") );
       
   431     CMemSpyEngineFileHolder* self = new(ELeave) CMemSpyEngineFileHolder( aParent, NULL );
       
   432     CleanupStack::PushL( self );
       
   433     self->ConstructL();
       
   434     return self;
       
   435     }
       
   436 
       
   437 
       
   438 CMemSpyEngineFileHolder* CMemSpyEngineFileHolder::NewL( CMemSpyEngineOutputSinkFile& aParent, CMemSpyEngineSinkMetaData* aMetaData )
       
   439     {
       
   440     TRACE( RDebug::Printf( "CMemSpyEngineFileHolder::NewL() - START") );
       
   441     CMemSpyEngineFileHolder* self = new(ELeave) CMemSpyEngineFileHolder( aParent, aMetaData );
       
   442     CleanupStack::PushL( self );
       
   443     self->CommonConstructL();
       
   444     self->OpenFileL();
       
   445     CleanupStack::Pop( self );
       
   446     return self;
       
   447     }
       
   448 
       
   449 
       
   450 CMemSpyEngineFileHolder* CMemSpyEngineFileHolder::NewLogToRAML( CMemSpyEngineOutputSinkFile& aParent, CMemSpyEngineSinkMetaData* aMetaData )
       
   451     {
       
   452     TRACE( RDebug::Printf( "CMemSpyEngineFileHolder::NewLogToRAML() - START") );
       
   453     CMemSpyEngineFileHolder* self = new(ELeave) CMemSpyEngineFileHolder( aParent, aMetaData );
       
   454     CleanupStack::PushL( self );
       
   455     self->CommonConstructL();
       
   456     self->EnableBufferL();
       
   457     CleanupStack::Pop( self );
       
   458     return self;
       
   459     }
       
   460 
       
   461 
       
   462 void CMemSpyEngineFileHolder::OpenFileL()
       
   463     {
       
   464     TInt err = KErrNone;
       
   465 
       
   466     TRACE( RDebug::Printf( "CMemSpyEngineFileHolder::OpenFileL() - START - iMetaData: 0x%08x", iMetaData ) );
       
   467     ASSERT( iMetaData );
       
   468 
       
   469     delete iFileName;
       
   470     iFileName = NULL;
       
   471     if  ( iFile.SubSessionHandle() != KNullHandle )
       
   472         {
       
   473         TRACE( RDebug::Printf( "CMemSpyEngineFileHolder::OpenFileL() - closing existing file..." ) );
       
   474         iFile.Flush();
       
   475         iFile.Close();
       
   476         }
       
   477     
       
   478     // First try, with current external drive
       
   479     TRAP( err, PrepareFileL() );
       
   480     TRACE( RDebug::Printf( "CMemSpyEngineFileHolder::OpenFileL() - PrepareFileL(1) - err: %d", err ) );
       
   481     
       
   482     if  ( err != KErrNone )
       
   483         {
       
   484         TRACE( RDebug::Printf( "CMemSpyEngineFileHolder::OpenFileL() - trying with forced C:\\ ..." ) );
       
   485 
       
   486         // Try again with C:\ instead...
       
   487         const TDriveNumber cDrive = EDriveC;
       
   488         TRAP(err, PrepareFileL( &cDrive ) );
       
   489         TRACE( RDebug::Printf( "CMemSpyEngineFileHolder::OpenFileL() - PrepareFileL(2) - err: %d", err ) );
       
   490         }
       
   491 
       
   492     TRACE( RDebug::Printf( "CMemSpyEngineFileHolder::OpenFileL() - final err: %d", err ) );
       
   493     User::LeaveIfError( err );
       
   494 
       
   495     TRACE( RDebug::Printf( "CMemSpyEngineFileHolder::OpenFileL() - END - OK - iIsMainLog: %d", iIsMainLog ) );
       
   496     }
       
   497 
       
   498 
       
   499 void CMemSpyEngineFileHolder::PrepareFileL( const TDriveNumber* aForceDrive )
       
   500     {
       
   501     TRACE( RDebug::Printf( "CMemSpyEngineFileHolder::PrepareFileL() - START - this: 0x%08x", this ) );
       
   502     ASSERT( iMetaData );
       
   503 
       
   504     iFileName = GenerateFileNameLC( aForceDrive );
       
   505     CleanupStack::Pop( iFileName );
       
   506 
       
   507     // Try to make log directory - ignore if already exists
       
   508     TInt error = FsSession().MkDirAll( *iFileName );
       
   509     TRACE( RDebug::Print( _L("CMemSpyEngineFileHolder::PrepareFileL() - iFileName: %S, mkDir: %d, aOverwrite: %d"), iFileName, error, iMetaData->Overwrite() ) );
       
   510 
       
   511     if  ( error == KErrNone || error == KErrAlreadyExists )
       
   512         {
       
   513         if  ( iMetaData->Overwrite() )
       
   514             {
       
   515             error = iFile.Replace( FsSession(), *iFileName, EFileWrite );
       
   516             TRACE( RDebug::Printf( "CMemSpyEngineFileHolder::PrepareFileL() - overwrite/replace error: %d", error ) );
       
   517             }
       
   518         else
       
   519             {
       
   520             error = iFile.Open( FsSession(), *iFileName, EFileWrite );
       
   521             TRACE( RDebug::Printf( "CMemSpyEngineFileHolder::PrepareFileL() - open error: %d", error ) );
       
   522             
       
   523             // Try creating it then...
       
   524             if  ( error == KErrNotFound )
       
   525                 {
       
   526                 error = iFile.Create( FsSession(), *iFileName, EFileWrite );
       
   527                 TRACE( RDebug::Printf( "CMemSpyEngineFileHolder::PrepareFileL() - create error: %d", error ) );
       
   528                 }
       
   529             }
       
   530             
       
   531         // Seek to end of file
       
   532         TRACE( RDebug::Printf( "CMemSpyEngineFileHolder::PrepareFileL() - final error: %d", error ) );
       
   533         if  ( error == KErrNone )
       
   534             {
       
   535             TInt pos = 0;
       
   536             error = iFile.Seek( ESeekEnd, pos );
       
   537             TRACE( RDebug::Printf( "CMemSpyEngineFileHolder::PrepareFileL() - seek error: %d", error ) );
       
   538             }
       
   539         }
       
   540 
       
   541     TRACE( RDebug::Printf( "CMemSpyEngineFileHolder::PrepareFileL() - END - this: 0x%08x, error: %d", this, error ) );
       
   542     User::LeaveIfError( error );
       
   543     }
       
   544 
       
   545 
       
   546 void CMemSpyEngineFileHolder::WriteLineL( const TDesC& aData )
       
   547     {
       
   548     TPtr8 pText( iLineBuffer->Des() );
       
   549     pText.Copy( aData );
       
   550     pText.Append( KMemSpyCRLF );
       
   551 
       
   552     if  ( iWorkingBuffer != NULL )
       
   553         {
       
   554         AddToWorkingBufferL( pText );
       
   555         }
       
   556     else if ( iFile.SubSessionHandle() != KNullHandle )
       
   557         {
       
   558         const TInt error = iFile.Write( pText );
       
   559         if  ( error != KErrNone )
       
   560             {
       
   561             TRACE( RDebug::Printf( "CMemSpyEngineFileHolder::WriteLineL() - FILE WRITE ERROR - this: 0x%08x, error: %d", this, error ) );
       
   562             }
       
   563         User::LeaveIfError( error );
       
   564         }
       
   565     else
       
   566         {
       
   567         TRACE( RDebug::Printf( "CMemSpyEngineFileHolder::WriteLineL() - DISCARDING LINE!" ) );
       
   568         }
       
   569     }
       
   570 
       
   571 
       
   572 void CMemSpyEngineFileHolder::WriteRawL( const TDesC8& aData )
       
   573     {
       
   574     const TInt error = iFile.Write( aData );
       
   575     User::LeaveIfError( error );
       
   576     }
       
   577 
       
   578 
       
   579 void CMemSpyEngineFileHolder::EnableBufferL()
       
   580     {
       
   581     TRACE( RDebug::Printf( "CMemSpyEngineFileHolder::EnableBufferL() - START - this: 0x%08x", this ) );
       
   582     if  ( iEntireFileBuffer == NULL )
       
   583         {
       
   584         iEntireFileBuffer = CBufFlat::NewL( KMemSpyFileServerBufferExpandSize );
       
   585         }
       
   586     //
       
   587     iEntireFileBuffer->Reset();
       
   588     TRACE( RDebug::Printf( "CMemSpyEngineFileHolder::EnableBufferL() - END - this: 0x%08x", this ) );
       
   589     }
       
   590 
       
   591 
       
   592 void CMemSpyEngineFileHolder::DisableBufferL()
       
   593     {
       
   594 #ifdef _DEBUG
       
   595     TInt size = 0;
       
   596     if  ( iFile.SubSessionHandle() != KNullHandle )
       
   597         {
       
   598         iFile.Size( size );
       
   599         }
       
   600     TInt ramBufferSize = 0;
       
   601     if  ( iEntireFileBuffer )
       
   602         {
       
   603         ramBufferSize = iEntireFileBuffer->Size();
       
   604         }
       
   605     //
       
   606     RDebug::Printf( "CMemSpyEngineFileHolder::DisableBufferL() - START - file handle: 0x%08x, iEntireFileBuffer: 0x%08x, fileSize: %d, ramBufferSize: %d", iFile.SubSessionHandle(), iEntireFileBuffer, size, ramBufferSize );
       
   607 #endif
       
   608 
       
   609     // This will also open the file if necessary
       
   610     FlushWorkingBufferL();
       
   611     //
       
   612     if  ( iEntireFileBuffer != NULL )
       
   613         {
       
   614         // Probably need to open the file...
       
   615         if  ( iFile.SubSessionHandle() == KNullHandle )
       
   616             {
       
   617             TRACE( RDebug::Printf( "CMemSpyEngineFileHolder::DisableBufferL() - FILE IS NOT YET OPEN!" ) );
       
   618             OpenFileL();
       
   619             TRACE( RDebug::Printf( "CMemSpyEngineFileHolder::DisableBufferL() - file opened okay." ) );
       
   620             }
       
   621 
       
   622         TRACE( RDebug::Print( _L("CMemSpyEngineFileHolder::DisableBufferL() - about to write entire file buffer - file: %S"), &FileName() ) );
       
   623         const TPtr8 pBuffer( iEntireFileBuffer->Ptr( 0 ) );
       
   624         const TInt error = iFile.Write( pBuffer );
       
   625         TRACE( RDebug::Printf( "CMemSpyEngineFileHolder::DisableBufferL() - write result: %d", error ) );
       
   626         //
       
   627         delete iEntireFileBuffer;
       
   628         iEntireFileBuffer = NULL;
       
   629         //
       
   630         User::LeaveIfError( error );
       
   631         }
       
   632     
       
   633     TRACE( RDebug::Printf( "CMemSpyEngineFileHolder::DisableBufferL() - END" ) );
       
   634     }
       
   635 
       
   636 
       
   637 void CMemSpyEngineFileHolder::FlushWorkingBufferL()
       
   638     {
       
   639     TRACE( RDebug::Print( _L("CMemSpyEngineFileHolder::FlushWorkingBufferL() - START - fileName: [%S], file handle: 0x%08x, iWorkingBuffer: 0x%08x"), &FileName(), iFile.SubSessionHandle(), iWorkingBuffer ) );
       
   640     __ASSERT_ALWAYS( iWorkingBuffer, MemSpyEngineUtils::Panic( EMemSpyEnginePanicSinkFileWorkingFileBufferIsNull ) );
       
   641 
       
   642     // The underlying file may not be open - it could be that we are buffering everything
       
   643     // to RAM (i.e. the file server is currently suspended).
       
   644     const TPtr8 pBuffer( iWorkingBuffer->Ptr(0) );
       
   645     //
       
   646     if  ( iEntireFileBuffer )
       
   647         {
       
   648         __ASSERT_ALWAYS( iEntireFileBuffer, MemSpyEngineUtils::Panic( EMemSpyEnginePanicSinkFileEntireFileBufferNull ) );
       
   649 
       
   650         TRACE( RDebug::Printf( "CMemSpyEngineFileHolder::FlushWorkingBufferL() - file not open or we are currently bufferring to RAM - copying %d bytes to entire file buffer (%d)", pBuffer.Length(), iEntireFileBuffer->Size() ) );
       
   651         iEntireFileBuffer->InsertL( iEntireFileBuffer->Size(), pBuffer );
       
   652         }
       
   653     else if ( iFile.SubSessionHandle() != KNullHandle )
       
   654         {
       
   655         const TInt error = iFile.Write( pBuffer );
       
   656         if  ( error != KErrNone )
       
   657             {
       
   658             TRACE( RDebug::Printf( "CMemSpyEngineFileHolder::FlushWorkingBufferL() - write result: %d", error ) );
       
   659             }
       
   660         User::LeaveIfError( error );
       
   661         }
       
   662 
       
   663     iWorkingBuffer->Reset();
       
   664     TRACE( RDebug::Print( _L("CMemSpyEngineFileHolder::FlushWorkingBufferL() - END - fileName: %S"), &FileName() ) );
       
   665     }
       
   666 
       
   667 
       
   668 void CMemSpyEngineFileHolder::AddToWorkingBufferL( const TDesC8& aText )
       
   669     {
       
   670     if  ( iWorkingBuffer->Size() + aText.Length() > KMemSpyFileServerBufferExpandSize )
       
   671         {
       
   672         FlushWorkingBufferL();
       
   673         }
       
   674     //
       
   675     iWorkingBuffer->InsertL( iWorkingBuffer->Size(), aText );
       
   676     }
       
   677 
       
   678 
       
   679 HBufC* CMemSpyEngineFileHolder::CleanContextInfoLC( const TDesC& aContext )
       
   680     {
       
   681     TRACE( RDebug::Print( _L("CMemSpyEngineFileHolder::CleanContextInfoLC() - START - %S"), &aContext ) );
       
   682     TFileName fileName;
       
   683 
       
   684     TBool seenDoubleColon = EFalse;
       
   685     const TInt length = aContext.Length();
       
   686     for( TInt i=0; i<length; i++ )
       
   687         {
       
   688         const TChar c( aContext[ i ] );
       
   689         const TBool haveNextChar = ( i+1 < length );
       
   690         //
       
   691         //TRACE( RDebug::Print( _L("CMemSpyEngineFileHolder::CleanContextInfoLC() - c[%03d]: \'%c\', haveNextChar: %d, seenDoubleColon: %d"), i, (TUint32) c, haveNextChar, seenDoubleColon ) );
       
   692         //
       
   693         if  ( c == ':' && haveNextChar && aContext[ i + 1 ] == ':' )
       
   694             {
       
   695             // Skip double colon
       
   696             i++;
       
   697             fileName.Append( '-' );
       
   698             seenDoubleColon = ETrue;
       
   699             }
       
   700         else if ( c == '.' )
       
   701             {
       
   702             if  ( seenDoubleColon )
       
   703                 {
       
   704                 break;
       
   705                 }
       
   706             else
       
   707                 {
       
   708                 fileName.Append( '-' );
       
   709                 }
       
   710             }
       
   711         else
       
   712             {
       
   713             fileName.Append( c );
       
   714             }
       
   715         }
       
   716 
       
   717     TRACE( RDebug::Print( _L("CMemSpyEngineFileHolder::CleanContextInfoLC() - END - %S"), &fileName ) );
       
   718     return fileName.AllocLC();
       
   719     }
       
   720 
       
   721 
       
   722 HBufC* CMemSpyEngineFileHolder::GenerateFileNameLC( const TDriveNumber* aForceDrive )
       
   723     {
       
   724     TFileName name;
       
   725     MemSpyEngineUtils::GetFolderL( FsSession(), name, *iMetaData, aForceDrive );
       
   726     return name.AllocLC();
       
   727     }
       
   728 
       
   729 
       
   730 RFs& CMemSpyEngineFileHolder::FsSession()
       
   731     {
       
   732     return iParent.iFsSession;
       
   733     }
       
   734 
       
   735 
       
   736 const TDesC& CMemSpyEngineFileHolder::FileName() const 
       
   737     {
       
   738     if  ( iFileName )
       
   739         {
       
   740         return *iFileName;
       
   741         }
       
   742     //
       
   743     return KNullDesC;
       
   744     }
       
   745