--- /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
+}