lowlevellibsandfws/pluginfw/Test_Bed/test_bed/DataLogger.cpp
changeset 0 e4d67989cc36
child 44 97b0fb8a2cc2
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include <e32def.h>
       
    17 #include <f32file.h>
       
    18 
       
    19 #include <ecom/test_bed/datalogger.h>
       
    20 
       
    21 // KLogBufferSize is the maximum line length allowed by flogger
       
    22 const TInt KMaxTBLogEntrySize = KLogBufferSize;
       
    23 
       
    24 // Common string literals for all output formats
       
    25 _LIT(KTimeFormatStr,"%J%:1%T%:2%S%.%*C3");
       
    26 // Above string will give time in format HH:MM:SS.SSS therefore max length = 12
       
    27 const TInt KTimeBufLength = 12;
       
    28 
       
    29 // Define some string literals for HTML formatting
       
    30 _LIT(KHTMLDocumentStart,"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"><HTML><HEAD><META NAME=\"robots\" CONTENT=\"noindex\"><META NAME=\"author\" CONTENT=\"Symbian RTestBed log generator\"><TITLE>");
       
    31 // Insert title string here
       
    32 _LIT(KHTMLContentStart,"</TITLE></HEAD><BODY><P><FONT=3>");
       
    33 // Insert time string here
       
    34 _LIT(KHTMLCommentStart,"<P>");
       
    35 // Insert content here
       
    36 _LIT(KHTMLCommentEnd,"</P>");
       
    37 _LIT(KHTMLDocumentEnd,"</FONT></P></BODY></HTML>");
       
    38 
       
    39 //___________________________________________________________________________
       
    40 // Define the overflow handling classes for any log formatting methods
       
    41 // Simply record the overflow...
       
    42 //
       
    43 
       
    44 NONSHARABLE_CLASS(TLogMessageOverflow) : public TDes16Overflow
       
    45 	{
       
    46 	public:
       
    47 	
       
    48 		TLogMessageOverflow();
       
    49 	
       
    50 		void Overflow(TDes16&);	
       
    51 	
       
    52 		TInt iError;
       
    53 	};
       
    54 
       
    55 TLogMessageOverflow::TLogMessageOverflow()
       
    56 : TDes16Overflow(),
       
    57 iError(KErrNone)
       
    58 	{
       
    59 	}
       
    60 
       
    61 void TLogMessageOverflow::Overflow(TDes16&)
       
    62 	{
       
    63 	__DEBUGGER();
       
    64 	iError = KErrOverflow;
       
    65 	}
       
    66 
       
    67 
       
    68 NONSHARABLE_CLASS(TLogMessageOverflow8) : public TDes8Overflow
       
    69 	{
       
    70 	public:
       
    71 	
       
    72 		TLogMessageOverflow8();
       
    73 	
       
    74 		void Overflow(TDes8&);	
       
    75 	
       
    76 		TInt iError;
       
    77 	};
       
    78 
       
    79 TLogMessageOverflow8::TLogMessageOverflow8()
       
    80 : TDes8Overflow(),
       
    81 iError(KErrNone)
       
    82 	{
       
    83 	}
       
    84 
       
    85 void TLogMessageOverflow8::Overflow(TDes8&)
       
    86 	{
       
    87 	__DEBUGGER();
       
    88 	iError = KErrOverflow;
       
    89 	}
       
    90 
       
    91 //___________________________________________________________________________
       
    92 
       
    93 //___________________________________________________________________________
       
    94 
       
    95 CDataLogger::~CDataLogger()
       
    96 	{
       
    97 	if(iLogOutput != NULL)
       
    98 		{
       
    99 		if(iLogStyle != EText && iLogFormat.iDocumentEnd)
       
   100 			Log(iLogOutput, *(iLogFormat.iDocumentEnd));
       
   101 		iLogOutput->Close();
       
   102 		}
       
   103 
       
   104 	if(iReportOutput != NULL)
       
   105 		{
       
   106 		if(iLogStyle != EText && iLogFormat.iDocumentEnd)
       
   107 			Log(iReportOutput, *(iLogFormat.iDocumentEnd));
       
   108 		iReportOutput->Close();
       
   109 		}
       
   110 
       
   111 	delete iFormatBuf;
       
   112 	delete iDebug;
       
   113 	delete iDefaultLogOutput;
       
   114 	delete iDefaultReportOutput;
       
   115 	}
       
   116 
       
   117 
       
   118 CDataLogger::CDataLogger()
       
   119 	{
       
   120 	}
       
   121 
       
   122 CDataLogger* CDataLogger::NewLC(TLoggingInfo* aLogInfo)
       
   123 	{
       
   124 	CDataLogger* self = new (ELeave) CDataLogger();
       
   125 	CleanupStack::PushL(self);
       
   126 	self->ConstructL(aLogInfo);
       
   127 	return self;
       
   128 	}
       
   129 
       
   130 CDataLogger* CDataLogger::NewL(TLoggingInfo* aLogInfo)
       
   131 	{
       
   132 	CDataLogger* self = NewLC(aLogInfo);
       
   133 	CleanupStack::Pop();
       
   134 	return self;
       
   135 	}
       
   136 
       
   137 
       
   138 void CDataLogger::ConstructL(TLoggingInfo* aLogInfo)
       
   139 	{
       
   140 	iFormatBuf = HBufC::NewL(KMaxTBLogEntrySize);
       
   141 
       
   142 	SetupLoggingL(aLogInfo);
       
   143 
       
   144 	iLogOutput->OpenL();
       
   145 	iReportOutput->OpenL();
       
   146 
       
   147 	// Record additional information : Time
       
   148 	TTime time;
       
   149 	time.UniversalTime();
       
   150 	TBuf<KTimeBufLength> timeBuf;
       
   151 	time.FormatL(timeBuf,KTimeFormatStr);
       
   152 	if(iLogStyle != EText)
       
   153 		{
       
   154 		// Use the log format
       
   155 		Log(iLogOutput, *(iLogFormat.iDocumentStart));
       
   156 		if(aLogInfo->iTitle)
       
   157 			Log(iLogOutput, *(aLogInfo->iTitle));
       
   158 		Log(iLogOutput, *(iLogFormat.iContentStart));
       
   159 		Log(iLogOutput, timeBuf);
       
   160 
       
   161 		Log(iReportOutput, *(iLogFormat.iDocumentStart));
       
   162 		if(aLogInfo->iTitle)
       
   163 			Log(iReportOutput, *(aLogInfo->iTitle));
       
   164 		Log(iReportOutput, *(iLogFormat.iContentStart));
       
   165 		Log(iReportOutput, timeBuf);
       
   166 		}
       
   167 	else
       
   168 		{
       
   169 		if(aLogInfo && aLogInfo->iTitle)
       
   170 			{
       
   171 			Log(iLogOutput, *(aLogInfo->iTitle));
       
   172 			Log(iReportOutput, *(aLogInfo->iTitle));
       
   173 			}
       
   174 		Log(iLogOutput, timeBuf);
       
   175 		Log(iReportOutput, timeBuf);
       
   176 		}
       
   177 	}
       
   178 
       
   179 
       
   180 EXPORT_C void CDataLogger::DumpMemoryBlock(const TUint8* aAddress, TInt aLength)
       
   181 	{
       
   182 	const TInt KBytesPerRow = 16;
       
   183 	const TInt KLowestAsciiPrint = 32;
       
   184 	const TInt KHighestAsciiPrint = 127;
       
   185 
       
   186 	// The required descriptors for outputting the data
       
   187 	_LIT(KDumpLineStart, "%04x : ");
       
   188 	_LIT(KDumpHexOutput, "%02x ");
       
   189 	_LIT(KDumpHexBlank, "   ");
       
   190 	_LIT(KDumpHexEnd, ": ");
       
   191 	_LIT(KDumpCharOutput, "%c");
       
   192 	_LIT(KDumpCharUnknown, ".");
       
   193 	_LIT(KDumpCharBlank, " ");
       
   194 
       
   195 	TPtrC8 theData(aAddress, aLength);
       
   196 
       
   197 	// Iterate the supplied block of data in blocks of 16 bytes
       
   198 	TInt pos = 0;
       
   199 	TBuf<KMaxTBLogEntrySize> logLine;
       
   200 	TBuf<KMaxTBLogEntrySize> anEntry;
       
   201 	while (pos < theData.Length())
       
   202 		{
       
   203 		TInt offset = 0;
       
   204 
       
   205 		anEntry.Format(KDumpLineStart, pos);
       
   206 		logLine.Append(anEntry);
       
   207 
       
   208 		// Hex output
       
   209 		for (offset = 0; offset < KBytesPerRow; ++offset)
       
   210 			{
       
   211 			if (pos + offset < theData.Length())
       
   212 				{
       
   213 				TInt nextByte = theData[pos + offset];
       
   214 				anEntry.Format(KDumpHexOutput, nextByte);
       
   215 				logLine.Append(anEntry);
       
   216 				}
       
   217 			else
       
   218 				{
       
   219 				anEntry.Format(KDumpHexBlank);
       
   220 				logLine.Append(anEntry);
       
   221 				}
       
   222 			}
       
   223 			anEntry.Format(KDumpHexEnd);
       
   224 			logLine.Append(anEntry);
       
   225 
       
   226 		// Char output
       
   227 		for (offset = 0; offset < KBytesPerRow; ++offset)
       
   228 			{
       
   229 			if (pos + offset < theData.Length())
       
   230 				{
       
   231 				TInt nextByte = theData[pos + offset];
       
   232 				if ((nextByte >= KLowestAsciiPrint) && (nextByte <= KHighestAsciiPrint))
       
   233 					{
       
   234 					anEntry.Format(KDumpCharOutput, nextByte);
       
   235 					logLine.Append(anEntry);
       
   236 					}
       
   237 				else
       
   238 					{
       
   239 					anEntry.Format(KDumpCharUnknown);
       
   240 					logLine.Append(anEntry);
       
   241 					}
       
   242 				}
       
   243 			else
       
   244 				{
       
   245 				anEntry.Format(KDumpCharBlank);
       
   246 				logLine.Append(anEntry);
       
   247 				}
       
   248 			}
       
   249 
       
   250 		//Log this line to the file
       
   251 		if(iLogStyle != EText)
       
   252 			{
       
   253 			Log(iLogOutput, *(iLogFormat.iCommentStart));
       
   254 			Log(iLogOutput, logLine);
       
   255 			Log(iLogOutput, *(iLogFormat.iCommentEnd));
       
   256 			}
       
   257 		else
       
   258 			Log(iLogOutput, logLine);
       
   259 
       
   260 		logLine.Zero();
       
   261 
       
   262 		// Advance to next segment of size 'KBytesPerRow'
       
   263 		pos += KBytesPerRow;
       
   264 		}
       
   265 
       
   266 	}
       
   267 
       
   268 
       
   269 EXPORT_C void CDataLogger::LogInformation(const TDesC16& aComment)
       
   270 	{
       
   271 	if(iLogStyle != EText)
       
   272 		{
       
   273 		Log(iLogOutput, *(iLogFormat.iCommentStart));
       
   274 		Log(iLogOutput, aComment);
       
   275 		Log(iLogOutput, *(iLogFormat.iCommentEnd));
       
   276 		}
       
   277 	else
       
   278 		Log(iLogOutput, aComment);
       
   279 	iDebug->Print(aComment);
       
   280 	}
       
   281 
       
   282 EXPORT_C void CDataLogger::LogInformation(const TDesC8& aComment)
       
   283 	{
       
   284 	// Create a wide descriptor to copy aComment into
       
   285 	HBufC* message = HBufC::NewMax(aComment.Length());
       
   286 
       
   287 	// If the allocation failed then do nothing
       
   288 	if(message != NULL)
       
   289 		{
       
   290 		TPtr message16 = message->Des();
       
   291 
       
   292 		message16.Copy(aComment);
       
   293 		LogInformation(message16);
       
   294 		delete message;
       
   295 		}
       
   296 	}
       
   297 
       
   298 EXPORT_C void CDataLogger::LogInformationWithParameters(TRefByValue<const TDesC16> aFormat, ...)
       
   299 	{
       
   300 	// Prepare the message
       
   301 	// coverity [var_decl]
       
   302        // VA_LIST is initialized in VA_START
       
   303 	VA_LIST list;
       
   304 	VA_START(list,aFormat);
       
   305 	
       
   306 	TPtr message = iFormatBuf->Des();
       
   307 
       
   308 	// Catch the overflow if formatting
       
   309 	TLogMessageOverflow overflowHandler;
       
   310 	message.AppendFormatList(aFormat,list,&overflowHandler);
       
   311 	VA_END(list);
       
   312 	if(overflowHandler.iError == KErrNone)
       
   313 		{
       
   314 		// Ok formatted correctly so...
       
   315 		// Wrap the logging level as the first parameter
       
   316 		if(iLogStyle != EText)
       
   317 			{
       
   318 			Log(iLogOutput, *(iLogFormat.iCommentStart));
       
   319 			Log(iLogOutput, message);
       
   320 			Log(iLogOutput, *(iLogFormat.iCommentEnd));
       
   321 			}
       
   322 		else
       
   323 			Log(iLogOutput, message);
       
   324 		iDebug->Print(message);
       
   325 		}
       
   326 
       
   327 	// Clear the message buffer
       
   328 	message.Zero();
       
   329 	}
       
   330 
       
   331 EXPORT_C void CDataLogger::LogInformationWithParameters(TRefByValue<const TDesC8> aFormat, ...)
       
   332 	{
       
   333 	// Create an 8 bit descriptor to copy aFormat into
       
   334 	HBufC8* message8 = HBufC8::New(KMaxTBLogEntrySize);
       
   335 	if(message8)
       
   336 		{
       
   337 		// Prepare the message
       
   338 		// coverity [var_decl]
       
   339 	       // VA_LIST is initialized in VA_START
       
   340 		VA_LIST list;
       
   341 		VA_START(list,aFormat);
       
   342 		TPtr8 messagePtr8 = message8->Des();
       
   343 
       
   344 		// Catch the overflow if formatting
       
   345 		TLogMessageOverflow8 overflowHandler;
       
   346 		messagePtr8.AppendFormatList(aFormat,list,&overflowHandler);
       
   347 		VA_END(list);
       
   348 		if(overflowHandler.iError == KErrNone)
       
   349 			{
       
   350 			TPtr message = iFormatBuf->Des();
       
   351 			// Copy over the fromatted message into the 16 bit descriptor
       
   352 			message.Copy(messagePtr8);
       
   353 
       
   354 			// Ok formatted correctly so...
       
   355 			// Wrap the logging level as the first parameter
       
   356 			if(iLogStyle != EText)
       
   357 				{
       
   358 				Log(iLogOutput, *(iLogFormat.iCommentStart));
       
   359 				Log(iLogOutput, message);
       
   360 				Log(iLogOutput, *(iLogFormat.iCommentEnd));
       
   361 				}
       
   362 			else
       
   363 				Log(iLogOutput, message);
       
   364 			iDebug->Print(message);
       
   365 
       
   366 			// Clear the message buffer
       
   367 			message.Zero();
       
   368 			}
       
   369 		delete message8;
       
   370 		}
       
   371 	}
       
   372 
       
   373 EXPORT_C void CDataLogger::ReportInformation(const TDesC& aComment)
       
   374 	{
       
   375 	if(iLogStyle != EText)
       
   376 		{
       
   377 		Log(iReportOutput, *(iLogFormat.iCommentStart));
       
   378 		Log(iReportOutput, aComment);
       
   379 		Log(iReportOutput, *(iLogFormat.iCommentEnd));
       
   380 		}
       
   381 	else
       
   382 		Log(iReportOutput, aComment);
       
   383 	}
       
   384 
       
   385 EXPORT_C void CDataLogger::ReportInformationWithParameters(TRefByValue<const TDesC> aFormat, ...)
       
   386 	{
       
   387 	// Prepare the message
       
   388 	// coverity [var_decl]
       
   389        // VA_LIST is initialized in VA_START
       
   390 	VA_LIST list;
       
   391 	VA_START(list,aFormat);
       
   392 	
       
   393 	TPtr message = iFormatBuf->Des();
       
   394 
       
   395 	// Catch the overflow if formatting
       
   396 	TLogMessageOverflow overflowHandler;
       
   397 	message.AppendFormatList(aFormat,list,&overflowHandler);
       
   398 	VA_END(list);
       
   399 	if(overflowHandler.iError == KErrNone)
       
   400 		{
       
   401 		// Ok formatted correctly so...
       
   402 		// Wrap the logging level as the first parameter
       
   403 		if(iLogStyle != EText)
       
   404 			{
       
   405 			Log(iReportOutput, *(iLogFormat.iCommentStart));
       
   406 			Log(iReportOutput, message);
       
   407 			Log(iReportOutput, *(iLogFormat.iCommentEnd));
       
   408 			}
       
   409 		else
       
   410 			Log(iReportOutput, message);
       
   411 		}
       
   412 
       
   413 	// Clear the message buffer
       
   414 	message.Zero();
       
   415 	}
       
   416 
       
   417 
       
   418 void CDataLogger::SetupRDebugL(TBool aRequest) 
       
   419 	{
       
   420 	delete iDebug; 
       
   421 	if(aRequest) 
       
   422 		iDebug = new(ELeave) TDebugPrint;		// Print to RDebug
       
   423 	else 
       
   424 		iDebug = new(ELeave) TNullDebugPrint;	// Ignore prints
       
   425 	}
       
   426 
       
   427 void CDataLogger::TDebugPrint::Print(const TDesC& aMessage) 
       
   428 	{
       
   429 	_LIT(KRDebugFormatStr,"%S");
       
   430 	RDebug::Print(KRDebugFormatStr, &aMessage);
       
   431 	}
       
   432 
       
   433 void CDataLogger::Log(MLogOutput* aLogOutput, const TDesC16& aMessage)
       
   434 	{
       
   435 	// If the message is short enough then log it in one go
       
   436 	if(aMessage.Length() < KMaxTBLogEntrySize)
       
   437 		aLogOutput->Write(aMessage);
       
   438 	else
       
   439 		{
       
   440 		// Start at the beginning and log out short blocks until finished
       
   441 		TInt outIndex = 0;
       
   442 		while(outIndex < aMessage.Length())
       
   443 			{
       
   444 			if((outIndex+KMaxTBLogEntrySize) > aMessage.Length())
       
   445 				{
       
   446 				aLogOutput->Write(aMessage.Right(aMessage.Length() - outIndex));
       
   447 				outIndex = aMessage.Length();
       
   448 				}
       
   449 			else
       
   450 				{
       
   451 				// The -1 is required to ensure that the submessage is not too long
       
   452 				TPtrC subMessage = aMessage.Mid(outIndex, KMaxTBLogEntrySize - 1);
       
   453 				// Find the space nearest the end for a convenient break point
       
   454 				TInt spaceLoc = subMessage.LocateReverse(TChar(' '));
       
   455 				if(spaceLoc != KErrNotFound)
       
   456 					outIndex = spaceLoc;
       
   457 				else
       
   458 					outIndex = KMaxTBLogEntrySize - 1;
       
   459 				aLogOutput->Write(subMessage.Left(++outIndex));
       
   460 				}
       
   461 			}
       
   462 		}
       
   463 	}
       
   464 
       
   465 void CDataLogger::SetupLoggingL(TLoggingInfo* aLogInfo)
       
   466 	{
       
   467 	// The possible log filenames
       
   468 	_LIT(KTestBedLogName, "RTestBed.log");
       
   469 	_LIT(KTestBedHtmlLogName, "TestBedLog.html");
       
   470 	// The possible report file names
       
   471 	_LIT(KTestBedReportName, "RTestBed.rep");
       
   472 	_LIT(KTestBedHtmlReportName, "TestBedReport.html");
       
   473 
       
   474 	if(aLogInfo)
       
   475 		{
       
   476 		iLogStyle = aLogInfo->iStyle;
       
   477 		
       
   478 		if(aLogInfo->iLogOutput)
       
   479 			iLogOutput = aLogInfo->iLogOutput;
       
   480 		else
       
   481 			{
       
   482 			if(iLogStyle==EHtml)
       
   483 				iDefaultLogOutput = new(ELeave) CDefaultLogOutput(KTestBedHtmlLogName);
       
   484 			else
       
   485 				iDefaultLogOutput = new(ELeave) CDefaultLogOutput(KTestBedLogName);
       
   486 
       
   487 			iLogOutput = iDefaultLogOutput;
       
   488 			}
       
   489 
       
   490 		if(aLogInfo->iReportOutput)
       
   491 			iReportOutput = aLogInfo->iReportOutput;
       
   492 		else
       
   493 			{
       
   494 			if(iLogStyle==EHtml)
       
   495 				iDefaultReportOutput = new(ELeave) CDefaultLogOutput(KTestBedHtmlReportName);
       
   496 			else
       
   497 				iDefaultReportOutput = new(ELeave) CDefaultLogOutput(KTestBedReportName);
       
   498 
       
   499 			iReportOutput = iDefaultReportOutput;
       
   500 			}
       
   501 
       
   502 		SetupRDebugL(aLogInfo->iUseRDebug);
       
   503 		}
       
   504 	else
       
   505 		{
       
   506 		iLogStyle = EText;
       
   507 		iDefaultLogOutput = new(ELeave) CDefaultLogOutput(KTestBedLogName);
       
   508 		iLogOutput = iDefaultLogOutput;
       
   509 		iDefaultReportOutput = new(ELeave) CDefaultLogOutput(KTestBedReportName);
       
   510 		iReportOutput = iDefaultReportOutput;
       
   511 
       
   512 		SetupRDebugL(ETrue);
       
   513 		}
       
   514 
       
   515 	// If the user has specified a custom logging style then use their LogFormat
       
   516 	if(iLogStyle == ECustom)
       
   517 		iLogFormat = *(aLogInfo->iLogFormat);
       
   518 	else if(iLogStyle == EHtml)
       
   519 		{
       
   520 		// Output as HTML
       
   521 		iLogFormat.iDocumentStart	= &(KHTMLDocumentStart());
       
   522 		iLogFormat.iContentStart	= &(KHTMLContentStart());
       
   523 		iLogFormat.iCommentStart	= &(KHTMLCommentStart());
       
   524 		iLogFormat.iCommentEnd		= &(KHTMLCommentEnd());
       
   525 		iLogFormat.iDocumentEnd		= &(KHTMLDocumentEnd());
       
   526 		}
       
   527 	}