stif/Logger/src/FileOutput.cpp
changeset 0 a03f92240627
child 8 ecff51f1e7fb
child 13 33016869e0dd
equal deleted inserted replaced
-1:000000000000 0:a03f92240627
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 * 
       
    14 * Description: 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     COutput()
       
    87     {
       
    88     // Indicates file type
       
    89     iLoggerType = aLoggerType;
       
    90 
       
    91     // Time stamp indicator
       
    92     iWithTimeStamp = aWithTimeStamp;
       
    93 
       
    94     // Line break indicator
       
    95     iWithLineBreak = aWithLineBreak;
       
    96 
       
    97     // Log event ranking indicator
       
    98     iWithEventRanking = aWithEventRanking;
       
    99 
       
   100     // Indicator to thread id adding to end of the log file
       
   101     iThreadIdToLogFile = aThreadIdToLogFile;
       
   102 
       
   103     // Is file open indicator
       
   104     iIsFileOpen = 0;
       
   105 
       
   106     }
       
   107 
       
   108 /*
       
   109 -------------------------------------------------------------------------------
       
   110 
       
   111     Class: CFileOutput
       
   112 
       
   113     Method: ConstructL
       
   114 
       
   115     Description: Symbian OS second phase constructor
       
   116 
       
   117     Symbian OS default constructor can leave.
       
   118 
       
   119     Parameters: const TDesC& aTestPath: in: Log path
       
   120                 const TDesC& aTestFile: in: Log filename
       
   121                 TBool aOverWrite: in: For file overwrite
       
   122                 TBool aCreateLogDir: in: Indicator to directory creation
       
   123                 TInt  aStaticBufferSize
       
   124                 TBool aUnicode: in: Indicator if file has to be in unicode format
       
   125 
       
   126     Return Values: None
       
   127 
       
   128     Errors/Exceptions:  Leaves if called CreateNewFileL method fails
       
   129                         Leaves if called OpenExistingFileL method fails
       
   130 
       
   131     Status: Proposal
       
   132 
       
   133 -------------------------------------------------------------------------------
       
   134 */
       
   135 void CFileOutput::ConstructL( const TDesC& aTestPath,
       
   136                                 const TDesC& aTestFile,
       
   137                                 TBool aOverWrite,
       
   138                                 TBool aCreateLogDir,
       
   139                                 TInt aStaticBufferSize,
       
   140                                 TBool aUnicode)
       
   141     {
       
   142     iUnicode = aUnicode;
       
   143 
       
   144     // Open file session
       
   145     User::LeaveIfError( iFileSession.Connect() );
       
   146 
       
   147     // Create a log directory
       
   148     if( aCreateLogDir )
       
   149         {
       
   150         CreateDirectoryL( aTestPath );
       
   151         }
       
   152 
       
   153     // Create a new file
       
   154     if ( aOverWrite )
       
   155         {
       
   156         CreateNewFileL( aTestPath, aTestFile );
       
   157         }
       
   158     // Open an existing file
       
   159     else 
       
   160         {
       
   161         OpenExistingFileL( aTestPath, aTestFile );
       
   162         }
       
   163         
       
   164     if( aStaticBufferSize != 0)
       
   165         {
       
   166         iDataHBuf8 = HBufC8::NewL( aStaticBufferSize );
       
   167         iDataHBuf16 = HBufC::NewL(aStaticBufferSize);
       
   168         iStaticBufferSize = aStaticBufferSize;
       
   169         }
       
   170     }
       
   171 
       
   172 /*
       
   173 -------------------------------------------------------------------------------
       
   174 
       
   175     Class: CFileOutput
       
   176 
       
   177     Method: NewL
       
   178 
       
   179     Description: Two-phased constructor.
       
   180 
       
   181     Parameters: const TDesC& aTestPath: in: Log path
       
   182                 const TDesC& aTestFile: in: Log filename
       
   183                 TLoggerType aLoggerType: in: File type
       
   184                 TBool aOverWrite: in: For file overwrite
       
   185                 TBool aWithTimeStamp: in: For timestamp
       
   186                 TBool aWithLineBreak: in: For line break
       
   187                 TBool aWithEventRanking: in: For events ranking to file
       
   188                 TBool aThreadIdToLogFile: in: Indicator to thread id adding to
       
   189                                               end of the log file
       
   190                 TBool aCreateLogDir: in: Indicator to directory creation
       
   191                 TInt  aStaticBufferSize
       
   192                 TBool aUnicode: in: Indicator if file has to be in unicode format
       
   193 
       
   194     Return Values: CFileOutput*: pointer to CFileOutput object
       
   195 
       
   196     Errors/Exceptions: Leaves if ConstructL leaves
       
   197 
       
   198     Status: Proposal
       
   199 
       
   200 -------------------------------------------------------------------------------
       
   201 */
       
   202 CFileOutput* CFileOutput::NewL( const TDesC& aTestPath,
       
   203                                 const TDesC& aTestFile,
       
   204                                 CStifLogger::TLoggerType aLoggerType,
       
   205                                 TBool aOverWrite,
       
   206                                 TBool aWithTimeStamp,
       
   207                                 TBool aWithLineBreak,
       
   208                                 TBool aWithEventRanking,
       
   209                                 TBool aThreadIdToLogFile,
       
   210                                 TBool aCreateLogDir,
       
   211                                 TInt  aStaticBufferSize,
       
   212                                 TBool aUnicode )
       
   213     {
       
   214     // Create CFileOutput object fileWriter
       
   215     CFileOutput* fileWriter = new (ELeave) CFileOutput( aLoggerType,
       
   216                                                         aWithTimeStamp,
       
   217                                                         aWithLineBreak,
       
   218                                                         aWithEventRanking,
       
   219                                                         aThreadIdToLogFile );
       
   220 
       
   221     CleanupStack::PushL( fileWriter );
       
   222     fileWriter->ConstructL( aTestPath, aTestFile, aOverWrite, aCreateLogDir, aStaticBufferSize,
       
   223                             aUnicode );
       
   224     CleanupStack::Pop( fileWriter );
       
   225 
       
   226     return fileWriter;
       
   227 
       
   228     }
       
   229 
       
   230 /*
       
   231 -------------------------------------------------------------------------------
       
   232 
       
   233     Class: CFileOutput
       
   234 
       
   235     Method: ~CFileOutput
       
   236 
       
   237     Description: Destructor
       
   238 
       
   239     Parameters: None
       
   240 
       
   241     Return Values: None
       
   242 
       
   243     Errors/Exceptions: None
       
   244 
       
   245     Status: Approved
       
   246 
       
   247 -------------------------------------------------------------------------------
       
   248 */
       
   249 CFileOutput::~CFileOutput()
       
   250     {
       
   251     // Close file
       
   252     iFile.Close();
       
   253     // Close file session
       
   254     iFileSession.Close();
       
   255 
       
   256     delete iDataHBuf8;
       
   257     delete iDataHBuf16;
       
   258     }
       
   259 
       
   260 /*
       
   261 -------------------------------------------------------------------------------
       
   262 
       
   263     Class: CFileOutput
       
   264 
       
   265     Method: FileType
       
   266 
       
   267     Description: Check file type.
       
   268 
       
   269     Check is file type set with a aTestFile's name. If file type is not set
       
   270     the type will set according to StifLogger's type.
       
   271 
       
   272     Parameters: const TDesC& aTestFile: in: Log filename
       
   273                 TFileType& fileType: inout: Generated file type
       
   274 
       
   275     Return Values: None
       
   276 
       
   277     Errors/Exceptions: None
       
   278 
       
   279     Status: Approved
       
   280 
       
   281 -------------------------------------------------------------------------------
       
   282 */    
       
   283 void CFileOutput::FileType( const TDesC& aTestFile,
       
   284                             TFileType& aFileType )
       
   285     {
       
   286     TBool fileTypeIsSet( EFalse ); // File type indicator
       
   287 
       
   288     // Check is file type set to aTestFile parameter
       
   289     TInt ret = aTestFile.Find( _L( "." ) );
       
   290     if( ret != KErrNotFound )
       
   291         {
       
   292         fileTypeIsSet = ETrue;
       
   293         }
       
   294     // If not, add thread id name if allowed
       
   295     else if ( iThreadIdToLogFile )
       
   296         {
       
   297         // Thread id maximum length is 8 in hexadesimal format
       
   298         // Construct unique thread name
       
   299         aFileType.Append( _L("_") );
       
   300         RThread threadHandle;                   // A handle to a thread
       
   301         TThreadId id = threadHandle.Id();       // Encapsulates the 
       
   302                                                 // Id of a thread
       
   303         // Appends id in hexadesimal format             
       
   304         aFileType.AppendFormat( _L( "%x" ), (TInt)id );
       
   305         }
       
   306 
       
   307     // Add file type after the thread id name
       
   308     if ( iLoggerType == CStifLogger::ETxt && !fileTypeIsSet )
       
   309         {
       
   310         // ".txt"
       
   311         aFileType.Append( _L( "." ) );
       
   312         aFileType.Append( _L( "txt" ) );
       
   313         }
       
   314     else if ( iLoggerType == CStifLogger::EHtml && !fileTypeIsSet )
       
   315         {
       
   316         // ".html"
       
   317         aFileType.Append( _L( "." ) );
       
   318         aFileType.Append( _L( "html" ) );
       
   319         }
       
   320     // EData file type comes from the aTestFile name. If not the file type 
       
   321     // will be empty
       
   322     else if ( iLoggerType == CStifLogger::EData )
       
   323         {
       
   324         aFileType.Append( _L( "" ) );
       
   325         }
       
   326     else
       
   327         {
       
   328         aFileType.Append( _L( "" ) );
       
   329         }
       
   330 
       
   331     }
       
   332 
       
   333 /*
       
   334 -------------------------------------------------------------------------------
       
   335 
       
   336     Class: CFileOutput
       
   337 
       
   338     Method: TestFileWithThreadId
       
   339 
       
   340     Description: Generate thread id
       
   341 
       
   342     Generate thread id name between the test file name and test file type.
       
   343 
       
   344     Parameters: TDesC& aTestFile: in: Test file name
       
   345                 TFileName& aNewTestFile: inout: Generated test file name 
       
   346 
       
   347     Return Values: None
       
   348 
       
   349     Errors/Exceptions: None
       
   350 
       
   351     Status: Approved
       
   352 
       
   353 -------------------------------------------------------------------------------
       
   354 */
       
   355 void CFileOutput::TestFileWithThreadId( const TDesC& aTestFile, 
       
   356                                         TFileName& aNewTestFile )
       
   357     {
       
   358     for( TInt a = 0; a < aTestFile.Length(); a++ )
       
   359         {
       
   360         // Find a dot
       
   361         if( aTestFile[a] == '.' )
       
   362             {
       
   363             TPtrC parsedFileType = aTestFile.Mid( a );  // Take rest of the 
       
   364                                                         // aTestFile
       
   365             aNewTestFile.Append( _L( "_" ) );
       
   366             RThread threadHandle;                       // A handle to a thread
       
   367             TThreadId id = threadHandle.Id();           // Encapsulates the 
       
   368                                                         // Id of a thread
       
   369             aNewTestFile.AppendFormat( _L( "%x" ), (TInt)id );// Appends id in
       
   370                                                         // hexadesimal format
       
   371             aNewTestFile.Append( parsedFileType );
       
   372             break;
       
   373             }
       
   374         // Dot not found yet
       
   375         else
       
   376             {
       
   377             aNewTestFile.Append( aTestFile[a] );
       
   378             }
       
   379         }
       
   380 
       
   381     }
       
   382 
       
   383 /*
       
   384 -------------------------------------------------------------------------------
       
   385 
       
   386     Class: CFileOutput
       
   387 
       
   388     Method: CreateDirectoryL
       
   389 
       
   390     Description: Create a log directory.
       
   391 
       
   392     Method creates directory if not allready exist.
       
   393 
       
   394     Parameters: const TDesC& aTestPath: in: Test path definition
       
   395 
       
   396     Return Values: None
       
   397 
       
   398     Errors/Exceptions: Leaves if directory creation fails
       
   399 
       
   400     Status: Proposal
       
   401 
       
   402 -------------------------------------------------------------------------------
       
   403 */
       
   404 void CFileOutput::CreateDirectoryL( const TDesC& aTestPath )
       
   405     {
       
   406     __TRACE( KInfo, ( _L( "STIFLOGGER: Create a directory" ) ) );
       
   407 
       
   408     TInt ret = iFileSession.MkDirAll( aTestPath );
       
   409 	if( ret != KErrNone && ret != KErrAlreadyExists )
       
   410         {
       
   411         __TRACE( KError, 
       
   412             ( _L( "STIFLOGGER: Directory creation fails with error: %d" ), ret ) );
       
   413 		User::Leave( ret );
       
   414         }
       
   415 
       
   416     }
       
   417 
       
   418 /*
       
   419 -------------------------------------------------------------------------------
       
   420 
       
   421     Class: CFileOutput
       
   422 
       
   423     Method: OpenExistingFileL
       
   424 
       
   425     Description: Open an existing file.
       
   426 
       
   427     Method is used when is need for log new information after the existing
       
   428     log file.
       
   429 
       
   430     Parameters: const TDesC& aTestPath: in: Test path definition
       
   431                 const TDesC& aTestFile: in: Test file name
       
   432 
       
   433     Return Values: None
       
   434 
       
   435     Errors/Exceptions:  Leaves if path or file lengths are over KMaxFileName
       
   436                         Leaves if file Replace method fails
       
   437                         Leaves if file Open method fails
       
   438                         Leaves if file path not found
       
   439 
       
   440     Status: Proposal
       
   441 
       
   442 -------------------------------------------------------------------------------
       
   443 */
       
   444 void CFileOutput::OpenExistingFileL( const TDesC& aTestPath, 
       
   445                                         const TDesC& aTestFile )
       
   446     {
       
   447     __TRACE( KInfo, ( _L( "STIFLOGGER: Opening an existing file for logging" ) ) );
       
   448 
       
   449     // If path and file name lengths are over KMaxFileName(TFileName)
       
   450     __ASSERT_ALWAYS(
       
   451         ( aTestPath.Length() + aTestFile.Length() ) < KMaxFileName,
       
   452         User::Leave( KErrArgument ) );
       
   453 
       
   454     // Check file type and generate threat id name
       
   455     TFileType fileType;
       
   456     FileType( aTestFile, fileType );
       
   457 
       
   458     // File directory name, file name and file type definitions
       
   459     TPtrC dirNamePrt( aTestPath );
       
   460     iFileAndDirName.Copy( dirNamePrt );
       
   461 
       
   462     TInt isDotFound = aTestFile.Find( _L( "." ) );
       
   463     // If dot is found and iThreadIdToLogFile is true
       
   464     if( isDotFound != KErrNotFound && iThreadIdToLogFile )
       
   465         {
       
   466         TFileName testFileWithThreadId;
       
   467         // Generate thread id name
       
   468         TestFileWithThreadId( aTestFile, testFileWithThreadId );
       
   469         iFileAndDirName.Insert( 
       
   470             iFileAndDirName.Length(), testFileWithThreadId );
       
   471         }
       
   472     else
       
   473         {
       
   474         TPtrC txtPrt( fileType );
       
   475         iFileAndDirName.Insert( iFileAndDirName.Length(), aTestFile );
       
   476         iFileAndDirName.Insert( iFileAndDirName.Length(), txtPrt );
       
   477         }
       
   478 
       
   479     TBool isOpen( EFalse );
       
   480     TInt ret( KErrNone );
       
   481 
       
   482     iIsFileOpen = iFileSession.IsFileOpen( iFileAndDirName, isOpen );
       
   483     if( iIsFileOpen == KErrNotFound )
       
   484         {
       
   485         ret =  iFile.Create( iFileSession, iFileAndDirName, 
       
   486                                     EFileWrite | EFileStreamText |
       
   487                                     EFileShareAny );
       
   488         if(iUnicode && ret == KErrNone)
       
   489             {
       
   490             char FF = 0xFF;
       
   491             char FE = 0xFE;
       
   492             TBuf8<2> beg;
       
   493             beg.Append(FF);
       
   494             beg.Append(FE);
       
   495             if(iFile.Write(beg) == KErrNone)
       
   496                 iFile.Flush();
       
   497             }
       
   498         }
       
   499     else if( iIsFileOpen == KErrNone )
       
   500         {
       
   501         ret = iFile.Open( iFileSession, iFileAndDirName,
       
   502                             EFileWrite | EFileStreamText |
       
   503                                     EFileShareAny );
       
   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 != NULL )
       
   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 == NULL )
       
   688             {
       
   689             return KErrNoMemory;
       
   690             }
       
   691         dataHBuf16 = HBufC16::New(space + extraLength);
       
   692         if(dataHBuf16 == NULL)
       
   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 == NULL )
       
   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 != NULL )
       
   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 == NULL )
       
   857             {
       
   858             return KErrNoMemory;
       
   859             }
       
   860         dataHBuf16 = HBufC16::New(space + extraLength);
       
   861         if(dataHBuf16 == NULL)
       
   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 == NULL )
       
   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