diff -r 73b88125830c -r b8d1455fddc0 testconns/statdesktop/desktop/source/lib/src/cstatlogfile.cpp --- /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 + +//---------------------------------------------------------------------------- +// 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 +}