--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/emailservices/emaildebug/src/cmaillogger.cpp Thu Dec 17 08:39:21 2009 +0200
@@ -0,0 +1,200 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: commonemail file logger implementation
+*
+*/
+
+#include "cmaillogger.h"
+#include <e32std.h>
+
+_LIT( KLogFileExt, ".txt" );
+_LIT( KLogFileBaseName, "c:\\data\\cmail_" );
+
+// log file is replaced after certain amount of rows
+const TInt KLogFileMaxRowCount = 3000;
+
+#ifdef _DEBUG
+#define CMAILLOGGERTACE(x) {RDebug::Print(_L(x) );}
+#define CMAILLOGGERTACE2(x,y) {RDebug::Print(_L(x),y );}
+#else
+#define CMAILLOGGERTACE(x)
+#define CMAILLOGGERTACE2(x,y)
+#endif
+
+// local functions
+RFileWriteStream* File();
+
+void ReplaceIfSizeExceeded(LogFile& aLogFile );
+
+// ---------------------------------------------------------------------------
+// Exception handler that closes and renames current log file and passes
+// exception to original handler.
+// ---------------------------------------------------------------------------
+void LoggerExcHandler( TExcType aType )
+ {
+ CMAILLOGGERTACE2( "cmail exception handler %d", aType )
+ LogFile* logFile = reinterpret_cast<LogFile*>( Dll::Tls() );
+ TExceptionHandler storedExcHandler = NULL;
+ if ( logFile )
+ {
+ _LIT8( KExceptionText, "CMAIL catched exception %d \n" );
+ TBuf8<50> buf8;
+ buf8.Format( KExceptionText(), aType );
+ TRAP_IGNORE( logFile->iFile.WriteL( buf8 ) );
+ logFile->iFile.Close();
+
+ // rename file to prevent over writing
+ TBuf<100> newName;
+ TTime time;
+ time.HomeTime();
+ TDateTime dt = time.DateTime();
+ TInt pos = logFile->iFileName.Locate(TChar('.'));
+ if ( pos != KErrNotFound )
+ {
+ _LIT( KDateTimeFormat, "%C" ); // microsecond form
+ TBuf<20> timeBuf;
+ TRAP_IGNORE( time.FormatL( timeBuf, KDateTimeFormat() ) )
+ newName = logFile->iFileName.Left( pos );
+ newName.Append( timeBuf );
+ newName.Append( KLogFileExt() );
+ TInt err = logFile->iFs.Rename( logFile->iFileName, newName);
+ CMAILLOGGERTACE2( "CMAIL log file rename err=%d", err )
+ }
+
+ storedExcHandler = logFile->iHandler;
+ (*storedExcHandler)(aType);
+ }
+
+ }
+
+// ---------------------------------------------------------------------------
+// CmailLogger::Write
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CmailLogger::Write( const TDesC8& aData )
+{
+ RFileWriteStream* file = File();
+ if ( file /*&& file->SubSessionHandle() */)
+ {
+ TRAP_IGNORE(
+ {
+ file->WriteL( aData );
+ TBuf8<2> crLf;
+ crLf.Append( 13 );
+ crLf.Append( 10 );
+ file->WriteL( crLf );
+ } );
+ }
+}
+
+// ---------------------------------------------------------------------------
+// CmailLogger::Close
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CmailLogger::Close()
+{
+ CMAILLOGGERTACE("Cmaillogger Close")
+ TAny* tls = Dll::Tls();
+ if ( tls )
+ {
+ LogFile* logFile = reinterpret_cast<LogFile*>( tls );
+ logFile->iFile.Close();
+ logFile->iFs.Close();
+ logFile->iFileName.Zero();
+ User::SetExceptionHandler( logFile->iHandler,0xFFFFFFFF );
+ delete logFile;
+ Dll::SetTls( NULL );
+ }
+}
+
+// ---------------------------------------------------------------------------
+// Returns log file pointer. When called first time file handle container
+// LogFile is stored to TLS.
+// ---------------------------------------------------------------------------
+//
+RFileWriteStream* File()
+ {
+ CMAILLOGGERTACE("Cmaillogger File")
+ TAny* tls = Dll::Tls();
+ LogFile* logFile = NULL;
+ if ( !tls )
+ {
+ CMAILLOGGERTACE("Cmaillogger File no tls")
+ RThread t;
+ TName n = t.Name();
+ logFile = new LogFile;
+ if ( !logFile )
+ {
+ return NULL;
+ }
+ Dll::SetTls( logFile );
+ logFile->iThreadName.Copy( t.Name().Left(20));
+ logFile->iLinesWritten = KErrNotFound; // for ReplaceIfSizeExceeded()
+ TInt res = logFile->iFs.Connect();
+ CMAILLOGGERTACE2("Cmaillogger iFs.Connect res=%d", res )
+ ReplaceIfSizeExceeded( *logFile );
+
+ // store default exception handler pointer
+ logFile->iHandler = User::ExceptionHandler();
+
+ // set own exception handler (see above)
+ User::SetExceptionHandler( LoggerExcHandler,
+ KExceptionAbort |
+ KExceptionAbort |
+ KExceptionUserInterrupt |
+ KExceptionFault );
+ }
+ else
+ {
+ logFile = reinterpret_cast<LogFile*>( tls );
+ ReplaceIfSizeExceeded( *logFile );
+ logFile->iLinesWritten++;
+ if ( logFile->iLinesWritten % 100 == 0 )
+ { // flush every now and then to prevent loss of data if thread
+ // is paniced (exceptions like ke-3 are not a problem, they are
+ // catched by LoggerExcHandler).
+ TRAP_IGNORE( logFile->iFile.CommitL() )
+ }
+ }
+ return &logFile->iFile;
+ }
+
+// ---------------------------------------------------------------------------
+// ReplaceIfSizeExceeded
+// Replaces log file if determined log row count is exceeded.
+// ---------------------------------------------------------------------------
+//
+void ReplaceIfSizeExceeded( LogFile& aLogFile )
+ {
+ CMAILLOGGERTACE("Cmaillogger ReplaceIfSizeExceeded<")
+ if ( ( aLogFile.iLinesWritten >= KLogFileMaxRowCount ||
+ aLogFile.iLinesWritten < 0 ) && // initial creation
+ aLogFile.iFs.Handle() )
+ {
+ if ( !aLogFile.iFileName.Length() )
+ {
+ aLogFile.iFileName = KLogFileBaseName();
+ aLogFile.iFileName.Append( aLogFile.iThreadName );
+ aLogFile.iFileName.Append( KLogFileExt() );
+ }
+ aLogFile.iLinesWritten = 0;
+ aLogFile.iFile.Close();
+ CMAILLOGGERTACE2("Cmaillogger open file '%S'",&aLogFile.iFileName)
+ TInt res = aLogFile.iFile.Replace( aLogFile.iFs, aLogFile.iFileName,
+ EFileShareReadersOrWriters );
+ CMAILLOGGERTACE2("Cmaillogger open result=%d", res )
+ }
+ CMAILLOGGERTACE("Cmaillogger ReplaceIfSizeExceeded>")
+ }
+