标签:
来源: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