标签:
来源:http://blog.csdn.net/lezhiyong
1. 简介
将指定内存段转为16进制与asci码的输出到日志文件的类。96 013877A0:00000000
/**
* @file Vitrace.h
* @brief 支持windows linux下将指定内存段转为16进制与ascii码的日志输出类
*
* @writer longf
* @version 1.00
* @date 2015-01-27
* @history
*/
//#include "XAutoLock.h"
//#include "rcs_public.h"
#ifdef WIN32
#include <windows.h>
#else
#endif
#ifndef UINT
typedef unsigned int UINT;
#endif // UINT
#ifndef NULL
#define NULL 0
#endif // NULL
#define MAX_PATH 512
UINT vi_bin2ascii(char* pDstBuf,UINT nDstBufLen,char*pSrcBuf,UINT nSrcBufLen);
UINT vi_bin2hex(char* pDstBuf,UINT nDstBufLen,char*pSrcBuf,UINT nSrcBufLen);
typedef void (*_APP_INFO_OUT_CALLBACK)(char*szInfo,void*pCallParam);
class CViTrace
{
public:
CViTrace(char*szPathName,//路径名
char* szAppName,//文件名
_APP_INFO_OUT_CALLBACK pInfoOutCallback=NULL,//额外的输出回调
void *pInfoOutCallbackParam=NULL);//回调函数参数
~CViTrace(void);
public:
UINT trace(char* szFormat,...);
void trace_bin(char*pBuffer,UINT nLength,bool bPrintAsci=false);
public:
//方便应用层取出输出信息,在不同的输出设备打入自己的输出队列
_APP_INFO_OUT_CALLBACK m_pInfoOutCallback;
void* m_pInfoOutCallbackParam;
private:
char m_szFileName[MAX_PATH];//拼接好的路径名和文件名
//XCritSec m_Lock;
};/**
* @file Vitrace.cpp
* @brief 支持windows linux下将指定内存段转为16进制与ascii码的日志输出类
*
* @writer longf
* @version 1.00
* @date 2015-01-27
* @history
*/
#include "vitrace.h"
#include <time.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#ifdef WIN32
#include <windows.h>
#else
#include <pthread.h>
#include <sys/time.h>
#endif
#ifdef CON_DEBUG
#define CON_PRINTF printf
#else
#define CON_PRINTF//printf
#endif
#ifdef WIN32
#define PATH_CHAR "\\"
#else
#define PATH_CHAR "/"
#endif
inline unsigned int PthreadSelf()
{
#ifdef WIN32
return ::GetCurrentThreadId();
#else
return pthread_self();
#endif
}
#define VITRACE_BUFFER_LENGTH 10000 //TRACE缓冲区大小
#define VITRACE_HEX_PRINTBYTES_PERLINE 32
#define VITRACE_HEX_SPACE 4
static UINT safe_printf(char*pDst,UINT nDstSize,char*szFormat,...)
{
UINT nListCount=0;
va_list pArgList;
if (!pDst) goto _EXIT_FUN;
va_start(pArgList,szFormat);
nListCount+=vsnprintf(pDst+nListCount,nDstSize-nListCount,szFormat,pArgList);
va_end(pArgList);
if (nListCount>(nDstSize-1)) nListCount = nDstSize-1;
*(pDst+nListCount)='\0';
_EXIT_FUN:
return nListCount;
}
void GetFullFileName(char* pBufFullname,UINT nBufSize,char* path,char* name,char* ext_name)
{
if (strlen(path))
{
if (strlen(ext_name))
safe_printf(pBufFullname,nBufSize,
"%s%s%s.%s",path,PATH_CHAR,name,ext_name);
else
safe_printf(pBufFullname,nBufSize,
"%s%s%s",path,PATH_CHAR,name,name);
}
else
{
if (strlen(ext_name))
safe_printf(pBufFullname,nBufSize,
"%s.%s",name,ext_name);
else
safe_printf(pBufFullname,nBufSize,
"%s",name);
}
}
UINT get_timestamp(char* szBuf,UINT nMaxLength)
{
UINT nLength=0;
#ifdef WIN32
SYSTEMTIME tm;
GetLocalTime(&tm);
nLength= safe_printf(szBuf,nMaxLength,"%02d-%02d-%02d,%02d:%02d:%02d-%03d",tm.wYear,tm.wMonth,tm.wDay,tm.wHour,tm.wMinute,tm.wSecond,tm.wMilliseconds );
#else
/*
time_t t;
struct tm*pTM=NULL;
time(&t);
pTM= localtime(&t);
nLength= safe_printf(szBuf,nMaxLength,"%s",asctime(pTM));
*/
struct timeval tv;
struct timezone tz;
struct tm *p;
gettimeofday(&tv, &tz);
p = localtime(&tv.tv_sec);
nLength= safe_printf(szBuf,nMaxLength,"%02d-%02d-%02d,%02d:%02d:%02d-%03d", 1900+p->tm_year, 1+p->tm_mon, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec, tv.tv_usec/1000);
#endif
return nLength;
}
////以ascii显示指定数据区内容
UINT vi_bin2ascii(char* pDstBuf,UINT nDstBufLen,char*pSrcBuf,UINT nSrcBufLen)
{
if (nSrcBufLen>nDstBufLen)
{
nSrcBufLen = nDstBufLen;
}
UINT i;
UINT nCount=0;
for (i=0;i<nSrcBufLen;i++)
{
//ascii字符表中可显示字符代码>32
if (32<=*(pSrcBuf+i))
{
nCount+= safe_printf(pDstBuf+nCount,nDstBufLen-nCount,"%c",pSrcBuf[i]);
}
else
{
nCount+= safe_printf(pDstBuf+nCount,nDstBufLen-nCount,".");
}
}
return nCount;
}
//以16进制显示指定数据区内容
UINT vi_bin2hex(char* pDstBuf,UINT nDstBufLen,char*pSrcBuf,UINT nSrcBufLen)
{
if (nSrcBufLen>nDstBufLen)
{
nSrcBufLen = nDstBufLen;
}
UINT i=0;
UINT j=0;
UINT nCount=0;
for (i=0;i<nSrcBufLen;i++)
{
nCount+= safe_printf(pDstBuf+nCount,nDstBufLen-nCount,"%02X",(unsigned char)pSrcBuf[i]);
j++;
if (VITRACE_HEX_SPACE==j)
{
j=0;
nCount+= safe_printf(pDstBuf+nCount,nDstBufLen-nCount," ");
}
}
if (VITRACE_HEX_PRINTBYTES_PERLINE>nSrcBufLen)//每行打印VITRACE_PRINTBYTES_PER_LINE字节,不足补充空格
{
for (;i<VITRACE_HEX_PRINTBYTES_PERLINE;i++)
{
nCount+= safe_printf(pDstBuf+nCount,nDstBufLen-nCount," ");//一个字符占用两个字节
j++;
if (VITRACE_HEX_SPACE==j)
{
j=0;
nCount+= safe_printf(pDstBuf+nCount,nDstBufLen-nCount," ");
}
}
}
return nCount;
}
//用户指定的输出文件,文件打开方式,一般“a+”,返回输出字符总数
UINT vi_trace(char* szFileName,char*szMode,char*strBuf)
{
UINT nListCount =0;
char szTime[256];
get_timestamp(szTime,256);
char tmp[VITRACE_BUFFER_LENGTH+256];
sprintf(tmp, "\r\n<%s, tId=%d>",szTime,PthreadSelf);
FILE* fp;
fp=fopen(szFileName,szMode);
if (fp)
{
nListCount += fwrite(tmp, strlen(tmp), 1, fp);
}
nListCount += fwrite(strBuf, strlen(strBuf), 1, fp);
fclose(fp);
return nListCount;
}
/*
Vint32 vi_trace(char* szFileName,char*szMode,char*szFormat,...)
{
char szBuf[LODEBUG_BUFFER_LENGTH];
char szTime[256];
Vint32 nListCount=0;
va_list pArgList;
va_start(pArgList,szFormat);
nListCount+=_vsnprintf(szBuf+nListCount,LODEBUG_BUFFER_LENGTH-nListCount,szFormat,pArgList);
va_end(pArgList);
if (nListCount>(LODEBUG_BUFFER_LENGTH-1))
{
nListCount=LODEBUG_BUFFER_LENGTH-1;
}
*(szBuf+nListCount)='\0';
nListCount = vi_trace(szFileName,szMode,szBuf);
return nListCount;
}
*/
//调用函数,VITRACE_HEX_PRINTBYTES_PERLINE字节为一行,格式化输出二进制内容
void vi_trace_bin(char* szFileName,char*szMode,char*pBuffer,UINT nLength,bool bPrintAsci=false)
{
if (nLength>VITRACE_BUFFER_LENGTH)
{
nLength =VITRACE_BUFFER_LENGTH;
}
int nAddr=0;
int nLineValidCount=0;
int nLineSpaceCount=0;
int nBufferCount =nLength;
int n=0;
char szLine[VITRACE_BUFFER_LENGTH+1]={0};
int iLineNum=0;
if(0<nLength)
{
n+=safe_printf(szLine+n,VITRACE_BUFFER_LENGTH-n,"\r\n%4s %8s:%s","num","address ","bufferContent ");
if (bPrintAsci)
{
n+=vi_bin2ascii(szLine+n,VITRACE_BUFFER_LENGTH-n,pBuffer+nAddr,nLineValidCount);
}
while (1)
{
if (nBufferCount>=VITRACE_HEX_PRINTBYTES_PERLINE)
{
nLineValidCount = VITRACE_HEX_PRINTBYTES_PERLINE;
nLineSpaceCount = 0;
}
else
{
nLineValidCount = nBufferCount;
nLineSpaceCount = VITRACE_HEX_PRINTBYTES_PERLINE- nLineValidCount;
}
n+=safe_printf(szLine+n,VITRACE_BUFFER_LENGTH-n,"\r\n%4d %p:",iLineNum*VITRACE_HEX_PRINTBYTES_PERLINE,pBuffer+nAddr);
n+=vi_bin2hex(szLine+n,VITRACE_BUFFER_LENGTH-n,pBuffer+nAddr,nLineValidCount);
if (bPrintAsci)
{
n+=vi_bin2ascii(szLine+n,VITRACE_BUFFER_LENGTH-n,pBuffer+nAddr,nLineValidCount);
}
nAddr+=VITRACE_HEX_PRINTBYTES_PERLINE;
nBufferCount-=VITRACE_HEX_PRINTBYTES_PERLINE;
iLineNum++;
if (0>=nBufferCount) break;
}
}
vi_trace(szFileName,szMode,szLine);
}
/*************************************************************************************
功能:设置日志输出路径和额外的输出回调:
参数:
char*szPathName://路径名
char* szAppName,//文件名
_APP_INFO_OUT_CALLBACK pInfoOutCallback:额外的输出回调
**************************************************************************************/
CViTrace::CViTrace(char*szPathName,char* szAppName,_APP_INFO_OUT_CALLBACK pInfoOutCallback, void *pInfoOutCallbackParam)
{
m_pInfoOutCallback=pInfoOutCallback;
m_pInfoOutCallbackParam=pInfoOutCallbackParam;
if (szAppName)
{
GetFullFileName(m_szFileName,MAX_PATH,szPathName,szAppName,"log");
}
else
m_szFileName[0]='\0';
remove(m_szFileName);
}
CViTrace::~CViTrace(void)
{
}
/*************************************************************************************
功能:字符串输出:
参数:
char* szFormat:可变参数,类似printf的使用
**************************************************************************************/
UINT CViTrace::trace(char* szFormat,...)
{
//XAutoLock xLock(m_Lock);
char szBuff[VITRACE_BUFFER_LENGTH]={0};
FILE *fp=NULL;
UINT nListCount=0;
va_list pArgList;
va_start(pArgList,szFormat);
nListCount+= vsnprintf(szBuff+nListCount,VITRACE_BUFFER_LENGTH-nListCount,szFormat,pArgList);
va_end(pArgList);
if (nListCount>(VITRACE_BUFFER_LENGTH-1))
{
nListCount = VITRACE_BUFFER_LENGTH-1;
}
*(szBuff+nListCount)='\0';
nListCount = vi_trace(m_szFileName,"a+",szBuff);
//回调输出;
if(m_pInfoOutCallback)
{
char szTime[256];
get_timestamp(szTime,256);
char tmp[256];
sprintf(tmp, "\r\n<%s, tId=%d>\t",szTime,PthreadSelf);
char szInfoOut[VITRACE_BUFFER_LENGTH];
safe_printf(szInfoOut,VITRACE_BUFFER_LENGTH,"%s%s",tmp,szBuff);
m_pInfoOutCallback(szInfoOut,m_pInfoOutCallbackParam);
//CON_PRINTF("%s",szInfoOut);
}
return nListCount;
}
/******************************************************************************************
功能:转换为16进制和ascii码输出:
参数:
void *Buf:内存片地址。
UINT nLength:内存片长度
bool bPrintAsci: false:左侧不输出ascii码信息,true:左侧输出ascii码信息
******************************************************************************************/
void CViTrace::trace_bin(char*pBuffer,UINT nLength,bool bPrintAsci)
{
if (nLength>1000)
{
nLength = 1000;
}
//XAutoLock xLock(m_Lock);
vi_trace_bin(m_szFileName,"a+",pBuffer,nLength,bPrintAsci);
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
支持windows linux下将指定内存段转为16进制与ascii码的日志输出类
标签:
原文地址:http://blog.csdn.net/lezhiyong/article/details/46697533