loggingservices/rfilelogger/Logger/Src/Client.cpp
changeset 0 08ec8eefde2f
child 9 667e88a979d7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/loggingservices/rfilelogger/Logger/Src/Client.cpp	Fri Jan 22 11:06:30 2010 +0200
@@ -0,0 +1,394 @@
+// Copyright (c) 2005-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:
+// Source file for the client api
+// 
+//
+
+/**
+ @file Client.cpp
+*/
+#include <test/rfilelogger.h>
+
+
+//_LIT8(KxmlHeader,"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\r\n");
+
+
+// EKA1 requires DLL entry point
+//
+// RFileLogger class definition
+//
+
+EXPORT_C RFileFlogger::RFileFlogger() : ilogbody(NULL)
+/**
+ * Create a new flogger client interface object with an empty body.
+ * @internalTechnology 
+ */
+	{
+	iLogfileTag=FALSE;
+	}
+
+EXPORT_C RFileFlogger::~RFileFlogger()
+/**
+ * Destructor
+ * @internalTechnology 
+ */
+	{}
+
+
+
+EXPORT_C TInt RFileFlogger::Connect()
+/**
+ * @return int - Standard error codes
+ * EKA2 all variants and EKA1 target.
+ * Server is an exe
+ */
+	{
+	// Sanity check to make sure it's not been called multiple times
+	if (ilogbody)
+		{
+		return KErrAlreadyExists;
+		}
+	ilogbody = new RFileLoggerBody;
+	if(!ilogbody)
+		return KErrNoMemory;
+
+	TVersion version(KRFileLoggerMajorVersion,KRFileLoggerMinorVersion,KRFileLoggerBuildVersion);
+	// Assume the server is already running and attempt to create a session
+	
+	TInt err = ilogbody->DoCreateSession(KFileLogrerServerName,version,8);
+	if(err== KErrServerTerminated)
+	{
+		User::After(1000000); // OS need time to close previous server properly
+		err = ilogbody->DoCreateSession(KFileLogrerServerName,version,8);
+	}
+
+	if(err == KErrNotFound)
+		{
+		// Server not running
+		// Construct the server binary name
+		_LIT(KEmpty,"");
+		// EKA2 is simple
+		// No path required
+		TBuf<32> serverFile;
+		serverFile.Copy(KFileLogrerServerName);
+		_LIT(KExe,".exe");
+		serverFile.Append(KExe);
+		RProcess server;
+		err = server.Create(serverFile,KEmpty);
+		if(err != KErrNone)
+			return err;
+		// Synchronise with the server
+		TRequestStatus reqStatus;
+		server.Rendezvous(reqStatus);
+		server.Resume();
+		// Server will call the reciprocal static synchronise call
+		User::WaitForRequest(reqStatus);
+		server.Close();
+		if(reqStatus.Int() != KErrNone)
+			return reqStatus.Int();
+		// Create the root server session
+		err = ilogbody->DoCreateSession(KFileLogrerServerName,version,8);
+		}
+		if (err != KErrNone)
+		{  // some other problem, kill the logbody and clean the mamory
+			delete ilogbody;
+			ilogbody=NULL;
+		}
+		else
+		{   // Makes the session shared among all threads in the process
+			err = ilogbody->ShareAuto();
+		}
+
+
+	return err;
+	}
+
+///////
+EXPORT_C TInt RFileFlogger::CreateLog(const TDesC& aLogFilePath, TLogMode aMode)
+/**
+ * @param aLogFilePath - Full path and filename of the log file
+ * @param aMode - Overwrite or Append
+ * Makes synchronous call to the log server to create a log session
+ */
+	{
+	iloglevel = ESevrAll; //ELogNone;
+
+	if(aLogFilePath.Length() > KMaxLoggerFilePath)
+		return KErrTooBig;
+
+	TIpcArgs args;
+	args.Set(0,&aLogFilePath);
+	args.Set(1,aMode);
+    TInt err = ilogbody->DoSendReceive(ECreateLog,args);
+    return err; 
+
+	}
+
+EXPORT_C void RFileFlogger::Log(const TText8* aFile, TInt aLine, TLogSeverity aSeverity, TRefByValue<const TDesC> aFmt,...)
+/**
+ * @param aFile - Source file name
+ * @param aLine - Source file line number
+ * @param aSeverity - ERR, WARN, INFO
+ * @param aFmt - UNICODE format string
+ */
+	{
+	// Set up a Variable argument list and call private method
+	if (aSeverity>iloglevel && aSeverity != ESevrTEFUnit) 
+		{
+		return;
+		}
+	VA_LIST aList;
+	VA_START(aList, aFmt);
+	Log(aFile, aLine, aSeverity, aFmt, aList);
+	VA_END(aList); 
+
+	}
+EXPORT_C void RFileFlogger::Log(const TText8* aFile, TInt aLine, TLogSeverity aSeverity,TInt arraylength, TExtraLogField* aLogFields, TRefByValue<const TDesC> aFmt,...)
+/**
+ * @param aFile - Source file name
+ * @param aLine - Source file line number
+ * @param aSeverity - ERR, WARN, INFO
+ * @param aFmt - UNICODE format string
+ */
+	{
+	// Set up a Variable argument list and call private method
+	if (aSeverity>iloglevel && aSeverity != ESevrTEFUnit) 
+		{
+		return;
+		}
+	VA_LIST aList;
+	VA_START(aList, aFmt);
+	Log(aFile, aLine, aSeverity, arraylength, aLogFields, aFmt, aList);
+	VA_END(aList); 
+	}
+
+
+void RFileFlogger::AddTime(TDes8& aLogBuffer)
+	{
+	TTime now;
+	now.UniversalTime();
+	TDateTime dateTime = now.DateTime();
+	_LIT8(KFormat,"%02d:%02d:%02d:%03d");
+	// add the current time. 
+/*--------- Maintaince Warning for aLogBuffer -----------------------------------
+******* the fomat of below string is sensible to server.  
+******* Adding any string to the aLogBuffer has to be checked 
+******* in code on server side 
+--------------------------------------------------------------------------------*/
+	aLogBuffer.AppendFormat(KFormat,dateTime.Hour(),dateTime.Minute(),dateTime.Second(),(dateTime.MicroSecond()/1000)); 
+/*--------------- End of Maintaince Warning  ----------------*/
+	}
+
+EXPORT_C void RFileFlogger::Log(const TText8* aFile, TInt aLine, TLogSeverity aSeverity, TRefByValue<const TDesC> aFmt, VA_LIST aList)
+	{
+	if (aSeverity>iloglevel && aSeverity != ESevrTEFUnit) 
+		{
+		return;
+		}
+
+	TInt arraylength = 0;
+	TExtraLogField* aLogFields =NULL;	
+	Log(aFile, aLine, aSeverity, arraylength, aLogFields, aFmt, aList);
+	}
+
+EXPORT_C void RFileFlogger::Log(const TText8* aFile, TInt aLine, TLogSeverity aSeverity,TInt arraylength, TExtraLogField* aLogFields, TRefByValue<const TDesC> aFmt, VA_LIST aList)
+/**
+ * @param aFile - Source file name
+ * @param aLine - Source file line number
+ * @param aSeverity - ERR, WARN, INFO
+ * @param arraylength
+ * @param aLogFields
+ * @param aFmt - UNICODE format string
+ * @param aList - Variable argument list
+ *
+ * Format a log output line
+ */
+ 	{
+	if (aSeverity>iloglevel && aSeverity != ESevrTEFUnit) 
+		{
+		return;
+		}
+
+	if (aSeverity == ESevrTEFUnit)
+		{
+		aSeverity = ESevrInfo;
+		}
+/*----- Maintaince Warning for this section: -----------------------------------
+******* the fomat of below string is very sensible to server Server 
+******* defomating these string with the understanding of this 
+******* perticular format. Any change made here should be checked 
+******* in code on server side 
+--------------------------------------------------------------------------------*/
+	// Create a filename string
+	TBuf16<KMaxFilename> fileName;
+	GetCPPModuleName(fileName, aFile);  
+	// Create a buffer for formatting
+	HBufC* buffer = HBufC::NewLC(KMaxLoggerLineLength*2);
+	if(!buffer)
+		return;  // no memory
+	TPtr ptr(buffer->Des());
+	_LIT(KEnd,"\r\n");
+	_LIT(KErr,"ERROR");
+	_LIT(KHigh,"HIGH");
+	_LIT(KWarn,"WARN");
+	_LIT(KMedium,"MEDIUM");
+	_LIT(KInfo,"INFO");
+	_LIT(KLow,"LOW");
+//	ptr.Append(KTypeTagBeging);
+	ptr.Append(KSeperation);
+	if(aSeverity == ESevrErr)
+		ptr.Append(KErr);
+	else if(aSeverity == ESevrHigh)
+		ptr.Append(KHigh);
+	else if(aSeverity == ESevrWarn)
+		ptr.Append(KWarn);
+	else if(aSeverity == ESevrMedium)
+		ptr.Append(KMedium);
+	else if (aSeverity == ESevrInfo)
+		ptr.Append(KInfo);
+	else if(aSeverity == ESevrLow)
+		ptr.Append(KLow);
+	else //if(aSeverity == ESevrAll)
+		ptr.Append(KInfo);
+	// Add the thread id -------- read CIniData to decide the level of details
+	ptr.AppendFormat(KMessageFormat,(TInt)(RThread().Id()),&fileName, aLine);
+	ptr.AppendFormatList(aFmt, aList);
+	if(arraylength>0)  // trust user providing correct number with actual arrary length
+	{
+		_LIT(KTab,"\t");
+		// presuming the following string is hardly being apart of log message from users
+		// and no carrige return and line feed in their log field name and field value
+		ptr.Append(KEnd);
+		ptr.Append(KTagSeperation);
+		ptr.Append(KTab);
+		ptr.AppendNum(TInt64(arraylength));
+		TInt loopValue(arraylength);
+		while(loopValue)
+		{
+			ptr.Append(KEnd);
+			ptr.Append(aLogFields->iLogFieldName);
+			ptr.Append(KTab);
+			ptr.Append(aLogFields->iLogFieldValue);
+			loopValue--; // Decrement the looping until all fields are exhausted
+			aLogFields++; // Increment the pointer address to access sucessive array index values			
+		}
+		ptr.Append(KEnd);
+		ptr.Append(KTagSeperationEnd);
+
+	}
+/*----------------- End of Maintaince warning section --------------------------*/
+	TRAPD(err,WriteL(ptr));
+	CleanupStack::PopAndDestroy(buffer);
+
+	}
+
+
+void RFileFlogger::WriteL(const TDesC& aLogBuffer)
+/**
+ * @param aLogBuffer - UNICODE buffer
+ */
+	{
+	HBufC8* buffer = HBufC8::NewLC(aLogBuffer.Length()+100);
+	if(!buffer)
+		return;  // no memory
+	TPtr8 ptr(buffer->Des());
+	AddTime(ptr);
+	ptr.Append(aLogBuffer);
+	TRAPD(err,WriteL(ptr));
+
+	CleanupStack::PopAndDestroy(buffer);
+	}
+
+void RFileFlogger::WriteL(TDes8& aLogBuffer)
+/**
+ * @param aLogBuffer - pre-formatted narrow buffer
+ * 
+ * Synchronous write to the server
+ */
+	{
+	_LIT8(KEnd,"\r\n");
+	// Check to see if there's room to add CRLF
+	if(aLogBuffer.Length()+2 > aLogBuffer.MaxLength())
+		{
+		HBufC8* buffer = HBufC8::NewLC(aLogBuffer.Length()+2);
+		if(!buffer)
+			return;  // no memory
+		TPtr8 ptr(buffer->Des());
+		ptr.Copy(aLogBuffer);
+		TBuf8<4> tempBuf(_L8("\r\n"));
+		if (aLogBuffer.Mid(aLogBuffer.Length()-2,2).CompareF(tempBuf) != 0)
+			ptr.Append(KEnd);
+		TIpcArgs args;
+		args.Set(0,&ptr);
+		args.Set(1,ptr.Length());
+		User::LeaveIfError(ilogbody->DoSendReceive(EWriteLog,args));
+		CleanupStack::PopAndDestroy(buffer);
+		}
+	else
+		{
+		TBuf8<4> tempBuf(_L8("\r\n"));
+		if (aLogBuffer.Mid(aLogBuffer.Length()-2,2).CompareF(tempBuf) != 0)
+			aLogBuffer.Append(KEnd);
+		TIpcArgs args;
+		args.Set(0,&aLogBuffer);
+		args.Set(1,aLogBuffer.Length());
+		User::LeaveIfError(ilogbody->DoSendReceive(EWriteLog,args));
+		}
+	}
+
+void RFileFlogger::GetCPPModuleName(TDes& aModuleName, const TText8* aCPPFileName)
+/**
+ * @return aModuleName - Filename in descriptor
+ * @param aCppFileName - Filename
+ * Borrowed from scheduletest
+ */
+	{
+	TPtrC8 fileNamePtrC8(aCPPFileName);
+	// We do our own filename munging here; TParse can't help us since that's
+	// expressly for EPOC filepaths and here we've got whatever the build system is
+	// At present Win32 and Unix directory delimiters are supported
+	TInt lastDelimiter = Max(fileNamePtrC8.LocateReverse('\\'), fileNamePtrC8.LocateReverse('/'));
+	if(lastDelimiter >= 0 && lastDelimiter < fileNamePtrC8.Length() - 1)
+		{
+		// Found a delimiter which isn't trailing; update the ptr to start at the next char
+		TInt fileNameLen = Min(KMaxFilename, fileNamePtrC8.Length() - (lastDelimiter + 1));
+		fileNamePtrC8.Set(aCPPFileName + lastDelimiter + 1, fileNameLen);
+		}
+	else
+		{
+		// Didn't find a delimiter; take as much of the right-end of the name as fits
+		fileNamePtrC8.Set(aCPPFileName + Max(0, fileNamePtrC8.Length() - KMaxFilename), Min(fileNamePtrC8.Length(), KMaxFilename));
+		}
+	aModuleName.Copy(fileNamePtrC8);
+	}
+
+
+
+EXPORT_C void RFileFlogger::SetLogLevel(TLogSeverity aloglevel)
+	{
+	iloglevel=aloglevel;
+	}
+
+
+EXPORT_C void RFileFlogger::Close()
+	{
+  	if(ilogbody)
+  		{
+		ilogbody->Close();
+		delete ilogbody;
+		ilogbody = NULL;
+  		}
+	}
+
+