📄 aftrace.cpp
字号:
// AFTrace.cpp: implementation of the AFTrace class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "AFTrace.h"
#include "direct.h"
#include "algorithm"
#include "string"
using namespace std;
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
list<string *> AFTrace::m_listText;
list<AFTrace *> AFTrace::m_listTrace;
HANDLE AFTrace::m_hEventWait = NULL;
CRITICAL_SECTION AFTrace::m_csWriteEvent;
HANDLE AFTrace::m_hWriteThread = NULL;
HANDLE AFTrace::m_hOnlyFile = INVALID_HANDLE_VALUE;
HANDLE AFTrace::m_hConsole = INVALID_HANDLE_VALUE;
int AFTrace::m_nRefCount = 0;
__int64 AFTrace::m_i64TickCountFrequence = 1000;
string AFTrace::m_sFilePath;
string AFTrace::m_sFileName;
AFTrace::PFNWRITEMSGCALLBACK AFTrace::m_pfnCallBack = NULL;
DWORD AFTrace::m_dwMaxFileSize = 1024*1024*2;
AFTrace::AFTrace()
{
}
void AFTrace::Create(const char * sAppName ,unsigned int nWriteMode )
{
m_sText = NULL;
m_bNewLine = true;
m_dwWriteMode = 0;
m_nLineNumber = 1;
m_nMaxLines = 1024*1024;
m_hFile = INVALID_HANDLE_VALUE;
m_nRefCount ++;
SetAppName(sAppName);
SetMode(nWriteMode);
if (!m_hEventWait)
{
if (m_dwWriteMode & hitime)
{
if (!QueryPerformanceFrequency((LARGE_INTEGER*)&m_i64TickCountFrequence))
m_i64TickCountFrequence = 1000;
}
m_hEventWait = CreateEvent(NULL,false,false,NULL);
InitializeCriticalSection(&m_csWriteEvent);
DWORD id;
m_hWriteThread = CreateThread(NULL,0,WriteThreadProc,this,0,&id);
}
}
AFTrace::AFTrace(const char * sAppName,unsigned int nWriteMode)
{
Create(sAppName,nWriteMode);
}
AFTrace::~AFTrace()
{
m_nRefCount --;
flush();
bool bFound = false;
while (1)
{
EnterCriticalSection(&m_csWriteEvent);
if (m_listTrace.empty() || m_listText.empty())
bFound = false;
else
bFound = (find(m_listTrace.begin(),m_listTrace.end(),this) != m_listTrace.end());
LeaveCriticalSection(&m_csWriteEvent);
if (bFound)
{
Sleep(10);
continue ;
}
break ;
}
if (m_nRefCount<=0)
{
if (m_hEventWait)
{
SetEvent(m_hEventWait);
WaitForSingleObject(m_hWriteThread,INFINITE);
CloseHandle(m_hEventWait);
CloseHandle(m_hWriteThread);
DeleteCriticalSection(&m_csWriteEvent);
m_hEventWait = NULL;
m_hWriteThread = NULL;
if (m_hOnlyFile != INVALID_HANDLE_VALUE)
{
CloseHandle(m_hOnlyFile);
m_hOnlyFile = INVALID_HANDLE_VALUE;
}
}
}
if (m_dwWriteMode & ownfile && m_hFile !=INVALID_HANDLE_VALUE)
{
CloseHandle(m_hFile);
m_hFile = INVALID_HANDLE_VALUE;
}
}
void AFTrace::WriteToList(string * s)
{
if (m_nLineNumber>=m_nMaxLines)
{
SetEvent(m_hEventWait);
return ;
}
EnterCriticalSection(&m_csWriteEvent);
m_nLineNumber ++;
m_listText.push_back(s);
m_listTrace.push_back(this);
LeaveCriticalSection(&m_csWriteEvent);
SetEvent(m_hEventWait);
}
DWORD AFTrace::WriteThreadProc(void * p)
{
while (1)
{
AFTrace * pTrace = NULL;
if (m_nRefCount<=0)
break;
int nLines = m_listText.size();
if (!nLines)
WaitForSingleObject(m_hEventWait,5000);
nLines = m_listText.size();
if (nLines <= 0)
continue ;
while (nLines--)
{
// try {
EnterCriticalSection(&m_csWriteEvent);
AFTrace * pTrace = m_listTrace.front();
string * sText = m_listText.front();
m_listTrace.pop_front();
m_listText.pop_front();
LeaveCriticalSection(&m_csWriteEvent);
pTrace->WriteMessage(sText,sText->size()-2);
delete sText;
// } catch (...) {
// }
}
if (!m_listText.empty())
continue;
}
char szExitText[80];
strcpy(szExitText,"AFTrace线程退出 ");
const int nLen = strlen(szExitText) - 8;
DWORD dwBytes;
if (m_hConsole != INVALID_HANDLE_VALUE)
{
szExitText[nLen] = '\n';
WriteConsole(m_hConsole,szExitText,nLen+1,&dwBytes,NULL);
}
if (m_hOnlyFile != INVALID_HANDLE_VALUE)
{
szExitText[nLen] = '\r';
szExitText[nLen+1] = '\n';
WriteFile(m_hOnlyFile,szExitText,nLen+2,&dwBytes,NULL);
}
if (m_pfnCallBack)
{
szExitText[nLen] = 0;
m_pfnCallBack(szExitText,nLen);
}
return 0;
}
void AFTrace::WriteMessage(string * ps, int nLen)
{
char * p = ps->begin();
DWORD dwBytes;
if (m_dwWriteMode&console)
{
p[nLen] = '\n';
p[nLen+1] = 0;
// m_hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),p,nLen+1,&dwBytes,NULL);
// WriteConsole(m_hConsole,p,nLen+1,&dwBytes,NULL);
}
if (m_dwWriteMode&file)
{
m_hFile = m_dwWriteMode&ownfile?m_hFile:m_hOnlyFile;
p[nLen] = '\r';
p[nLen+1] = '\n';
p[nLen+2] = 0;
if (m_hFile != INVALID_HANDLE_VALUE)
{
DWORD dwFileSizeHi;
DWORD dwFileSizeLow = GetFileSize(m_hFile,&dwFileSizeHi);
if (dwFileSizeLow != -1 )
{
if (dwFileSizeLow >= m_dwMaxFileSize)
RenameFile();
WriteFile(m_hFile,p,nLen+2,&dwBytes,NULL);
}
}
}
if (m_pfnCallBack)
{
p[nLen] = 0;
m_pfnCallBack(p,nLen);
}
}
void AFTrace::SetMode(unsigned int dwWriteMode/* = console*/)
{
m_dwWriteMode = dwWriteMode;
if (m_dwWriteMode & console)
m_hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
else
m_hConsole = INVALID_HANDLE_VALUE;
if (m_dwWriteMode & ownfile)
m_dwWriteMode |= file;
if (m_dwWriteMode & file)
{
if (m_dwWriteMode & ownfile)
{
if (m_sFilePath.empty())
{
m_sFilePath.resize(MAX_PATH,0);
int n = GetModuleFileName(NULL,m_sFilePath.begin(),MAX_PATH);
m_sFilePath.resize(n);
n = m_sFilePath.rfind('\\');
m_sFilePath.resize(n);
m_sFilePath += "\\log";
_mkdir(m_sFilePath.c_str());
m_sFilePath += "\\";
}
string sPath = m_sFilePath + m_sAppName;
sPath += ".txt";
m_hFile = CreateFile(sPath.c_str(),GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
if (m_hFile!=INVALID_HANDLE_VALUE)
SetFilePointer(m_hFile,0,NULL,FILE_END);
}
else if (m_hOnlyFile == INVALID_HANDLE_VALUE)
{
if (m_sFilePath.empty())
{
m_sFilePath.resize(MAX_PATH,0);
int n = GetModuleFileName(NULL,m_sFilePath.begin(),MAX_PATH);
m_sFilePath.resize(n);
n = m_sFilePath.rfind('\\');
m_sFilePath.resize(n);
m_sFilePath += "\\log";
_mkdir(m_sFilePath.c_str());
m_sFilePath += "\\";
}
if (m_sFileName.empty())
m_sFileName = m_sAppName;
string sPath = m_sFilePath + m_sFileName;
sPath += ".txt";
m_hFile = CreateFile(sPath.c_str(),GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
if (m_hFile!=INVALID_HANDLE_VALUE)
SetFilePointer(m_hFile,0,NULL,FILE_END);
m_hOnlyFile = m_hFile;
}
else
{
m_hFile = m_hOnlyFile;
}
}
}
int AFTrace::out(const char * sz,...)
{
va_list va;
va_start(va,sz);
string sText;
int nTextLen = 512 + strlen(sz);
sText.resize(nTextLen);
int nLen = _vsnprintf(sText.begin(),nTextLen,sz,va);
while (nLen == -1)
{
nTextLen += 128;
sText.resize(nTextLen);
nLen = _vsnprintf(sText.begin(),nTextLen,sz,va);
}
sText.resize(nLen);
if (sText[nLen-1] != '\n')
{
sText += '\n';
}
va_end(va);
string * sHead;
MakeHead(sHead);
char * pSrc = sText.begin();
char * p = pSrc;
while (*p != '\n' && p < sText.end())
{
p ++;
}
nLen = p - pSrc;
int nOldLen = sHead->size();
sHead->resize(nOldLen + nLen + 2);
char * pDest = sHead->begin() + nOldLen;
memcpy(pDest,pSrc,nLen);
pDest[nLen] = 0;
pDest[nLen+1] = 0;
WriteToList(sHead);
p ++;
pSrc = p;
while (p < sText.end())
{
if (*p =='\n')
{
nLen = p - pSrc;
string * s = new string;
s->resize(nLen + 2);
pDest = s->begin();
memcpy(pDest,pSrc,nLen);
pDest[nLen] = 0;
pDest[nLen+1] = 0;
WriteToList(s);
pSrc = p + 1;
}
++ p;
}
return 0;
}
void AFTrace::RenameFile()
{
string sFileName = m_sFilePath;
if (m_dwWriteMode & ownfile)
sFileName += m_sAppName;
else
sFileName += m_sFileName;
string sName ;
sName.resize(sFileName.size() + 20);
for (int i = 15; i>=0; i--)
{
int n = sprintf(sName.begin(),"%s_%x.txt",sFileName.c_str(),i);
sName.resize(n);
WIN32_FIND_DATA fd;
HANDLE hFinder = FindFirstFile(sName.c_str(),&fd);
if (hFinder != INVALID_HANDLE_VALUE)
{
FindClose(hFinder);
if (i >= 15)
{
DeleteFile(sName.c_str());
continue ;
}
string sNewName;
sNewName.resize(sFileName.size()+20);
n = sprintf(sNewName.begin(),"%s_%x.txt",sFileName.c_str(),i+1);
sNewName.resize(n);
MoveFile(sName.c_str(),sNewName.c_str());
}
}
sFileName += ".txt";
CloseHandle(m_hFile);
MoveFile(sFileName.c_str(),sName.c_str());
m_hFile = CreateFile(sFileName.c_str(),GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
if (m_hFile!=INVALID_HANDLE_VALUE)
SetFilePointer(m_hFile,0,NULL,FILE_END);
if (!(m_dwWriteMode&ownfile))
m_hOnlyFile = m_hFile;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -