testconns/statdesktop/desktop/source/lib/src/cstatlogfile.cpp
changeset 4 b8d1455fddc0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/testconns/statdesktop/desktop/source/lib/src/cstatlogfile.cpp	Mon Oct 04 02:58:21 2010 +0300
@@ -0,0 +1,387 @@
+/*
+* 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:  
+*
+*/
+
+
+
+
+#include "stdafx.h"
+#include "CSTATLogFile.h"
+#include <statcommon.h>
+
+//----------------------------------------------------------------------------
+// our thread-safe mechanism - this must be defined, initialised and destroyed by
+// the code using CSTATEngine.  See STATExp.cpp for an example
+extern CRITICAL_SECTION CriticalSection;
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+//standard constructor
+CSTATLogFile::CSTATLogFile()
+: bMessageBox(false), bMessage(false), bWriteToScreen(false), bWriteToFile(false), bScreenshot(false),
+	iMessageReporter(NULL)
+{
+	message = _T("");
+	text = _T("");
+	*(szLogPrefix) = (char)0;
+}
+
+//----------------------------------------------------------------------------
+//destructor
+CSTATLogFile::~CSTATLogFile()
+{
+	CloseLogFile();
+}
+
+
+//----------------------------------------------------------------------------
+// opens (creates) logfile
+int CSTATLogFile::CreateLogFile(const CString& newlogfilename,const CString& defaultPath, const char* prefix, bool append, bool bMessages, bool bFile)
+{
+	// set flags to write to dialog screen/file
+	bWriteToScreen = bMessages;
+	bWriteToFile = bFile;
+
+	// construct our log file
+	if (bWriteToFile)
+	{
+		EnterCriticalSection(&CriticalSection);
+
+		// in case it's already open
+		CloseLogFile();
+
+		int position;
+		UINT openFlags = CFile::modeCreate | CFile::modeWrite | CFile::shareDenyNone;
+
+		// if newlogfilename contains a path, use it otherwise get the default log directory
+		position = newlogfilename.ReverseFind('\\');
+		if (position != -1)
+		{
+			Logfilename = newlogfilename;
+			CreateDirectory(Logfilename.Left(position), NULL); // try to create directory just in case
+		}
+		else
+		{
+			Logfilename=defaultPath;
+			if (Logfilename[Logfilename.GetLength() - 1] != _T('\\'))
+				Logfilename += _T("\\");
+
+			Logfilename += newlogfilename;
+			CreateDirectory(Logfilename, NULL); // try to create directory just in case
+		}
+
+		// just path supplied, add a filename
+		if (Logfilename[Logfilename.GetLength() - 1] == _T('\\'))
+		{
+			char FormattedDate[12] = {0};
+			Logfilename += _T("STAT");
+			Logfilename += _strdate(FormattedDate);		// ...\\filename is now 'STATmm/dd/yy'
+			Logfilename.Remove('/');					// ...\\filename is now 'STATmmddyy'
+		}
+
+		// add extension if not supplied
+		if(Logfilename.ReverseFind('.') == -1)
+			Logfilename += _T(".log");
+
+		// if not append, create a new file every time, renaming with (1),(2)...(n) as needed
+		CFileFind finder;
+		if (!append)
+		{
+			CString tempLogfile, tempLogstart, tempLogend;
+			char szCopycount[15] = {0};
+			int iCopycount = 1;
+
+			// save various bits
+			tempLogfile = Logfilename;
+			position = tempLogfile.ReverseFind('.');
+			tempLogstart = tempLogfile.Left(position);
+			tempLogend = Logfilename.Right(Logfilename.GetLength() - position);
+
+			while (finder.FindFile(tempLogfile, 0))
+			{
+				if (position > 0)
+				{
+					tempLogfile = tempLogstart;
+					tempLogfile += "(";
+					tempLogfile += itoa(iCopycount++, szCopycount, 10);
+					tempLogfile += ")";
+					tempLogfile += tempLogend;
+				}
+				finder.Close();
+			}					
+
+			// assign new filename
+			Logfilename = tempLogfile;
+		}
+		else
+		{
+			// if it already exists, open simple in case other handles are open on it
+			if (finder.FindFile(Logfilename, 0))
+			{
+				openFlags = CFile::modeWrite | CFile::shareDenyNone;
+				finder.Close();
+			}
+		}
+
+		// open the file
+		int valid = logfile.Open(Logfilename, openFlags);
+		if (valid)
+		{
+			logfile.SeekToEnd();
+			if (prefix && *prefix)
+			{
+				strcpy(szLogPrefix, "  ");
+				strcat(szLogPrefix, prefix);
+			}
+		}
+
+		LeaveCriticalSection(&CriticalSection);
+
+		if (!valid)
+			return LOG_FILE_FAILURE;
+	}
+
+	return LOG_FILE_OK;
+}
+
+//----------------------------------------------------------------------------
+// Specifies the message handler.
+void CSTATLogFile::SetMessageReporter(MessageReporter *const messageReporter)
+{
+	iMessageReporter =	messageReporter;
+}
+
+//----------------------------------------------------------------------------
+// sets a log message
+void
+CSTATLogFile::WriteTimeToLog()
+{
+	if (logfile.m_hFile != CFile::hFileNull)
+	{
+		EnterCriticalSection(&CriticalSection);
+
+		// get the time
+		time_t aclock;
+		time(&aclock);
+		CString cBuf = asctime(localtime(&aclock));
+		int position = cBuf.Find(_T('\n')); // remove the carriage return from the end
+		if (position != -1)
+			cBuf.SetAt(position, 0);
+
+		Write("--------------------------------------------------\r\n");
+		Write(FormatText(cBuf));
+
+		logfile.Flush();
+
+		LeaveCriticalSection(&CriticalSection);
+	}
+}
+
+
+//----------------------------------------------------------------------------
+// writes CString directly to the log file
+void
+CSTATLogFile::Write(CString cBuf)
+{
+	Write(FormatText(cBuf));
+}
+
+
+//----------------------------------------------------------------------------
+//writes basic text directly to the log file
+void CSTATLogFile::Write(char *szText, ...)
+{
+	if (logfile.m_hFile != CFile::hFileNull)
+	{
+		EnterCriticalSection(&CriticalSection);
+
+		static char szMessage[MAX_LOG_MSG_LEN + 1];
+		static time_t curTime;
+
+		logfile.SeekToEnd();
+		logfile.Write(szLogPrefix, strlen(szLogPrefix));
+
+		// write the date/time
+		time ( &curTime );
+		strftime ( szMessage, 
+					sizeof ( szMessage ), 
+					"%d/%m %H:%M:%S ",
+					localtime ( &curTime ) );
+		logfile.Write(szMessage, strlen(szMessage));
+
+		// write the message
+		memset(&szMessage, 0, sizeof(szMessage));
+		va_list pCurrent = (va_list)0;
+		va_start (pCurrent, szText);
+		vsprintf (szMessage, szText, pCurrent);
+		va_end (pCurrent);
+		logfile.Write(szMessage, strlen(szMessage));
+
+		// add a CRLF if there isn't one already
+		if (strlen(szMessage) > 2)
+			if (strcmp(szMessage + strlen(szMessage) - 2, "\r\n") != 0)
+				logfile.Write("\r\n", 2);
+
+		logfile.Flush();
+
+		LeaveCriticalSection(&CriticalSection);
+	}
+}
+
+
+//----------------------------------------------------------------------------
+// sets a log message (same as Write() but subject to waiting for previous
+// message to be processed before returning (if multi-threaded write to screen
+// is enabled)
+int
+CSTATLogFile::Set(const char* newtext)
+{
+	Set(-1, newtext, false, false);
+	return ITS_OK;
+}
+
+//----------------------------------------------------------------------------
+// sets a log message (same as Write() but subject to waiting for previous
+// message to be processed before returning (if multi-threaded write to screen
+// is enabled)
+int
+CSTATLogFile::Set(int iMsgCode, const char* newtext, bool bMsgBox, bool bScrshot)
+{
+	// write to screen
+	if (bWriteToScreen && (NULL != iMessageReporter))
+	{
+		// set contents
+		if (iMsgCode != -1)
+		{
+			message = ReturnCodes.GetRetMsg(iMsgCode);
+		}
+		else
+		{
+			message.Empty( );
+		}
+
+		if ((newtext != NULL) && (*newtext != '\0'))
+		{
+			text = newtext;
+		}
+
+		iMessageReporter->OnMessage( message.operator LPCTSTR(), text.operator LPCTSTR(),
+										bMsgBox, bScrshot );
+	}
+
+	// write to file
+	if (bWriteToFile)
+	{
+		EnterCriticalSection(&CriticalSection);
+
+		if (iMsgCode != -1)
+			Write(FormatText(ReturnCodes.GetRetMsg(iMsgCode)));
+
+		if ((newtext != NULL) && (*newtext != '\0'))
+			Write(FormatText(newtext));
+
+		LeaveCriticalSection(&CriticalSection);
+	}
+
+	return iMsgCode;
+}
+
+//----------------------------------------------------------------------------
+//closes the active logfile
+void CSTATLogFile::CloseLogFile()
+{
+	EnterCriticalSection(&CriticalSection);
+
+	if (logfile.m_hFile != CFile::hFileNull)
+		logfile.Abort();
+
+	LeaveCriticalSection(&CriticalSection);
+}
+
+
+//----------------------------------------------------------------------------
+// PRIVATE METHODS
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+//removes spacing between data when writing to file
+char* CSTATLogFile::FormatText(const char* message)
+{
+	int newlen = 0;
+	static char szBuffer[MAX_LOG_MSG_LEN + 3];
+	int maxlen = strlen(message);
+
+	if (maxlen > MAX_LOG_MSG_LEN)
+		maxlen = MAX_LOG_MSG_LEN;
+
+	(*szBuffer) = (char)0;
+	newlen = ToAnsi(message, szBuffer, maxlen);
+
+	// add CR-LF and null-terminate, even if an empty string
+	*(szBuffer + newlen) = (char)0;
+	strcat(szBuffer, "\r\n");
+
+	return szBuffer;
+}
+
+
+//----------------------------------------------------------------------------
+//function to convert unicode to ansi - for logging
+int CSTATLogFile::ToAnsi(LPCTSTR szUnicode, LPSTR szBuffer, int nBufLen)
+{
+#ifdef UNICODE
+	return (WideCharToMultiByte(CP_ACP,						// conversion type
+								0,							// flags
+								szUnicode,					// source
+								nBufLen,					// length
+								szBuffer,					// dest
+								nBufLen,					// length
+								NULL,
+								NULL));
+#else
+	strncpy(szBuffer, szUnicode, nBufLen);
+	*(szBuffer + nBufLen) = (char)0;
+	return strlen(szBuffer);
+#endif
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// Converts a char * to it's Unicode equivalent
+//
+LPCTSTR
+CSTATLogFile::ToUnicode(const char *string)
+{
+#ifdef UNICODE
+	static TCHAR szBuffer[MAX_LOG_MSG_LEN + 1] = {0};
+	szBuffer[0] = (TCHAR)0;
+
+    // Convert to UNICODE.
+    if (!MultiByteToWideChar(CP_ACP,					// conversion type
+							 0,							// flags
+							 string,					// source
+							 -1,						// length
+							 szBuffer,					// dest
+							 MAX_LOG_MSG_LEN))			// length
+    {
+        return _T("Unable to convert ansi to unicode");
+    }
+
+    return szBuffer;
+#else
+	return string;
+#endif
+}