--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lowlevellibsandfws/pluginfw/Test_Bed/test_bed/DataLogger.cpp Tue Feb 02 02:01:42 2010 +0200
@@ -0,0 +1,527 @@
+// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include <e32def.h>
+#include <f32file.h>
+
+#include <ecom/test_bed/datalogger.h>
+
+// KLogBufferSize is the maximum line length allowed by flogger
+const TInt KMaxTBLogEntrySize = KLogBufferSize;
+
+// Common string literals for all output formats
+_LIT(KTimeFormatStr,"%J%:1%T%:2%S%.%*C3");
+// Above string will give time in format HH:MM:SS.SSS therefore max length = 12
+const TInt KTimeBufLength = 12;
+
+// Define some string literals for HTML formatting
+_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>");
+// Insert title string here
+_LIT(KHTMLContentStart,"</TITLE></HEAD><BODY><P><FONT=3>");
+// Insert time string here
+_LIT(KHTMLCommentStart,"<P>");
+// Insert content here
+_LIT(KHTMLCommentEnd,"</P>");
+_LIT(KHTMLDocumentEnd,"</FONT></P></BODY></HTML>");
+
+//___________________________________________________________________________
+// Define the overflow handling classes for any log formatting methods
+// Simply record the overflow...
+//
+
+NONSHARABLE_CLASS(TLogMessageOverflow) : public TDes16Overflow
+ {
+ public:
+
+ TLogMessageOverflow();
+
+ void Overflow(TDes16&);
+
+ TInt iError;
+ };
+
+TLogMessageOverflow::TLogMessageOverflow()
+: TDes16Overflow(),
+iError(KErrNone)
+ {
+ }
+
+void TLogMessageOverflow::Overflow(TDes16&)
+ {
+ __DEBUGGER();
+ iError = KErrOverflow;
+ }
+
+
+NONSHARABLE_CLASS(TLogMessageOverflow8) : public TDes8Overflow
+ {
+ public:
+
+ TLogMessageOverflow8();
+
+ void Overflow(TDes8&);
+
+ TInt iError;
+ };
+
+TLogMessageOverflow8::TLogMessageOverflow8()
+: TDes8Overflow(),
+iError(KErrNone)
+ {
+ }
+
+void TLogMessageOverflow8::Overflow(TDes8&)
+ {
+ __DEBUGGER();
+ iError = KErrOverflow;
+ }
+
+//___________________________________________________________________________
+
+//___________________________________________________________________________
+
+CDataLogger::~CDataLogger()
+ {
+ if(iLogOutput != NULL)
+ {
+ if(iLogStyle != EText && iLogFormat.iDocumentEnd)
+ Log(iLogOutput, *(iLogFormat.iDocumentEnd));
+ iLogOutput->Close();
+ }
+
+ if(iReportOutput != NULL)
+ {
+ if(iLogStyle != EText && iLogFormat.iDocumentEnd)
+ Log(iReportOutput, *(iLogFormat.iDocumentEnd));
+ iReportOutput->Close();
+ }
+
+ delete iFormatBuf;
+ delete iDebug;
+ delete iDefaultLogOutput;
+ delete iDefaultReportOutput;
+ }
+
+
+CDataLogger::CDataLogger()
+ {
+ }
+
+CDataLogger* CDataLogger::NewLC(TLoggingInfo* aLogInfo)
+ {
+ CDataLogger* self = new (ELeave) CDataLogger();
+ CleanupStack::PushL(self);
+ self->ConstructL(aLogInfo);
+ return self;
+ }
+
+CDataLogger* CDataLogger::NewL(TLoggingInfo* aLogInfo)
+ {
+ CDataLogger* self = NewLC(aLogInfo);
+ CleanupStack::Pop();
+ return self;
+ }
+
+
+void CDataLogger::ConstructL(TLoggingInfo* aLogInfo)
+ {
+ iFormatBuf = HBufC::NewL(KMaxTBLogEntrySize);
+
+ SetupLoggingL(aLogInfo);
+
+ iLogOutput->OpenL();
+ iReportOutput->OpenL();
+
+ // Record additional information : Time
+ TTime time;
+ time.UniversalTime();
+ TBuf<KTimeBufLength> timeBuf;
+ time.FormatL(timeBuf,KTimeFormatStr);
+ if(iLogStyle != EText)
+ {
+ // Use the log format
+ Log(iLogOutput, *(iLogFormat.iDocumentStart));
+ if(aLogInfo->iTitle)
+ Log(iLogOutput, *(aLogInfo->iTitle));
+ Log(iLogOutput, *(iLogFormat.iContentStart));
+ Log(iLogOutput, timeBuf);
+
+ Log(iReportOutput, *(iLogFormat.iDocumentStart));
+ if(aLogInfo->iTitle)
+ Log(iReportOutput, *(aLogInfo->iTitle));
+ Log(iReportOutput, *(iLogFormat.iContentStart));
+ Log(iReportOutput, timeBuf);
+ }
+ else
+ {
+ if(aLogInfo && aLogInfo->iTitle)
+ {
+ Log(iLogOutput, *(aLogInfo->iTitle));
+ Log(iReportOutput, *(aLogInfo->iTitle));
+ }
+ Log(iLogOutput, timeBuf);
+ Log(iReportOutput, timeBuf);
+ }
+ }
+
+
+EXPORT_C void CDataLogger::DumpMemoryBlock(const TUint8* aAddress, TInt aLength)
+ {
+ const TInt KBytesPerRow = 16;
+ const TInt KLowestAsciiPrint = 32;
+ const TInt KHighestAsciiPrint = 127;
+
+ // The required descriptors for outputting the data
+ _LIT(KDumpLineStart, "%04x : ");
+ _LIT(KDumpHexOutput, "%02x ");
+ _LIT(KDumpHexBlank, " ");
+ _LIT(KDumpHexEnd, ": ");
+ _LIT(KDumpCharOutput, "%c");
+ _LIT(KDumpCharUnknown, ".");
+ _LIT(KDumpCharBlank, " ");
+
+ TPtrC8 theData(aAddress, aLength);
+
+ // Iterate the supplied block of data in blocks of 16 bytes
+ TInt pos = 0;
+ TBuf<KMaxTBLogEntrySize> logLine;
+ TBuf<KMaxTBLogEntrySize> anEntry;
+ while (pos < theData.Length())
+ {
+ TInt offset = 0;
+
+ anEntry.Format(KDumpLineStart, pos);
+ logLine.Append(anEntry);
+
+ // Hex output
+ for (offset = 0; offset < KBytesPerRow; ++offset)
+ {
+ if (pos + offset < theData.Length())
+ {
+ TInt nextByte = theData[pos + offset];
+ anEntry.Format(KDumpHexOutput, nextByte);
+ logLine.Append(anEntry);
+ }
+ else
+ {
+ anEntry.Format(KDumpHexBlank);
+ logLine.Append(anEntry);
+ }
+ }
+ anEntry.Format(KDumpHexEnd);
+ logLine.Append(anEntry);
+
+ // Char output
+ for (offset = 0; offset < KBytesPerRow; ++offset)
+ {
+ if (pos + offset < theData.Length())
+ {
+ TInt nextByte = theData[pos + offset];
+ if ((nextByte >= KLowestAsciiPrint) && (nextByte <= KHighestAsciiPrint))
+ {
+ anEntry.Format(KDumpCharOutput, nextByte);
+ logLine.Append(anEntry);
+ }
+ else
+ {
+ anEntry.Format(KDumpCharUnknown);
+ logLine.Append(anEntry);
+ }
+ }
+ else
+ {
+ anEntry.Format(KDumpCharBlank);
+ logLine.Append(anEntry);
+ }
+ }
+
+ //Log this line to the file
+ if(iLogStyle != EText)
+ {
+ Log(iLogOutput, *(iLogFormat.iCommentStart));
+ Log(iLogOutput, logLine);
+ Log(iLogOutput, *(iLogFormat.iCommentEnd));
+ }
+ else
+ Log(iLogOutput, logLine);
+
+ logLine.Zero();
+
+ // Advance to next segment of size 'KBytesPerRow'
+ pos += KBytesPerRow;
+ }
+
+ }
+
+
+EXPORT_C void CDataLogger::LogInformation(const TDesC16& aComment)
+ {
+ if(iLogStyle != EText)
+ {
+ Log(iLogOutput, *(iLogFormat.iCommentStart));
+ Log(iLogOutput, aComment);
+ Log(iLogOutput, *(iLogFormat.iCommentEnd));
+ }
+ else
+ Log(iLogOutput, aComment);
+ iDebug->Print(aComment);
+ }
+
+EXPORT_C void CDataLogger::LogInformation(const TDesC8& aComment)
+ {
+ // Create a wide descriptor to copy aComment into
+ HBufC* message = HBufC::NewMax(aComment.Length());
+
+ // If the allocation failed then do nothing
+ if(message != NULL)
+ {
+ TPtr message16 = message->Des();
+
+ message16.Copy(aComment);
+ LogInformation(message16);
+ delete message;
+ }
+ }
+
+EXPORT_C void CDataLogger::LogInformationWithParameters(TRefByValue<const TDesC16> aFormat, ...)
+ {
+ // Prepare the message
+ // coverity [var_decl]
+ // VA_LIST is initialized in VA_START
+ VA_LIST list;
+ VA_START(list,aFormat);
+
+ TPtr message = iFormatBuf->Des();
+
+ // Catch the overflow if formatting
+ TLogMessageOverflow overflowHandler;
+ message.AppendFormatList(aFormat,list,&overflowHandler);
+ VA_END(list);
+ if(overflowHandler.iError == KErrNone)
+ {
+ // Ok formatted correctly so...
+ // Wrap the logging level as the first parameter
+ if(iLogStyle != EText)
+ {
+ Log(iLogOutput, *(iLogFormat.iCommentStart));
+ Log(iLogOutput, message);
+ Log(iLogOutput, *(iLogFormat.iCommentEnd));
+ }
+ else
+ Log(iLogOutput, message);
+ iDebug->Print(message);
+ }
+
+ // Clear the message buffer
+ message.Zero();
+ }
+
+EXPORT_C void CDataLogger::LogInformationWithParameters(TRefByValue<const TDesC8> aFormat, ...)
+ {
+ // Create an 8 bit descriptor to copy aFormat into
+ HBufC8* message8 = HBufC8::New(KMaxTBLogEntrySize);
+ if(message8)
+ {
+ // Prepare the message
+ // coverity [var_decl]
+ // VA_LIST is initialized in VA_START
+ VA_LIST list;
+ VA_START(list,aFormat);
+ TPtr8 messagePtr8 = message8->Des();
+
+ // Catch the overflow if formatting
+ TLogMessageOverflow8 overflowHandler;
+ messagePtr8.AppendFormatList(aFormat,list,&overflowHandler);
+ VA_END(list);
+ if(overflowHandler.iError == KErrNone)
+ {
+ TPtr message = iFormatBuf->Des();
+ // Copy over the fromatted message into the 16 bit descriptor
+ message.Copy(messagePtr8);
+
+ // Ok formatted correctly so...
+ // Wrap the logging level as the first parameter
+ if(iLogStyle != EText)
+ {
+ Log(iLogOutput, *(iLogFormat.iCommentStart));
+ Log(iLogOutput, message);
+ Log(iLogOutput, *(iLogFormat.iCommentEnd));
+ }
+ else
+ Log(iLogOutput, message);
+ iDebug->Print(message);
+
+ // Clear the message buffer
+ message.Zero();
+ }
+ delete message8;
+ }
+ }
+
+EXPORT_C void CDataLogger::ReportInformation(const TDesC& aComment)
+ {
+ if(iLogStyle != EText)
+ {
+ Log(iReportOutput, *(iLogFormat.iCommentStart));
+ Log(iReportOutput, aComment);
+ Log(iReportOutput, *(iLogFormat.iCommentEnd));
+ }
+ else
+ Log(iReportOutput, aComment);
+ }
+
+EXPORT_C void CDataLogger::ReportInformationWithParameters(TRefByValue<const TDesC> aFormat, ...)
+ {
+ // Prepare the message
+ // coverity [var_decl]
+ // VA_LIST is initialized in VA_START
+ VA_LIST list;
+ VA_START(list,aFormat);
+
+ TPtr message = iFormatBuf->Des();
+
+ // Catch the overflow if formatting
+ TLogMessageOverflow overflowHandler;
+ message.AppendFormatList(aFormat,list,&overflowHandler);
+ VA_END(list);
+ if(overflowHandler.iError == KErrNone)
+ {
+ // Ok formatted correctly so...
+ // Wrap the logging level as the first parameter
+ if(iLogStyle != EText)
+ {
+ Log(iReportOutput, *(iLogFormat.iCommentStart));
+ Log(iReportOutput, message);
+ Log(iReportOutput, *(iLogFormat.iCommentEnd));
+ }
+ else
+ Log(iReportOutput, message);
+ }
+
+ // Clear the message buffer
+ message.Zero();
+ }
+
+
+void CDataLogger::SetupRDebugL(TBool aRequest)
+ {
+ delete iDebug;
+ if(aRequest)
+ iDebug = new(ELeave) TDebugPrint; // Print to RDebug
+ else
+ iDebug = new(ELeave) TNullDebugPrint; // Ignore prints
+ }
+
+void CDataLogger::TDebugPrint::Print(const TDesC& aMessage)
+ {
+ _LIT(KRDebugFormatStr,"%S");
+ RDebug::Print(KRDebugFormatStr, &aMessage);
+ }
+
+void CDataLogger::Log(MLogOutput* aLogOutput, const TDesC16& aMessage)
+ {
+ // If the message is short enough then log it in one go
+ if(aMessage.Length() < KMaxTBLogEntrySize)
+ aLogOutput->Write(aMessage);
+ else
+ {
+ // Start at the beginning and log out short blocks until finished
+ TInt outIndex = 0;
+ while(outIndex < aMessage.Length())
+ {
+ if((outIndex+KMaxTBLogEntrySize) > aMessage.Length())
+ {
+ aLogOutput->Write(aMessage.Right(aMessage.Length() - outIndex));
+ outIndex = aMessage.Length();
+ }
+ else
+ {
+ // The -1 is required to ensure that the submessage is not too long
+ TPtrC subMessage = aMessage.Mid(outIndex, KMaxTBLogEntrySize - 1);
+ // Find the space nearest the end for a convenient break point
+ TInt spaceLoc = subMessage.LocateReverse(TChar(' '));
+ if(spaceLoc != KErrNotFound)
+ outIndex = spaceLoc;
+ else
+ outIndex = KMaxTBLogEntrySize - 1;
+ aLogOutput->Write(subMessage.Left(++outIndex));
+ }
+ }
+ }
+ }
+
+void CDataLogger::SetupLoggingL(TLoggingInfo* aLogInfo)
+ {
+ // The possible log filenames
+ _LIT(KTestBedLogName, "RTestBed.log");
+ _LIT(KTestBedHtmlLogName, "TestBedLog.html");
+ // The possible report file names
+ _LIT(KTestBedReportName, "RTestBed.rep");
+ _LIT(KTestBedHtmlReportName, "TestBedReport.html");
+
+ if(aLogInfo)
+ {
+ iLogStyle = aLogInfo->iStyle;
+
+ if(aLogInfo->iLogOutput)
+ iLogOutput = aLogInfo->iLogOutput;
+ else
+ {
+ if(iLogStyle==EHtml)
+ iDefaultLogOutput = new(ELeave) CDefaultLogOutput(KTestBedHtmlLogName);
+ else
+ iDefaultLogOutput = new(ELeave) CDefaultLogOutput(KTestBedLogName);
+
+ iLogOutput = iDefaultLogOutput;
+ }
+
+ if(aLogInfo->iReportOutput)
+ iReportOutput = aLogInfo->iReportOutput;
+ else
+ {
+ if(iLogStyle==EHtml)
+ iDefaultReportOutput = new(ELeave) CDefaultLogOutput(KTestBedHtmlReportName);
+ else
+ iDefaultReportOutput = new(ELeave) CDefaultLogOutput(KTestBedReportName);
+
+ iReportOutput = iDefaultReportOutput;
+ }
+
+ SetupRDebugL(aLogInfo->iUseRDebug);
+ }
+ else
+ {
+ iLogStyle = EText;
+ iDefaultLogOutput = new(ELeave) CDefaultLogOutput(KTestBedLogName);
+ iLogOutput = iDefaultLogOutput;
+ iDefaultReportOutput = new(ELeave) CDefaultLogOutput(KTestBedReportName);
+ iReportOutput = iDefaultReportOutput;
+
+ SetupRDebugL(ETrue);
+ }
+
+ // If the user has specified a custom logging style then use their LogFormat
+ if(iLogStyle == ECustom)
+ iLogFormat = *(aLogInfo->iLogFormat);
+ else if(iLogStyle == EHtml)
+ {
+ // Output as HTML
+ iLogFormat.iDocumentStart = &(KHTMLDocumentStart());
+ iLogFormat.iContentStart = &(KHTMLContentStart());
+ iLogFormat.iCommentStart = &(KHTMLCommentStart());
+ iLogFormat.iCommentEnd = &(KHTMLCommentEnd());
+ iLogFormat.iDocumentEnd = &(KHTMLDocumentEnd());
+ }
+ }