diff -r bbd31066657e -r 8bb370ba6d1d testexecfw/stf/stfext/testmodules/teftestmod/testexecmdw/filelogger/src/client.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/testexecfw/stf/stfext/testmodules/teftestmod/testexecmdw/filelogger/src/client.cpp Fri Apr 09 10:46:28 2010 +0800 @@ -0,0 +1,397 @@ +/* +* 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 + + +//_LIT8(KxmlHeader,"\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 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 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 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 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 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 --------------------------*/ + TRAP_IGNORE(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); + TRAP_IGNORE(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; + } + } + +