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