testexecfw/stf/stffw/logger/STFLoggingServer/src/FileOutput.cpp
changeset 2 8bb370ba6d1d
equal deleted inserted replaced
1:bbd31066657e 2:8bb370ba6d1d
       
     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: This module contains implementation of CFileOutput 
       
    15 * class member functions.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include "FileOutput.h"
       
    22 
       
    23 // EXTERNAL DATA STRUCTURES
       
    24 // None
       
    25 
       
    26 // EXTERNAL FUNCTION PROTOTYPES  
       
    27 // None
       
    28 
       
    29 // CONSTANTS
       
    30 // None
       
    31 
       
    32 // MACROS
       
    33 // None
       
    34 //#define RDEBUG_FILEWRITECRASH(a) RDebug::Print(a)
       
    35 #define RDEBUG_FILEWRITECRASH(a)
       
    36 
       
    37 // LOCAL CONSTANTS AND MACROS
       
    38 // None
       
    39 
       
    40 // MODULE DATA STRUCTURES
       
    41 // None
       
    42 
       
    43 // LOCAL FUNCTION PROTOTYPES
       
    44 // None
       
    45 
       
    46 // FORWARD DECLARATIONS
       
    47 // None
       
    48 
       
    49 // ==================== LOCAL FUNCTIONS =======================================
       
    50 // None
       
    51 
       
    52 // ================= MEMBER FUNCTIONS =========================================
       
    53 
       
    54 /*
       
    55 -------------------------------------------------------------------------------
       
    56 
       
    57     Class: CFileOutput
       
    58 
       
    59     Method: CFileOutput
       
    60 
       
    61     Description: Default constructor
       
    62 
       
    63     C++ default constructor can NOT contain any code, that
       
    64     might leave.
       
    65 
       
    66     Parameters: TLoggerType aLoggerType: in: File type
       
    67                 TBool aWithTimeStamp: in: For timestamp
       
    68                 TBool aWithLineBreak: in: For line break
       
    69                 TBool aWithEventRanking: in: For events ranking to file
       
    70                 TBool aThreadIdToLogFile: in: Indicator to thread id adding to
       
    71                                               end of the log file
       
    72 
       
    73     Return Values: None
       
    74 
       
    75     Errors/Exceptions: None
       
    76 
       
    77     Status: Approved
       
    78 
       
    79 -------------------------------------------------------------------------------
       
    80 */
       
    81 CFileOutput::CFileOutput( CStifLogger::TLoggerType aLoggerType,
       
    82                             TBool aWithTimeStamp,
       
    83                             TBool aWithLineBreak,
       
    84                             TBool aWithEventRanking,
       
    85                             TBool aThreadIdToLogFile,
       
    86                             TInt aThreadId) :
       
    87     COutput()
       
    88     {
       
    89     // Indicates file type
       
    90     iLoggerType = aLoggerType;
       
    91 
       
    92     // Time stamp indicator
       
    93     iWithTimeStamp = aWithTimeStamp;
       
    94 
       
    95     // Line break indicator
       
    96     iWithLineBreak = aWithLineBreak;
       
    97 
       
    98     // Log event ranking indicator
       
    99     iWithEventRanking = aWithEventRanking;
       
   100 
       
   101     // Indicator to thread id adding to end of the log file
       
   102     iThreadIdToLogFile = aThreadIdToLogFile;
       
   103 
       
   104     // Is file open indicator
       
   105     iIsFileOpen = 0;
       
   106 
       
   107     // Thread id of test case thread. Get from client side when creating logger.
       
   108     iThreadId = aThreadId;
       
   109     }
       
   110 
       
   111 /*
       
   112 -------------------------------------------------------------------------------
       
   113 
       
   114     Class: CFileOutput
       
   115 
       
   116     Method: ConstructL
       
   117 
       
   118     Description: Symbian OS second phase constructor
       
   119 
       
   120     Symbian OS default constructor can leave.
       
   121 
       
   122     Parameters: const TDesC& aTestPath: in: Log path
       
   123                 const TDesC& aTestFile: in: Log filename
       
   124                 TBool aOverWrite: in: For file overwrite
       
   125                 TBool aCreateLogDir: in: Indicator to directory creation
       
   126                 TInt  aStaticBufferSize
       
   127                 TBool aUnicode: in: Indicator if file has to be in unicode format
       
   128 
       
   129     Return Values: None
       
   130 
       
   131     Errors/Exceptions:  Leaves if called CreateNewFileL method fails
       
   132                         Leaves if called OpenExistingFileL method fails
       
   133 
       
   134     Status: Proposal
       
   135 
       
   136 -------------------------------------------------------------------------------
       
   137 */
       
   138 void CFileOutput::ConstructL( const TDesC& aTestPath,
       
   139                                 const TDesC& aTestFile,
       
   140                                 TBool aOverWrite,
       
   141                                 TBool aCreateLogDir,
       
   142                                 TInt aStaticBufferSize,
       
   143                                 TBool aUnicode)
       
   144     {
       
   145     iUnicode = aUnicode;
       
   146 
       
   147     // Open file session
       
   148     User::LeaveIfError( iFileSession.Connect() );
       
   149 
       
   150     // Create a log directory
       
   151     if( aCreateLogDir )
       
   152         {
       
   153         CreateDirectoryL( aTestPath );
       
   154         }
       
   155 
       
   156     // Create a new file
       
   157     if ( aOverWrite )
       
   158         {
       
   159         CreateNewFileL( aTestPath, aTestFile );
       
   160         }
       
   161     // Open an existing file
       
   162     else 
       
   163         {
       
   164         OpenExistingFileL( aTestPath, aTestFile );
       
   165         }
       
   166         
       
   167     if( aStaticBufferSize != 0)
       
   168         {
       
   169         iDataHBuf8 = HBufC8::NewL( aStaticBufferSize );
       
   170         iDataHBuf16 = HBufC::NewL(aStaticBufferSize);
       
   171         iStaticBufferSize = aStaticBufferSize;
       
   172         }
       
   173     }
       
   174 
       
   175 /*
       
   176 -------------------------------------------------------------------------------
       
   177 
       
   178     Class: CFileOutput
       
   179 
       
   180     Method: NewL
       
   181 
       
   182     Description: Two-phased constructor.
       
   183 
       
   184     Parameters: const TDesC& aTestPath: in: Log path
       
   185                 const TDesC& aTestFile: in: Log filename
       
   186                 TLoggerType aLoggerType: in: File type
       
   187                 TBool aOverWrite: in: For file overwrite
       
   188                 TBool aWithTimeStamp: in: For timestamp
       
   189                 TBool aWithLineBreak: in: For line break
       
   190                 TBool aWithEventRanking: in: For events ranking to file
       
   191                 TBool aThreadIdToLogFile: in: Indicator to thread id adding to
       
   192                                               end of the log file
       
   193                 TBool aCreateLogDir: in: Indicator to directory creation
       
   194                 TInt  aStaticBufferSize
       
   195                 TBool aUnicode: in: Indicator if file has to be in unicode format
       
   196 
       
   197     Return Values: CFileOutput*: pointer to CFileOutput object
       
   198 
       
   199     Errors/Exceptions: Leaves if ConstructL leaves
       
   200 
       
   201     Status: Proposal
       
   202 
       
   203 -------------------------------------------------------------------------------
       
   204 */
       
   205 CFileOutput* CFileOutput::NewL( const TDesC& aTestPath,
       
   206                                 const TDesC& aTestFile,
       
   207                                 CStifLogger::TLoggerType aLoggerType,
       
   208                                 TBool aOverWrite,
       
   209                                 TBool aWithTimeStamp,
       
   210                                 TBool aWithLineBreak,
       
   211                                 TBool aWithEventRanking,
       
   212                                 TBool aThreadIdToLogFile,
       
   213                                 TBool aCreateLogDir,
       
   214                                 TInt  aStaticBufferSize,
       
   215                                 TBool aUnicode,
       
   216                                 TInt  aThreadId)
       
   217     {
       
   218     // Create CFileOutput object fileWriter
       
   219     CFileOutput* fileWriter = new (ELeave) CFileOutput( aLoggerType,
       
   220                                                         aWithTimeStamp,
       
   221                                                         aWithLineBreak,
       
   222                                                         aWithEventRanking,
       
   223                                                         aThreadIdToLogFile,
       
   224                                                         aThreadId);
       
   225 
       
   226     CleanupStack::PushL( fileWriter );
       
   227     fileWriter->ConstructL( aTestPath, aTestFile, aOverWrite, aCreateLogDir, aStaticBufferSize,
       
   228                             aUnicode );
       
   229     CleanupStack::Pop( fileWriter );
       
   230 
       
   231     return fileWriter;
       
   232 
       
   233     }
       
   234 
       
   235 /*
       
   236 -------------------------------------------------------------------------------
       
   237 
       
   238     Class: CFileOutput
       
   239 
       
   240     Method: ~CFileOutput
       
   241 
       
   242     Description: Destructor
       
   243 
       
   244     Parameters: None
       
   245 
       
   246     Return Values: None
       
   247 
       
   248     Errors/Exceptions: None
       
   249 
       
   250     Status: Approved
       
   251 
       
   252 -------------------------------------------------------------------------------
       
   253 */
       
   254 CFileOutput::~CFileOutput()
       
   255     {
       
   256     // Close file
       
   257     iFile.Close();
       
   258     // Close file session
       
   259     iFileSession.Close();
       
   260 
       
   261     delete iDataHBuf8;
       
   262     delete iDataHBuf16;
       
   263     }
       
   264 
       
   265 /*
       
   266 -------------------------------------------------------------------------------
       
   267 
       
   268     Class: CFileOutput
       
   269 
       
   270     Method: FileType
       
   271 
       
   272     Description: Check file type.
       
   273 
       
   274     Check is file type set with a aTestFile's name. If file type is not set
       
   275     the type will set according to StifLogger's type.
       
   276 
       
   277     Parameters: const TDesC& aTestFile: in: Log filename
       
   278                 TFileType& fileType: inout: Generated file type
       
   279 
       
   280     Return Values: None
       
   281 
       
   282     Errors/Exceptions: None
       
   283 
       
   284     Status: Approved
       
   285 
       
   286 -------------------------------------------------------------------------------
       
   287 */    
       
   288 void CFileOutput::FileType( const TDesC& aTestFile,
       
   289                             TFileType& aFileType )
       
   290     {
       
   291     TBool fileTypeIsSet( EFalse ); // File type indicator
       
   292 
       
   293     // Check is file type set to aTestFile parameter
       
   294     TInt ret = aTestFile.Find( _L( "." ) );
       
   295     if( ret != KErrNotFound )
       
   296         {
       
   297         fileTypeIsSet = ETrue;
       
   298         }
       
   299     // If not, add thread id name if allowed
       
   300     else if ( iThreadIdToLogFile )
       
   301         {
       
   302         // Thread id maximum length is 8 in hexadesimal format
       
   303         // Construct unique thread name
       
   304         aFileType.Append( _L("_") );
       
   305 
       
   306         // Appends id in hexadesimal format             
       
   307         aFileType.AppendFormat( _L( "%x" ), iThreadId );
       
   308         }
       
   309 
       
   310     // Add file type after the thread id name
       
   311     if ( iLoggerType == CStifLogger::ETxt && !fileTypeIsSet )
       
   312         {
       
   313         // ".txt"
       
   314         aFileType.Append( _L( "." ) );
       
   315         aFileType.Append( _L( "txt" ) );
       
   316         }
       
   317     else if ( iLoggerType == CStifLogger::EHtml && !fileTypeIsSet )
       
   318         {
       
   319         // ".html"
       
   320         aFileType.Append( _L( "." ) );
       
   321         aFileType.Append( _L( "html" ) );
       
   322         }
       
   323     // EData file type comes from the aTestFile name. If not the file type 
       
   324     // will be empty
       
   325     else if ( iLoggerType == CStifLogger::EData )
       
   326         {
       
   327         aFileType.Append( _L( "" ) );
       
   328         }
       
   329     else
       
   330         {
       
   331         aFileType.Append( _L( "" ) );
       
   332         }
       
   333 
       
   334     }
       
   335 
       
   336 /*
       
   337 -------------------------------------------------------------------------------
       
   338 
       
   339     Class: CFileOutput
       
   340 
       
   341     Method: TestFileWithThreadId
       
   342 
       
   343     Description: Generate thread id
       
   344 
       
   345     Generate thread id name between the test file name and test file type.
       
   346 
       
   347     Parameters: TDesC& aTestFile: in: Test file name
       
   348                 TFileName& aNewTestFile: inout: Generated test file name 
       
   349 
       
   350     Return Values: None
       
   351 
       
   352     Errors/Exceptions: None
       
   353 
       
   354     Status: Approved
       
   355 
       
   356 -------------------------------------------------------------------------------
       
   357 */
       
   358 void CFileOutput::TestFileWithThreadId( const TDesC& aTestFile, 
       
   359                                         TFileName& aNewTestFile )
       
   360     {
       
   361     for( TInt a = 0; a < aTestFile.Length(); a++ )
       
   362         {
       
   363         // Find a dot
       
   364         if( aTestFile[a] == '.' )
       
   365             {
       
   366             TPtrC parsedFileType = aTestFile.Mid( a );  // Take rest of the 
       
   367                                                         // aTestFile
       
   368             aNewTestFile.Append( _L( "_" ) );
       
   369 
       
   370             aNewTestFile.AppendFormat( _L( "%x" ), iThreadId );// Appends id in
       
   371                                                         // hexadesimal format
       
   372             aNewTestFile.Append( parsedFileType );
       
   373             break;
       
   374             }
       
   375         // Dot not found yet
       
   376         else
       
   377             {
       
   378             aNewTestFile.Append( aTestFile[a] );
       
   379             }
       
   380         }
       
   381 
       
   382     }
       
   383 
       
   384 /*
       
   385 -------------------------------------------------------------------------------
       
   386 
       
   387     Class: CFileOutput
       
   388 
       
   389     Method: CreateDirectoryL
       
   390 
       
   391     Description: Create a log directory.
       
   392 
       
   393     Method creates directory if not allready exist.
       
   394 
       
   395     Parameters: const TDesC& aTestPath: in: Test path definition
       
   396 
       
   397     Return Values: None
       
   398 
       
   399     Errors/Exceptions: Leaves if directory creation fails
       
   400 
       
   401     Status: Proposal
       
   402 
       
   403 -------------------------------------------------------------------------------
       
   404 */
       
   405 void CFileOutput::CreateDirectoryL( const TDesC& aTestPath )
       
   406     {
       
   407     __TRACE( KInfo, ( _L( "STIFLOGGER: Create a directory" ) ) );
       
   408 
       
   409     TInt ret = iFileSession.MkDirAll( aTestPath );
       
   410 	if( ret != KErrNone && ret != KErrAlreadyExists )
       
   411         {
       
   412         __TRACE( KError, 
       
   413             ( _L( "STIFLOGGER: Directory creation fails with error: %d" ), ret ) );
       
   414 		User::Leave( ret );
       
   415         }
       
   416 
       
   417     }
       
   418 
       
   419 /*
       
   420 -------------------------------------------------------------------------------
       
   421 
       
   422     Class: CFileOutput
       
   423 
       
   424     Method: OpenExistingFileL
       
   425 
       
   426     Description: Open an existing file.
       
   427 
       
   428     Method is used when is need for log new information after the existing
       
   429     log file.
       
   430 
       
   431     Parameters: const TDesC& aTestPath: in: Test path definition
       
   432                 const TDesC& aTestFile: in: Test file name
       
   433 
       
   434     Return Values: None
       
   435 
       
   436     Errors/Exceptions:  Leaves if path or file lengths are over KMaxFileName
       
   437                         Leaves if file Replace method fails
       
   438                         Leaves if file Open method fails
       
   439                         Leaves if file path not found
       
   440 
       
   441     Status: Proposal
       
   442 
       
   443 -------------------------------------------------------------------------------
       
   444 */
       
   445 void CFileOutput::OpenExistingFileL( const TDesC& aTestPath, 
       
   446                                         const TDesC& aTestFile )
       
   447     {
       
   448     __TRACE( KInfo, ( _L( "STIFLOGGER: Opening an existing file for logging" ) ) );
       
   449 
       
   450     // If path and file name lengths are over KMaxFileName(TFileName)
       
   451     __ASSERT_ALWAYS(
       
   452         ( aTestPath.Length() + aTestFile.Length() ) < KMaxFileName,
       
   453         User::Leave( KErrArgument ) );
       
   454 
       
   455     // Check file type and generate threat id name
       
   456     TFileType fileType;
       
   457     FileType( aTestFile, fileType );
       
   458 
       
   459     // File directory name, file name and file type definitions
       
   460     TPtrC dirNamePrt( aTestPath );
       
   461     iFileAndDirName.Copy( dirNamePrt );
       
   462 
       
   463     TInt isDotFound = aTestFile.Find( _L( "." ) );
       
   464     // If dot is found and iThreadIdToLogFile is true
       
   465     if( isDotFound != KErrNotFound && iThreadIdToLogFile )
       
   466         {
       
   467         TFileName testFileWithThreadId;
       
   468         // Generate thread id name
       
   469         TestFileWithThreadId( aTestFile, testFileWithThreadId );
       
   470         iFileAndDirName.Insert( 
       
   471             iFileAndDirName.Length(), testFileWithThreadId );
       
   472         }
       
   473     else
       
   474         {
       
   475         TPtrC txtPrt( fileType );
       
   476         iFileAndDirName.Insert( iFileAndDirName.Length(), aTestFile );
       
   477         iFileAndDirName.Insert( iFileAndDirName.Length(), txtPrt );
       
   478         }
       
   479 
       
   480     TInt ret( KErrNone );
       
   481 
       
   482     iIsFileOpen =iFile.Open( iFileSession, iFileAndDirName,
       
   483             EFileWrite | EFileStreamText |
       
   484                     EFileShareAny );
       
   485     if( iIsFileOpen == KErrNotFound )
       
   486         {
       
   487         ret =  iFile.Create( iFileSession, iFileAndDirName, 
       
   488                                     EFileWrite | EFileStreamText |
       
   489                                     EFileShareAny );
       
   490         if(iUnicode && ret == KErrNone)
       
   491             {
       
   492             char FF = 0xFF;
       
   493             char FE = 0xFE;
       
   494             TBuf8<2> beg;
       
   495             beg.Append(FF);
       
   496             beg.Append(FE);
       
   497             if(iFile.Write(beg) == KErrNone)
       
   498                 iFile.Flush();
       
   499             }
       
   500         }
       
   501     else if( iIsFileOpen == KErrNone )
       
   502         {
       
   503         ret = KErrNone;
       
   504         }
       
   505     // Probably path not found
       
   506     else
       
   507         {
       
   508         User::Leave( iIsFileOpen );
       
   509         }
       
   510 
       
   511     if ( ret != KErrNone )
       
   512         {
       
   513         User::Leave( ret );
       
   514         }
       
   515 
       
   516     }
       
   517 
       
   518 /*
       
   519 -------------------------------------------------------------------------------
       
   520 
       
   521     Class: CFileOutput
       
   522 
       
   523     Method: CreateNewFileL
       
   524 
       
   525     Description: Create a new file.
       
   526 
       
   527     Method creates new file to the log information.
       
   528 
       
   529     Parameters: const TDesC& aTestPath: in: Test path definition
       
   530                 const TDesC& aTestFile: in: Test file name
       
   531 
       
   532     Return Values: None
       
   533 
       
   534     Errors/Exceptions:  Leaves if path or file lengths are over KMaxFileName
       
   535                         Leaves if file server Connect method fails
       
   536                         Leaves if file Replace method fails
       
   537                         Leaves if file Open method fails
       
   538                         Leaves if file path not found
       
   539 
       
   540     Status: Proposal
       
   541 
       
   542 -------------------------------------------------------------------------------
       
   543 */
       
   544 void CFileOutput::CreateNewFileL( const TDesC& aTestPath,
       
   545                                     const TDesC& aTestFile )
       
   546     {
       
   547     __TRACE( KInfo, ( _L( "STIFLOGGER: Create a new file for logging" ) ) );
       
   548 
       
   549     // If path and file name lengths are over KMaxFileName(TFileName)
       
   550     __ASSERT_ALWAYS(
       
   551         ( aTestPath.Length() + aTestFile.Length() ) < KMaxFileName,
       
   552         User::Leave( KErrArgument ) );
       
   553 
       
   554     // Check file type and generate threat id name
       
   555     TFileType fileType;
       
   556     FileType( aTestFile, fileType );
       
   557 
       
   558     // File directory name, file name and file type definitions
       
   559     TPtrC dirNamePrt( aTestPath );
       
   560     iFileAndDirName.Copy( dirNamePrt );
       
   561 
       
   562     TInt isDotFound = aTestFile.Find( _L( "." ) );
       
   563     // If dot is found and iThreadIdToLogFile is true
       
   564     if( isDotFound != KErrNotFound && iThreadIdToLogFile )
       
   565         {
       
   566         TFileName testFileWithThreadId;
       
   567         // Generate thread id name
       
   568         TestFileWithThreadId( aTestFile, testFileWithThreadId );
       
   569         iFileAndDirName.Insert( 
       
   570             iFileAndDirName.Length(), testFileWithThreadId );
       
   571         }
       
   572     else
       
   573         {
       
   574         TPtrC txtPrt( fileType );
       
   575         iFileAndDirName.Insert( iFileAndDirName.Length(), aTestFile );
       
   576         iFileAndDirName.Insert( iFileAndDirName.Length(), txtPrt );
       
   577         }
       
   578 
       
   579     // Delete file if exist
       
   580     iFileSession.Delete( iFileAndDirName );
       
   581 
       
   582     TBool isOpen( EFalse );
       
   583     TInt ret( KErrNone );
       
   584 
       
   585     iIsFileOpen = iFileSession.IsFileOpen( iFileAndDirName, isOpen );
       
   586     if( ( iIsFileOpen == KErrNotFound ) ||
       
   587         ( iIsFileOpen == KErrNone ) )
       
   588         {
       
   589         ret = iFile.Replace( iFileSession, iFileAndDirName,
       
   590                                     EFileWrite | EFileStreamText |
       
   591                                     EFileShareAny );
       
   592         if(iUnicode && ret == KErrNone)
       
   593             {
       
   594             char FF = 0xFF;
       
   595             char FE = 0xFE;
       
   596             TBuf8<2> beg;
       
   597             beg.Append(FF);
       
   598             beg.Append(FE);
       
   599             if(iFile.Write(beg) == KErrNone)
       
   600                 iFile.Flush();
       
   601             }
       
   602         }
       
   603     // Probably path not found
       
   604     else
       
   605         {
       
   606         User::Leave( iIsFileOpen );
       
   607         }
       
   608 
       
   609     if ( ret != KErrNone )
       
   610         {
       
   611         User::Leave( ret );
       
   612         }
       
   613 
       
   614     }
       
   615 
       
   616 /*
       
   617 -------------------------------------------------------------------------------
       
   618 
       
   619     Class: CFileOutput
       
   620 
       
   621     Method: Write
       
   622 
       
   623     Description: Write log information or data to the file. 16 bit.
       
   624 
       
   625     Parameters: TBool aWithTimeStamp: in: Is time stamp flag used
       
   626                 TBool aWithLineBreak: in: Is line break flag used
       
   627                 TBool aWithEventRanking: in: Is event ranking flag used
       
   628                 const TDesC& aData: in: Logged or saved data
       
   629 
       
   630     Return Values: TInt: Symbian error code.
       
   631 
       
   632     Errors/Exceptions: None
       
   633 
       
   634     Status: Approved
       
   635 
       
   636 -------------------------------------------------------------------------------
       
   637 */
       
   638 TInt CFileOutput::Write( TBool aWithTimeStamp, TBool aWithLineBreak,
       
   639                             TBool aWithEventRanking, const TDesC& aData )
       
   640     {
       
   641     TInt extraLength( 0 );  // Line and/or event required length
       
   642 
       
   643     TPtr data16(0, 0);
       
   644     TPtr8 data8(0, 0);
       
   645 
       
   646     // Extra space calculation
       
   647     if( iWithEventRanking && aWithEventRanking )
       
   648         {
       
   649         extraLength = extraLength + KMaxEventRanking + KMaxSpace;
       
   650         }
       
   651     if( ( iLoggerType == CStifLogger::EHtml ) && iWithLineBreak && aWithLineBreak )
       
   652         {
       
   653         extraLength = extraLength + KMaxHtmlLineBreak;
       
   654         }
       
   655     if( iWithLineBreak && aWithLineBreak )
       
   656         {
       
   657         extraLength = extraLength + KMaxLineBreak;
       
   658         }
       
   659     if( aWithTimeStamp && iWithTimeStamp )
       
   660         {
       
   661         extraLength = extraLength + KMaxTimeStamp;
       
   662         }
       
   663 
       
   664     // Calculated space
       
   665     TInt space = aData.Length();
       
   666 
       
   667     HBufC8* dataHBuf8 = NULL;
       
   668     HBufC16* dataHBuf16 = NULL;
       
   669 
       
   670     if(iDataHBuf8)
       
   671         {
       
   672         // We'll use HBufC created in ConstructL
       
   673         data8.Set(iDataHBuf8->Des());
       
   674         data16.Set(iDataHBuf16->Des());
       
   675         data16.Copy(_L("")); // Initialize aData buffer
       
   676         
       
   677         if( (aData.Length() + extraLength) > iStaticBufferSize )
       
   678             {
       
   679              RDebug::Print(_L("Warning: buffer size too small, not able to log!"));
       
   680              return KErrOverflow;
       
   681             }        
       
   682         }
       
   683     else
       
   684         {        
       
   685         // We'll create a local HBufC, deleting it in the end of this method
       
   686         dataHBuf8 = HBufC8::New( space + extraLength );
       
   687         if(!dataHBuf8)
       
   688             {
       
   689             return KErrNoMemory;
       
   690             }
       
   691         dataHBuf16 = HBufC16::New(space + extraLength);
       
   692         if(!dataHBuf16)
       
   693             {
       
   694             delete dataHBuf8;
       
   695             return KErrNoMemory;
       
   696             }
       
   697         data8.Set(dataHBuf8->Des());
       
   698         data16.Set(dataHBuf16->Des());
       
   699         }
       
   700 
       
   701     // Event ranking
       
   702     if( iWithEventRanking && aWithEventRanking && !iWithTimeStamp )
       
   703         {
       
   704         EventRanking( data16 );      // Event ranking to data
       
   705         data16.Append( aData );      // Unicode aData to normal text
       
   706         }
       
   707     // Time stamp
       
   708     else if( iWithTimeStamp && aWithTimeStamp )
       
   709         {
       
   710         // With event ranking
       
   711         if( iWithEventRanking && aWithEventRanking )
       
   712             {
       
   713             EventRanking( data16 );  // Event ranking to data
       
   714             }
       
   715         AddTimeStampToData( data16 );// Add time stamp
       
   716         data16.Append( aData );      // Unicode aData to normal text
       
   717         }
       
   718     else
       
   719         {
       
   720         data16.Copy( aData );        // Unicode aData to normal text
       
   721         }
       
   722 
       
   723     // NOTE: If need some special line break do it with logging phase
       
   724 
       
   725     // If html logging and line break is used add the line break.
       
   726     if (( iLoggerType == CStifLogger::EHtml ) && iWithLineBreak && aWithLineBreak )
       
   727         {
       
   728         data16.Append( _L( "<BR>" ) );
       
   729         data16.Append( _L( "\n" ) );  // To make html file more readable
       
   730                                     // with text editor
       
   731         }
       
   732 
       
   733     // Other cases line break is normal '\n' if logging is used
       
   734     else if( iWithLineBreak && aWithLineBreak )
       
   735         {
       
   736         data16.Append( 0x0D ); // 13 or '\' in Symbian OS
       
   737         data16.Append( 0x0A ); // 10 or 'n' in Symbian OS
       
   738         }
       
   739 
       
   740     // Write the data to file
       
   741     TInt tmp = 0;
       
   742     if( iFile.Seek( ESeekEnd, tmp ) == KErrNone )
       
   743         {
       
   744         RDEBUG_FILEWRITECRASH(_L("iFile.Write 1 in"));
       
   745         TPtrC8 dataToFile(0, 0);
       
   746         if(iUnicode)
       
   747             {
       
   748             dataToFile.Set((TUint8 *)(data16.Ptr()), data16.Length() * 2);
       
   749             }
       
   750         else
       
   751             {
       
   752             data8.Copy(data16);
       
   753             dataToFile.Set(data8);
       
   754             }
       
   755         if(iFile.Write(dataToFile) == KErrNone)
       
   756             iFile.Flush();
       
   757         RDEBUG_FILEWRITECRASH(_L("iFile.Write 1 out"));
       
   758         }
       
   759     if(!iDataHBuf8)
       
   760         {
       
   761         delete dataHBuf8;
       
   762         dataHBuf8 = 0;
       
   763         delete dataHBuf16;
       
   764         dataHBuf16 = 0;
       
   765         }
       
   766 
       
   767     return KErrNone;
       
   768 
       
   769     }
       
   770 
       
   771 /*
       
   772 -------------------------------------------------------------------------------
       
   773 
       
   774     Class: CFileOutput
       
   775 
       
   776     Method: Write
       
   777 
       
   778     Description: Write log information or data to the file. 8 bit.
       
   779 
       
   780     Parameters: TBool aWithTimeStamp: in: Is time stamp flag used
       
   781                 TBool aWithLineBreak: in: Is line break flag used
       
   782                 TBool aWithEventRanking: in: Is event ranking flag used
       
   783                 const TDesC8& aData: in: Logged or saved data
       
   784 
       
   785     Return Values: TInt: Symbian error code.
       
   786 
       
   787     Errors/Exceptions: None
       
   788 
       
   789     Status: Approved
       
   790 
       
   791 -------------------------------------------------------------------------------
       
   792 */
       
   793 TInt CFileOutput::Write( TBool aWithTimeStamp, TBool aWithLineBreak,
       
   794                             TBool aWithEventRanking, const TDesC8& aData )
       
   795     {
       
   796     TInt extraLength( 0 );  // Line and/or event required length
       
   797 
       
   798     TPtr data16(0, 0);
       
   799     TPtr8 data8(0, 0);
       
   800 
       
   801     // Extra space calculation
       
   802     if( iWithEventRanking && aWithEventRanking )
       
   803         {
       
   804         extraLength = extraLength + KMaxEventRanking + KMaxSpace;
       
   805         }
       
   806     if( ( iLoggerType == CStifLogger::EHtml ) && iWithLineBreak && aWithLineBreak )
       
   807         {
       
   808         extraLength = extraLength + KMaxHtmlLineBreak;
       
   809         }
       
   810     if( iWithLineBreak && aWithLineBreak )
       
   811         {
       
   812         extraLength = extraLength + KMaxLineBreak;
       
   813         }
       
   814     if( aWithTimeStamp && iWithTimeStamp )
       
   815         {
       
   816         extraLength = extraLength + KMaxTimeStamp;
       
   817         }
       
   818 
       
   819     // aData straight to the file
       
   820     if ( extraLength == 0 && !iUnicode)
       
   821         {
       
   822         // Write the data to file
       
   823         TInt tmp = 0;
       
   824         if( iFile.Seek( ESeekEnd, tmp ) == KErrNone )
       
   825             {
       
   826             RDEBUG_FILEWRITECRASH(_L("iFile.Write 2 in"));
       
   827             if( iFile.Write( aData ) == KErrNone )
       
   828                 iFile.Flush();
       
   829             RDEBUG_FILEWRITECRASH(_L("iFile.Write 2 out"));
       
   830             }
       
   831         return KErrNone;
       
   832         }
       
   833 
       
   834     // Calculated space
       
   835     TInt space = aData.Length();
       
   836     HBufC8* dataHBuf8 = NULL;
       
   837     HBufC* dataHBuf16 = NULL;
       
   838 
       
   839     if(iDataHBuf8)
       
   840         {
       
   841         // We'll use HBufC created in ConstructL
       
   842         data8.Set(iDataHBuf8->Des());
       
   843         data8.Copy(_L("")); // Initialize aData buffer
       
   844         data16.Set(iDataHBuf16->Des());
       
   845         
       
   846         if( (aData.Length() + extraLength) > iStaticBufferSize )
       
   847             {
       
   848              RDebug::Print(_L("Warning: buffer size too small, not able to log!"));
       
   849              return KErrOverflow;
       
   850             }        
       
   851         }
       
   852     else
       
   853         {        
       
   854         // We'll create a local HBufC, deleting it in the end of this method
       
   855         dataHBuf8 = HBufC8::New( space + extraLength );
       
   856         if(!dataHBuf8)
       
   857             {
       
   858             return KErrNoMemory;
       
   859             }
       
   860         dataHBuf16 = HBufC16::New(space + extraLength);
       
   861         if(!dataHBuf16)
       
   862             {
       
   863             delete dataHBuf8;
       
   864             return KErrNoMemory;
       
   865             }
       
   866         data8.Set(dataHBuf8->Des());  // Memory allocation for data
       
   867         data16.Set(dataHBuf16->Des());  // Memory allocation for data
       
   868         }
       
   869 
       
   870     // Event ranking
       
   871     if( iWithEventRanking && aWithEventRanking && !iWithTimeStamp )
       
   872         {
       
   873         EventRanking( data8 );      // Event ranking to data
       
   874         data8.Append( aData );      // Unicode aData to normal text
       
   875         }
       
   876     // Time stamp
       
   877     else if( iWithTimeStamp && aWithTimeStamp )
       
   878         {
       
   879         // With event ranking
       
   880         if( iWithEventRanking && aWithEventRanking )
       
   881             {
       
   882             EventRanking( data8 );  // Event ranking to data
       
   883             }
       
   884         AddTimeStampToData( data8 );// Add time stamp
       
   885         data8.Append( aData );      // Unicode aData to normal text
       
   886         }
       
   887     else
       
   888         {
       
   889         data8.Copy( aData );        // Unicode aData to normal text
       
   890         }
       
   891 
       
   892     // NOTE: If need some special line break do it with logging phase
       
   893 
       
   894     // If html logging and line break is used add the line break.
       
   895     if ( ( iLoggerType == CStifLogger::EHtml ) && iWithLineBreak && aWithLineBreak )
       
   896         {
       
   897         data8.Append( _L( "<BR>" ) );
       
   898         data8.Append( _L( "\n" ) );  // To make html file more readable
       
   899                                     // with text editor
       
   900         }
       
   901 
       
   902     // Other cases line break is normal '\n' if logging is used
       
   903     else if( iWithLineBreak && aWithLineBreak )
       
   904         {
       
   905         data8.Append( 0x0D ); // 13 or '\' in Symbian OS
       
   906         data8.Append( 0x0A ); // 10 or 'n' in Symbian OS
       
   907         }
       
   908 
       
   909     // Write the data to file
       
   910     TInt tmp = 0;
       
   911     if( iFile.Seek( ESeekEnd, tmp ) == KErrNone )
       
   912         {
       
   913         RDEBUG_FILEWRITECRASH(_L("iFile.Write 3 in"));
       
   914         TPtrC8 dataToFile(0, 0);
       
   915         if(iUnicode)
       
   916             {
       
   917             data16.Copy(data8);
       
   918             dataToFile.Set((TUint8 *)(data16.Ptr()), data16.Length() * 2);
       
   919             }
       
   920         else
       
   921             {
       
   922             dataToFile.Set(data8);
       
   923             }
       
   924         if(iFile.Write(dataToFile) == KErrNone)
       
   925             iFile.Flush();
       
   926         RDEBUG_FILEWRITECRASH(_L("iFile.Write 3 out"));
       
   927         }
       
   928     if(!iDataHBuf8)
       
   929         {
       
   930         delete dataHBuf8;
       
   931         dataHBuf8 = 0;
       
   932         delete dataHBuf16;
       
   933         dataHBuf16 = 0;
       
   934         }
       
   935 
       
   936     return KErrNone;
       
   937 
       
   938     }
       
   939 
       
   940 /*
       
   941 -------------------------------------------------------------------------------
       
   942 
       
   943     Class: CFileOutput
       
   944 
       
   945     Method: EventRanking
       
   946 
       
   947     Description: For event ranking logging.
       
   948 
       
   949     Parameters: TPtr& aData: inout: Data with event ranking
       
   950 
       
   951     Return Values: None
       
   952 
       
   953     Errors/Exceptions: None
       
   954 
       
   955     Status: Approved
       
   956 
       
   957 -------------------------------------------------------------------------------
       
   958 */
       
   959 void CFileOutput::EventRanking( TPtr& aData )
       
   960     {
       
   961     // Returns the machine's current tick count.
       
   962     TUint tick = User::TickCount();
       
   963     tick &= 0xffff;
       
   964     aData.AppendNum( tick );
       
   965     aData.Append( _L( " " ) );
       
   966     }
       
   967 
       
   968 /*
       
   969 -------------------------------------------------------------------------------
       
   970 
       
   971     Class: CFileOutput
       
   972 
       
   973     Method: EventRanking
       
   974 
       
   975     Description: For event ranking logging.
       
   976 
       
   977     Parameters: TPtr8& aData: inout: Data with event ranking
       
   978 
       
   979     Return Values: None
       
   980 
       
   981     Errors/Exceptions: None
       
   982 
       
   983     Status: Approved
       
   984 
       
   985 -------------------------------------------------------------------------------
       
   986 */
       
   987 void CFileOutput::EventRanking( TPtr8& aData )
       
   988     {
       
   989     // Returns the machine's current tick count.
       
   990     TUint tick = User::TickCount();
       
   991     tick &= 0xffff;
       
   992     aData.AppendNum( tick );
       
   993     aData.Append( _L8( " " ) );
       
   994 
       
   995     }
       
   996 
       
   997 /*
       
   998 -------------------------------------------------------------------------------
       
   999 
       
  1000     Class: CFileOutput
       
  1001 
       
  1002     Method: AddTimeStampToData
       
  1003 
       
  1004     Description: For date and time logging.
       
  1005 
       
  1006     Parameters: TPtr& aData: inout: Data with time stamps
       
  1007 
       
  1008     Return Values: None
       
  1009 
       
  1010     Errors/Exceptions: None
       
  1011 
       
  1012     Status: Approved
       
  1013 
       
  1014 -------------------------------------------------------------------------------
       
  1015 */
       
  1016 void CFileOutput::AddTimeStampToData( TPtr& aData )
       
  1017     {
       
  1018     TStifLoggerTimeStamp timeStamp;
       
  1019     GetDateAndTime( timeStamp );
       
  1020 
       
  1021     TStifLoggerTimeStamp8 tStamp16;
       
  1022     tStamp16.Copy(timeStamp);
       
  1023 
       
  1024     aData.Append( tStamp16 );
       
  1025     }
       
  1026 
       
  1027 /*
       
  1028 -------------------------------------------------------------------------------
       
  1029 
       
  1030     Class: CFileOutput
       
  1031 
       
  1032     Method: AddTimeStampToData
       
  1033 
       
  1034     Description: For date and time logging.
       
  1035 
       
  1036     Parameters: TPtr8& aData: inout: Data with time stamps
       
  1037 
       
  1038     Return Values: None
       
  1039 
       
  1040     Errors/Exceptions: None
       
  1041 
       
  1042     Status: Approved
       
  1043 
       
  1044 -------------------------------------------------------------------------------
       
  1045 */
       
  1046 void CFileOutput::AddTimeStampToData( TPtr8& aData )
       
  1047     {
       
  1048     TStifLoggerTimeStamp timeStamp;
       
  1049     GetDateAndTime( timeStamp );
       
  1050     aData.Append( timeStamp );
       
  1051 
       
  1052     }
       
  1053 
       
  1054 /*
       
  1055 -------------------------------------------------------------------------------
       
  1056 
       
  1057     Class: CFileOutput
       
  1058 
       
  1059     Method: GetDateAndTime
       
  1060 
       
  1061     Description: For date and time logging.
       
  1062 
       
  1063     Parameters: TStifLoggerTimeStamp& aDataAndTime: inout: Generated date and time
       
  1064 
       
  1065     Return Values: None
       
  1066 
       
  1067     Errors/Exceptions: None
       
  1068 
       
  1069     Status: Approved
       
  1070 
       
  1071 -------------------------------------------------------------------------------
       
  1072 */
       
  1073 void CFileOutput::GetDateAndTime( TStifLoggerTimeStamp& aDataAndTime )
       
  1074     {
       
  1075     TInt num( 0 );
       
  1076     TInt microseconds( 0 );
       
  1077 
       
  1078     // Append date
       
  1079     TTime time;
       
  1080     time.HomeTime();
       
  1081     TDateTime dateTime( time.DateTime() );
       
  1082 
       
  1083     num = dateTime.Day() + 1;
       
  1084     if( num < 10 )
       
  1085         {
       
  1086         aDataAndTime.Append( '0' );
       
  1087         }
       
  1088     // Append month
       
  1089     aDataAndTime.AppendNum( num );
       
  1090     aDataAndTime.Append( '.' );
       
  1091     num = 0;
       
  1092     num = dateTime.Month();
       
  1093     switch( num )
       
  1094         {
       
  1095         case EJanuary:      // 1
       
  1096             {
       
  1097              aDataAndTime.Append( _L( "Jan" ) );
       
  1098              break;
       
  1099             }
       
  1100         case EFebruary:     // 2
       
  1101             {
       
  1102              aDataAndTime.Append( _L( "Feb" ) );
       
  1103              break;
       
  1104             }
       
  1105         case EMarch:        // 3
       
  1106             {
       
  1107              aDataAndTime.Append( _L( "Mar" ) );
       
  1108              break;
       
  1109             }
       
  1110         case EApril:        // 4
       
  1111             {
       
  1112              aDataAndTime.Append( _L( "Apr" ) );
       
  1113              break;
       
  1114             }
       
  1115         case EMay:          // 5
       
  1116             {
       
  1117              aDataAndTime.Append( _L( "May" ) );
       
  1118              break;
       
  1119             }
       
  1120         case EJune:         // 6
       
  1121             {
       
  1122              aDataAndTime.Append( _L( "Jun" ) );
       
  1123              break;
       
  1124             }
       
  1125         case EJuly:         // 7
       
  1126             {
       
  1127              aDataAndTime.Append( _L( "Jul" ) );
       
  1128              break;
       
  1129             }
       
  1130         case EAugust:       // 8
       
  1131             {
       
  1132              aDataAndTime.Append( _L( "Aug" ) );
       
  1133              break;
       
  1134             }
       
  1135         case ESeptember:    // 9
       
  1136             {
       
  1137              aDataAndTime.Append( _L( "Sep" ) );
       
  1138              break;
       
  1139             }
       
  1140         case EOctober:      // 10
       
  1141             {
       
  1142              aDataAndTime.Append( _L( "Oct" ) );
       
  1143              break;
       
  1144             }
       
  1145         case ENovember:     // 11
       
  1146             {
       
  1147              aDataAndTime.Append( _L( "Nov" ) );
       
  1148              break;
       
  1149             }
       
  1150         case EDecember:     // 12
       
  1151             {
       
  1152              aDataAndTime.Append( _L( "Dec" ) );
       
  1153              break;
       
  1154             }
       
  1155         default:
       
  1156             {
       
  1157              aDataAndTime.Append( '-' );
       
  1158              break;
       
  1159             }
       
  1160         }
       
  1161    // Append year
       
  1162     aDataAndTime.Append( '.' );
       
  1163     aDataAndTime.AppendNum( dateTime.Year() );
       
  1164 
       
  1165     // Append time
       
  1166     aDataAndTime.Append( ' ' );
       
  1167     num = dateTime.Hour();
       
  1168     if( num < 10 )
       
  1169         {
       
  1170         aDataAndTime.Append( '0' );
       
  1171         }
       
  1172     aDataAndTime.AppendNum( num );
       
  1173     aDataAndTime.Append( ':' );
       
  1174     num = dateTime.Minute();
       
  1175     if( num < 10 )
       
  1176         {
       
  1177         aDataAndTime.Append( '0' );
       
  1178         }
       
  1179     aDataAndTime.AppendNum( num );
       
  1180     aDataAndTime.Append( ':' );
       
  1181 
       
  1182     num = dateTime.Second();                // Seconds
       
  1183     microseconds = dateTime.MicroSecond();  // Microseconds
       
  1184 
       
  1185     // Seconds
       
  1186     if( num < 10 )
       
  1187         {
       
  1188         aDataAndTime.Append( '0' );
       
  1189         }
       
  1190     aDataAndTime.AppendNum( num );
       
  1191 
       
  1192     // Milliseconds
       
  1193     aDataAndTime.Append( '.' );
       
  1194     aDataAndTime.AppendNumFixedWidth( microseconds, EDecimal, 3 );
       
  1195 
       
  1196     // NOTE: If you add more spaces etc. remember increment KMaxTimeStamp size!
       
  1197 
       
  1198     if ( iLoggerType == CStifLogger::EHtml )
       
  1199         {
       
  1200         aDataAndTime.Append( _L("....") );
       
  1201         }
       
  1202     else
       
  1203         {
       
  1204         aDataAndTime.Append( _L("    ") );
       
  1205         }
       
  1206 
       
  1207     }
       
  1208 
       
  1209 // ================= OTHER EXPORTED FUNCTIONS =================================
       
  1210 // None
       
  1211 
       
  1212 //  End of File